From e23542fcafbccd8f501a84754712d3aa6683c9c4 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Mon, 14 Dec 2020 18:44:19 -0500 Subject: [PATCH] High-Level Documentation (#565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * High level docs - start. * Clean up README * Start adding details to high level docs * More docs on the header sync pallet * Testing scenarios document. * Add some scenarios. * Add multi-sig scenario. * Start writing about message dispatch pallet * Move content from old README into PoA specific doc * Apply suggestions from code review Co-authored-by: Andreas Doerr * GRANDPA for consistency. * Describe scenario steps. * WiP * Add notes about block production and forks * Update. * Add sequence diagram for Millau to Rialto transfer * Clean up header sync pallet overview * Remove leftover example code * Clean up testing scenarios and amend sequence diagram. * Linking docs. * Add some more docs. * Do a bit of cleanup on the high-level docs * Clean up the testing scenario * Fix typos in flow charts * Fix small typo * Fix indentation of Rust block * Another attempt at rendering block correctly * TIL about lazy list numbering in Markdown * Add list numbers across sections * Start counting from correct number * Update README to use correct path to local scripts * Wrap ASCII art in code block Co-authored-by: Tomasz Drwięga Co-authored-by: Tomasz Drwięga Co-authored-by: Andreas Doerr --- bridges/README.md | 238 ++++++------------ bridges/docs/high-level-overview.md | 177 +++++++++++++ bridges/modules/substrate/src/fork_tests.rs | 6 +- .../modules/substrate/src/justification.rs | 4 +- bridges/modules/substrate/src/lib.rs | 16 +- bridges/modules/substrate/src/storage.rs | 10 +- bridges/modules/substrate/src/verifier.rs | 12 +- bridges/primitives/runtime/src/chain.rs | 2 +- 8 files changed, 280 insertions(+), 185 deletions(-) create mode 100644 bridges/docs/high-level-overview.md diff --git a/bridges/README.md b/bridges/README.md index 8c086d0b6df1b..da98270b65951 100644 --- a/bridges/README.md +++ b/bridges/README.md @@ -2,20 +2,18 @@ This is a collection of components for building bridges. -These components include runtime modules to help you construct your bridge's runtime, as well as -bridge relays for cross-chain communication. +These components include Substrate pallets for syncing headers, passing arbitrary messages, as well +as libraries for building relayers to provide cross-chain communication capabilities. -A bridge node is also available. The node can be used to run a test network which has support for bridging Ethereum -PoA chains to Substrate. We're working on expanding this functionality in the future. +Three bridge nodes are also available. The nodes can be used to run test networks which bridge other +Substrate chains or Ethereum Proof-of-Authority chains. 🚧 The bridges are currently under construction - a hardhat is recommended beyond this point 🚧 ## Contents - [Installation](#installation) +- [High-Level Architecture](#high-level-architecture) - [Project Layout](#project-layout) -- [Rialto Runtime](#rialto-runtime) -- [Ethereum Node](#ethereum-node) -- [Bridge Relay](#bridge-relay) - [Running the Bridge](#running-the-bridge) ## Installation @@ -40,199 +38,119 @@ If you need more information about setting up your development environment Subst [Getting Started](https://substrate.dev/docs/en/knowledgebase/getting-started/) page is a good resource. -## Project Layout -Here's an overview of how the project is laid out. The main bits are the `node`, which is the actual -"blockchain", the `modules` which are used to build the blockchain's logic (a.k.a the runtime) and -the `relays` which are used to pass messages between chains. - -``` -├── bin -│ └── node // Bridge ready chain implementation -├── modules // Runtime Modules -│ ├── ethereum // Manage Ethereum PoA chain info -│ ├── ethereum-contract // Ethereum built-in for validating Substrate block info -│ ├── currency-exchange // Cross-chain fund transfers -│ └── substrate // Manage Substrate chain info -├── primitives // Shared runtime and node code -│ └── ethereum-poa // Helpers for Ethereum PoA -├── relays // Cross-chain communication -│ ├── ethereum // Sync and communicate between Ethereum PoA + Substrate chains -│ └── substrate // 🚧 WIP 🚧 -``` - -## Rialto Runtime -The node runtime consists of several runtime modules, however not all of them are used at the same -time. When running an Ethereum PoA to Substrate bridge the modules required are the Ethereum module -and the currency exchange module. When running a Substrate to Substrate bridge the Substrate and -currency exchange modules are required. - -Below is a brief description of each of the runtime modules. - -### Ethereum Bridge Runtime Module -The main job of this runtime module is to keep track of useful information an Ethereum PoA chain -which has been submitted by a bridge relayer. This includes: +## High-Level Architecture - - Ethereum headers and their status (e.g are they the best header, are they finalized, etc.) - - Current validator set, and upcoming validator sets - -This runtime module has more responsibilties than simply storing headers and validator sets. It is -able to perform checks on the incoming headers to verify their general integrity, as well as whether -or not they've been finalized by the authorities on the PoA chain. - -This module is laid out as so: +This repo has support for bridging foreign chains together using a combination of Substrate pallets +and external processes called relayers. A bridge chain is one that is able to follow the consensus +of a foreign chain independently. For example, consider the case below where we want to bridge two +Substrate based chains. ``` -├── ethereum -│ └── src -│ ├── error.rs // Runtime error handling -│ ├── finality.rs // Manage finality operations -│ ├── import.rs // Import new Ethereum headers -│ ├── lib.rs // Store headers and validator set info -│ ├── validators.rs // Track current and future PoA validator sets -│ └── verification.rs // Verify validity of incoming Ethereum headers ++---------------+ +---------------+ +| | | | +| Rialto | | Millau | +| | | | ++-------+-------+ +-------+-------+ + ^ ^ + | +---------------+ | + | | | | + +-----> | Bridge Relay | <-------+ + | | + +---------------+ ``` -### Currency Exchange Runtime Module -The currency exchange module is used to faciliate cross-chain funds transfers. It works by accepting -a transaction which proves that funds were locked on one chain, and releases a corresponding amount -of funds on the recieving chain. - -For example: Alice would like to send funds from chain A to chain B. What she would do is send a -transaction to chain A indicating that she would like to send funds to an address on chain B. This -transaction would contain the amount of funds she would like to send, as well as the address of the -recipient on chain B. These funds would now be locked on chain A. Once the block containing this -"locked-funds" transaction is finalized it can be relayed to chain B. Chain B will verify that this -transaction was included in a finalized block on chain A, and if successful deposit funds into the -recipient account on chain B. - -Chain B would need a way to convert from a foreign currency to its local currency. How this is done -is left to the runtime developer for chain B. - -This module is one example of how an on-chain light client can be used to prove a particular action -was taken on a foreign chain. In particular it enables transfers of the foreign chain's native -currency, but more sophisticated modules such as ERC20 token transfers or arbitrary message transfers -are being worked on as well. +The Millau chain must be able to accept Rialto headers and verify their integrity. It does this by +using a runtime module designed to track GRANDPA finality. Since two blockchains can't interact +directly they need an external service, called a relayer, to communicate. The relayer will subscribe +to new Rialto headers via RPC and submit them to the Millau chain for verification. -### Substrate Bridge Runtime Module -👷 Under Construction 👷‍♀️ +Take a look at [Bridge High Level Documentation](./docs/high-level-overview.md) for more in-depth +description of the bridge interaction. -## Ethereum Node -On the Ethereum side of things, we require two things. First, a Solidity smart contract to track the -Substrate headers which have been submitted to the bridge (by the relay), and a built-in contract to -be able to verify that headers have been finalized by the Grandpa finality gadget. Together this -allows the Ethereum PoA chain to verify the integrity and finality of incoming Substrate headers. - -The Solidity smart contract is not part of this repo, but can be found -[here](https://github.com/svyatonik/substrate-bridge-sol/blob/master/substrate-bridge.sol) if you're -curious. We have the contract ABI in the `ethereum/relays/res` directory. - -## Bridge Relay -The bridge relay is responsible for syncing the chains which are being bridged, and passing messages -between them. The current implementation of the relay supportings syncing and interacting with -Ethereum PoA and Substrate chains. - -The folder structure of the bridge relay is as follows: +## Project Layout +Here's an overview of how the project is laid out. The main bits are the `node`, which is the actual +"blockchain", the `modules` which are used to build the blockchain's logic (a.k.a the runtime) and +the `relays` which are used to pass messages between chains. ``` -├── relays -│ ├── ethereum -│ │ ├── res -│ │ │ └── ... -│ │ └── src -│ │ ├── ethereum_client.rs // Interface for Ethereum RPC -│ │ ├── ethereum_deploy_contract.rs // Utility for deploying bridge contract to Ethereum -│ │ ├── ethereum_exchange.rs // Relay proof of PoA -> Substrate exchange transactions -│ │ ├── ethereum_sync_loop.rs // Sync headers from Ethereum, submit to Substrate -│ │ ├── ethereum_types.rs // Useful Ethereum types -│ │ ├── exchange.rs // Relay proof of exchange transactions -│ │ ├── headers.rs // Track synced and incoming block headers -│ │ ├── main.rs // Entry point to binary -│ │ ├── substrate_client.rs // Interface for Substrate RPC -│ │ ├── substrate_sync_loop.rs // Sync headers from Substrate, submit to Ethereum -│ │ ├── substrate_types.rs // Useful Ethereum types -│ │ ├── sync.rs // Sync configuration and helpers -│ │ ├── sync_loop.rs // Header synchronization between source and target chains -│ │ ├── sync_types.rs // Useful sync types -│ │ └── utils.rs // General utilities -``` +├── bin // Node and Runtime for the various Substrate chains +│ └── ... +├── deployments // Useful tools for deploying test networks +│ └── ... +├── diagrams // Pretty pictures of the project architecture +│ └── ... +├── modules // Substrate Runtime Modules (a.k.a Pallets) +│ ├── ethereum // Ethereum PoA Header Sync Module +│ ├── substrate // Substrate Based Chain Header Sync Module +│ ├── message-lane // Cross Chain Message Passing +│ └── ... +├── primitives // Code shared between modules, runtimes, and relays +│ └── ... +├── relays // Application for sending headers and messages between chains +│ └── ... +└── scripts // Useful development and maintenence scripts + ``` ## Running the Bridge To run the Bridge you need to be able to connect the bridge relay node to the RPC interface of nodes -on each side of the bridge (home & foreign chain). An easy way to build all the required nodes is -through Docker. +on each side of the bridge (source and target chain). -### Local Development Build +There are 3 ways to run the bridge, described below: + - building & running from source, + - building or using Docker images for each individual component, + - running a Docker Compose setup (recommended). -#### Building +### Building -First you'll need to build the bridge node and relay. This can be done as follows: +First you'll need to build the bridge nodes and relay. This can be done as follows: ```bash # In `parity-bridges-common` folder cargo build -p rialto-bridge-node -cargo build -p ethereum-poa-relay -``` - -Next you'll need to clone the following [fork of OpenEthereum](https://github.com/paritytech/openethereum). -If you're doing development which only involves the Ethereum to Substrate side of the bridge you may -use the `master` branch. Otherwise you'll need to checkout the `substrate-builtins-stubs` branch. - -```bash -# Should be at the same level as `parity-bridges-common` folder -git clone https://github.com/paritytech/openethereum.git openethereum -git fetch -git checkout substrate-builtins-stubs +cargo build -p millau-bridge-node +cargo build -p substrate-relay ``` -If you've checked out the `substrate-builtins-stubs` branch make sure you've cloned the OpenEthereum -repo at the same level as `parity-bridges-common` since it references the repo. - -Next you'll need to build the Ethereum node: - -```bash -# In `openethereum` folder -cargo build -``` - -#### Running +### Running To run a simple dev network you'll can use the scripts located in -[the `scripts` folder](./scripts). Since the relay connects to both the Substrate and Ethereum -chains it must be run last. +[the `scripts` folder](./scripts). Since the relay connects to both Substrate chains it must be run +last. ```bash # In `parity-bridges-common` folder -./scripts/run-openethereum-node.sh -./scripts/run-rialto-bridge-node.sh -./scripts/run-eth2sub-relay.sh +./deployments/local-scripts/run-rialto-bridge-node.sh +./deployments/local-scripts/run-millau-bridge-node.sh +./deployments/local-scripts/run-millau-to-rialto-relay.sh +./deployments/local-scripts/run-rialto-to-millau-relay.sh ``` -At this point you should see the relayer submitting blocks from the Ethereum chain -to the Substrate chain. + +At this point you should see the relayer submitting blocks from the Millau Substrate chain to the +Rialto Substrate chain and vice-versa. ### Local Docker Build If you want to make a Docker container using your local source files you can run the following command at the top level of the repository: ```bash -docker build . -t bridge-relay-dev +docker build . -t local/rialto-bridge-node --build-arg PROJECT=rialto-bridge-node +docker build . -t local/millau-bridge-node --build-arg PROJECT=millau-bridge-node +docker build . -t local/substrate-relay --build-arg PROJECT=substrate-relay ``` -You can also build and run the Substrate based node as follows: +You can then run the network as follows: ```bash -docker build . -t bridge-node-dev --build-arg PROJECT=rialto-bridge-node -``` - -To run the Substrate node you can do the following: - -```bash -docker run -it bridge-node-dev --dev --tmp +docker run -it local/rialto-bridge-node --dev --tmp +docker run -it local/millau-bridge-node --dev --tmp +docker run -it local/substrate-relay ``` Notice that the `docker run` command will accept all the normal Substrate flags. For local development you should at minimum run with the `--dev` flag or else no blocks will be produced. -### Full Network Docker Setup -See [Deployments README](./deployments/README.md) to learn more about how to run -a more sophisticated test network using `docker-compose` setup. +### Full Network Docker Compose Setup + +For a more sophisticated deployment which includes bidirectional header sync, message passing, +monitoring dashboards, etc. see the [Deployments README](./deployments/README.md). diff --git a/bridges/docs/high-level-overview.md b/bridges/docs/high-level-overview.md new file mode 100644 index 0000000000000..763371bbf193f --- /dev/null +++ b/bridges/docs/high-level-overview.md @@ -0,0 +1,177 @@ +# High-Level Bridge Documentation + +## Purpose + +Trustless connecting between two Substrate-based chains using GRANDPA finality. + +## Overview + +Even though we support two-way bridging, the documentation will generally talk about a one-sided +interaction. That's to say, we will only talk about syncing headers and messages from a _source_ +chain to a _target_ chain. This is because the two-sided interaction is really just the one-sided +interaction with the source and target chains switched. + +To understand the full interaction with the bridge, take a look at the +[testing scenarios](./testing-scenarios.md) document. It describes potential use cases and describes +how each of the layers outlined below is involved. + +The bridge is built from various components. Here is a quick overview of the important ones. + +### Header Sync + +A light client of the source chain built into the target chain's runtime. It is a single FRAME +pallet. It provides a "source of truth" about the source chain headers which have been finalized. +This is useful for higher level applications. + +### Headers Relayer + +A standalone application connected to both chains. It submits every source chain header it sees to +the target chain through RPC. + +### Message Delivery + +A FRAME pallet built on top of the header sync pallet. It allows users to submit messages to the +source chain, which are to be delivered to the target chain. The delivery protocol doesn't care +about the payload more than it has to. Handles replay protection and message ordering. + +### Message Dispatch + +A FRAME pallet responsible for interpreting the payload of delivered messages. + +### Message Relayer + +A standalone application handling delivery of the messages from source chain to the target chain. + +## Processes + +High level sequence charts of the process can be found in [a separate document](./high-level.html). + +### Substrate (GRANDPA) Header Sync + +The header sync pallet (`pallet-substrate-bridge`) is an on-chain light client for chains which use +GRANDPA finality. It is part of the target chain's runtime, and accepts headers from the source +chain. Its main goals are to accept valid headers, track GRANDPA finality set changes, and verify +GRANDPA finality proofs (a.k.a justifications). + +The pallet does not care about what block production mechanism is used for the source chain +(e.g Aura or BABE) as long as it uses the GRANDPA finality gadget. Due to this it is possible for +the pallet to import (but not necessarily finalize) headers which are _not_ valid according to the +source chain's block production mechanism. + +The pallet has support for tracking forks and uses the longest chain rule to determine what the +canonical chain is. The pallet allows headers to be imported on a different fork from the canonical +one as long as the headers being imported don't conflict with already finalized headers (for +example, it will not allow importing a header at a lower height than the best finalized header). + +When tracking authority set changes, the pallet - unlike the full GRANDPA protocol - does not +support tracking multiple authority set changes across forks. Each fork can have at most one pending +authority set change. This is done to prevent DoS attacks if GRANDPA on the source chain were to +stall for a long time (the pallet would have to do a lot of expensive ancestry checks to catch up). + +Referer to the [pallet documentation](../modules/substrate/src/lib.rs) for more details. + +#### Header Relayer strategy + +There is currently no reward strategy for the relayers at all. They also are not required to be +staked or registered on-chain, unlike in other bridge designs. We consider the header sync to be +an essential part of the bridge and the incentivisation should be happening on the higher layers. + +At the moment, signed transactions are the only way to submit headers to the header sync pallet. +However, in the future we would like to use unsigned transactions for headers delivery. This will +allow transaction de-duplication to be done at the transaction pool level and also remove the cost +for message relayers to run header relayers. + +### Message Passing + +Once header sync is maintained, the target side of the bridge can receive and verify proofs about +events happening on the source chain, or its internal state. On top of this, we built a message +passing protocol which consists of two parts described in following sections: message delivery and +message dispatch. + +#### Message Lanes Delivery + +The [Message delivery pallet](../modules/message-lane/src/lib.rs) is responsible for queueing up +messages and delivering them in order on the target chain. It also dispatches messages, but we will +cover that in the next section. + +The pallet supports multiple lanes (channels) where messages can be added. Every lane can be +considered completely independent from others, which allows them to make progress in parallel. +Different lanes can be configured to validated messages differently (e.g higher rewards, specific +types of payload, etc.) and may be associated with a particular "user application" built on top of +the bridge. Note that messages in the same lane MUST be delivered _in the same order_ they were +queued up. + +The message delivery protocol does not care about the payload it transports and can be coupled +with an arbitrary message dispatch mechanism that will interpret and execute the payload if delivery +conditions are met. Each delivery on the target chain is confirmed back to the source chain by the +relayer. This is so that she can collect the reward for delivering these messages. + +Users of the pallet add their messages to an "outbound lane" on the source chain. When a block is +finalized message relayers are responsible for reading the current queue of messages and submitting +some (or all) of them to the "inbound lane" of the target chain. Each message has a `nonce` +associated with it, which serves as the ordering of messages. The inbound lane stores the last +delivered nonce to prevent replaying messages. To succesfuly deliver the message to the inbound lane +on target chain the relayer has to present present a storage proof which shows that the message was +part of the outbound lane on the source chain. + +During delivery of messages they are immediately dispatched on the target chain and the relayer is +required to declare the correct `weight` to cater for all messages dispatch and pay all required +fees of the target chain. To make sure the relayer is incentivised to do so, on the source chain: +- the user provides a declared dispatch weight of the payload +- the pallet calculates the expected fee on the target chain based on the declared weight +- the pallet converts the target fee into source tokens (based on a price oracle) and reserves + enough tokens to cover for the delivery, dispatch, confirmation and additional relayers reward. + +If the declared weight turns out to be too low on the target chain the message is delivered but +it immediately fails to dispatch. The fee and reward is collected by the relayer upon confirmation +of delivery. + +Due to the fact that message lanes require delivery confirmation transactions, they also strictly +require bi-directional header sync (i.e. you can't use message delivery with one-way header sync). + +#### Dispatching Messages + +The [Message dispatch pallet](../modules/call-dispatch/src/lib.rs) is used to perform the actions +specified by messages which have come over the bridge. For Substrate-based chains this means +interpreting the source chain's message as a `Call` on the target chain. + +An example `Call` of the target chain would look something like this: + +```rust +target_runtime::Call::Balances(target_runtime::pallet_balances::Call::transfer(recipient, amount)) +``` + +When sending a `Call` it must first be SCALE encoded and then sent to the source chain. The `Call` +is then delivered by the message lane delivery mechanism from the source chain to the target chain. +When a message is received the inbound message lane on the target chain will try and decode the +message payload into a `Call` enum. If it's successful it will be dispatched after we check that the +weight of the call does not exceed the weight declared by the sender. The relayer pays fees for +executing the transaction on the target chain, but her costs should be covered by the sender on the +source chain. + +When dispatching messages there are three Origins which can be used by the target chain: +1. Root Origin +2. Source Origin +3. Target Origin + +Senders of a message can indicate which one of the three origins they would like to dispatch their +message with. However, there are restrictions on who/what is allowed to dispatch messages with a +particular origin. + +The Root origin represents the source chain's Root account on the target chain. This origin can can +only be dispatched on the target chain if the "send message" request was made by the Root origin of +the source chain - otherwise the message will fail to be dispatched. + +The Source origin represents an account without a private key on the target chain. This account will +be generated/derived using the account ID of the sender on the source chain. We don't necessarily +require the source account id to be associated with a private key on the source chain either. This +is useful for representing things such as source chain proxies or pallets. + +The Target origin represents an account with a private key on the target chain. The sender on the +source chain needs to prove ownership of this account by using their target chain private key to +sign: `(Call, SourceChainAccountId).encode()`. This will be included in the message payload and +verified by the target chain before dispatch. + +See [`CallOrigin` documentation](../modules/call-dispatch/src/lib.rs) for more details. + +#### Message Relayers Strategy diff --git a/bridges/modules/substrate/src/fork_tests.rs b/bridges/modules/substrate/src/fork_tests.rs index cd146cd1ec8d8..f90d2c0231ca6 100644 --- a/bridges/modules/substrate/src/fork_tests.rs +++ b/bridges/modules/substrate/src/fork_tests.rs @@ -134,7 +134,7 @@ fn fork_does_not_allow_competing_finality_proofs() { // // Not allowed to import 3 until we get F2 // -// Note: Grandpa would technically allow 3 to be imported as long as it didn't try and enact an +// Note: GRANDPA would technically allow 3 to be imported as long as it didn't try and enact an // authority set change. However, since we expect finality proofs to be imported quickly we've // decided to simplify our import process and disallow header imports until we get a finality proof. #[test] @@ -161,9 +161,9 @@ fn fork_waits_for_finality_proof_before_importing_header_past_one_which_enacts_a // // [1] <- [2: S|1] <- [3: S|0] // -// Grandpa can have multiple authority set changes pending on the same fork. However, we've decided +// GRANDPA can have multiple authority set changes pending on the same fork. However, we've decided // to introduce a limit of _one_ pending authority set change per fork in order to simplify pallet -// logic and to prevent DoS attacks if Grandpa finality were to temporarily stall for a long time +// logic and to prevent DoS attacks if GRANDPA finality were to temporarily stall for a long time // (we'd have to perform a lot of expensive ancestry checks to catch back up). #[test] fn fork_does_not_allow_multiple_scheduled_changes_on_the_same_fork() { diff --git a/bridges/modules/substrate/src/justification.rs b/bridges/modules/substrate/src/justification.rs index 911ebf3f2c8c4..c285dd34b808d 100644 --- a/bridges/modules/substrate/src/justification.rs +++ b/bridges/modules/substrate/src/justification.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! Module for checking Grandpa Finality Proofs. +//! Module for checking GRANDPA Finality Proofs. //! //! Adapted copy of substrate/client/finality-grandpa/src/justification.rs. If origin //! will ever be moved to the sp_finality_grandpa, we should reuse that implementation. @@ -123,7 +123,7 @@ where Ok(()) } -/// A Grandpa Justification is a proof that a given header was finalized +/// A GRANDPA Justification is a proof that a given header was finalized /// at a certain height and with a certain set of authorities. /// /// This particular proof is used to prove that headers on a bridged chain diff --git a/bridges/modules/substrate/src/lib.rs b/bridges/modules/substrate/src/lib.rs index eb77b5af750fb..58bf3ea05dd9d 100644 --- a/bridges/modules/substrate/src/lib.rs +++ b/bridges/modules/substrate/src/lib.rs @@ -21,7 +21,7 @@ //! It has a simple interface for achieving this. First it can import headers to the runtime //! storage. During this it will check the validity of the headers and ensure they don't conflict //! with any existing headers (e.g they're on a different finalized chain). Secondly it can finalize -//! an already imported header (and its ancestors) given a valid Grandpa justification. +//! an already imported header (and its ancestors) given a valid GRANDPA justification. //! //! With these two functions the pallet is able to form a "source of truth" for what headers have //! been finalized on a given Substrate chain. This can be a useful source of info for other @@ -94,17 +94,17 @@ decl_storage! { /// Hash of the best finalized header. BestFinalized: BridgedBlockHash; /// The set of header IDs (number, hash) which enact an authority set change and therefore - /// require a Grandpa justification. + /// require a GRANDPA justification. RequiresJustification: map hasher(identity) BridgedBlockHash => BridgedBlockNumber; /// Headers which have been imported into the pallet. ImportedHeaders: map hasher(identity) BridgedBlockHash => Option>>; - /// The current Grandpa Authority set. + /// The current GRANDPA Authority set. CurrentAuthoritySet: AuthoritySet; /// The next scheduled authority set change for a given fork. /// /// The fork is indicated by the header which _signals_ the change (key in the mapping). /// Note that this is different than a header which _enacts_ a change. - // Grandpa doesn't require there to always be a pending change. In fact, most of the time + // GRANDPA doesn't require there to always be a pending change. In fact, most of the time // there will be no pending change available. NextScheduledChange: map hasher(identity) BridgedBlockHash => Option>>; /// Optional pallet owner. @@ -448,10 +448,10 @@ pub trait BridgeStorage { /// Returns None if it is not known to the pallet. fn header_by_hash(&self, hash: ::Hash) -> Option>; - /// Get the current Grandpa authority set. + /// Get the current GRANDPA authority set. fn current_authority_set(&self) -> AuthoritySet; - /// Update the current Grandpa authority set. + /// Update the current GRANDPA authority set. /// /// Should only be updated when a scheduled change has been triggered. fn update_current_authority_set(&self, new_set: AuthoritySet); @@ -462,13 +462,13 @@ pub trait BridgeStorage { #[allow(clippy::result_unit_err)] fn enact_authority_set(&mut self, signal_hash: ::Hash) -> Result<(), ()>; - /// Get the next scheduled Grandpa authority set change. + /// Get the next scheduled GRANDPA authority set change. fn scheduled_set_change( &self, signal_hash: ::Hash, ) -> Option::Number>>; - /// Schedule a Grandpa authority set change in the future. + /// Schedule a GRANDPA authority set change in the future. /// /// Takes the hash of the header which scheduled this particular change. fn schedule_next_set_change( diff --git a/bridges/modules/substrate/src/storage.rs b/bridges/modules/substrate/src/storage.rs index 86677f67c54f8..93f30bdec7c9a 100644 --- a/bridges/modules/substrate/src/storage.rs +++ b/bridges/modules/substrate/src/storage.rs @@ -42,24 +42,24 @@ pub struct InitializationData { pub is_halted: bool, } -/// A Grandpa Authority List and ID. +/// A GRANDPA Authority List and ID. #[derive(Default, Encode, Decode, RuntimeDebug, PartialEq, Clone)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct AuthoritySet { - /// List of Grandpa authorities for the current round. + /// List of GRANDPA authorities for the current round. pub authorities: AuthorityList, - /// Monotonic identifier of the current Grandpa authority set. + /// Monotonic identifier of the current GRANDPA authority set. pub set_id: SetId, } impl AuthoritySet { - /// Create a new Grandpa Authority Set. + /// Create a new GRANDPA Authority Set. pub fn new(authorities: AuthorityList, set_id: SetId) -> Self { Self { authorities, set_id } } } -/// Keeps track of when the next Grandpa authority set change will occur. +/// Keeps track of when the next GRANDPA authority set change will occur. #[derive(Default, Encode, Decode, RuntimeDebug, PartialEq, Clone)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct ScheduledChange { diff --git a/bridges/modules/substrate/src/verifier.rs b/bridges/modules/substrate/src/verifier.rs index 1b58df03f85e0..913129f19c6ef 100644 --- a/bridges/modules/substrate/src/verifier.rs +++ b/bridges/modules/substrate/src/verifier.rs @@ -19,7 +19,7 @@ //! //! When importing headers it performs checks to ensure that no invariants are broken (like //! importing the same header twice). When it imports finality proofs it will ensure that the proof -//! has been signed off by the correct Grandpa authorities, and also enact any authority set changes +//! has been signed off by the correct GRANDPA authorities, and also enact any authority set changes //! if required. use crate::justification::verify_justification; @@ -34,8 +34,8 @@ use sp_std::{prelude::Vec, vec}; /// The finality proof used by the pallet. /// -/// For a Substrate based chain using Grandpa this will -/// be an encoded Grandpa Justification. +/// For a Substrate based chain using GRANDPA this will +/// be an encoded GRANDPA Justification. #[derive(RuntimeDebug)] pub struct FinalityProof(Vec); @@ -139,7 +139,7 @@ where // we need to make a note of it. // // Note: This assumes that we can only have one authority set change pending per fork at a - // time. While this is not strictly true of Grandpa (it can have multiple pending changes, + // time. While this is not strictly true of GRANDPA (it can have multiple pending changes, // even across forks), this assumption simplifies our tracking of authority set changes. let mut signal_hash = parent_header.signal_hash; let scheduled_change = find_scheduled_change(&header); @@ -213,7 +213,7 @@ where Ok(()) } - /// Verify that a previously imported header can be finalized with the given Grandpa finality + /// Verify that a previously imported header can be finalized with the given GRANDPA finality /// proof. If the header enacts an authority set change the change will be applied once the /// header has been finalized. pub fn import_finality_proof(&mut self, hash: H::Hash, proof: FinalityProof) -> Result<(), FinalizationError> { @@ -680,7 +680,7 @@ mod tests { let mut storage = PalletStorage::::new(); let _imported_headers = write_default_headers(&mut storage, vec![1]); - // Nothing special about this header, yet Grandpa may have created a justification + // Nothing special about this header, yet GRANDPA may have created a justification // for it since it does that periodically let header = test_header(2); diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 1edd4675da1b8..348b5bf1d277d 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -29,7 +29,7 @@ pub trait Chain: Send + Sync + 'static { // See here for more info: // https://crates.parity.io/sp_runtime/traits/trait.Header.html#associatedtype.Number // - // Note that the `AsPrimitive` trait is required by the Grandpa justification + // Note that the `AsPrimitive` trait is required by the GRANDPA justification // verifier, and is not usually part of a Substrate Header's Number type. type BlockNumber: Parameter + Member