|
| 1 | +# Bridge Parachains Pallet |
| 2 | + |
| 3 | +The bridge parachains pallet is a light client for one or several parachains of the bridged relay chain. |
| 4 | +It serves as a source of finalized parachain headers and is used when you need to build a bridge with |
| 5 | +a parachain. |
| 6 | + |
| 7 | +The pallet requires [bridge GRANDPA pallet](../grandpa/) to be deployed at the same chain - it is used |
| 8 | +to verify storage proofs, generated at the bridged relay chain. |
| 9 | + |
| 10 | +## A Brief Introduction into Parachains Finality |
| 11 | + |
| 12 | +You can find detailed information on parachains finality in the [Polkadot](https://github.com/paritytech/polkadot) |
| 13 | +and [Cumulus](https://github.com/paritytech/cumulus) repositories. This section gives a brief overview of how |
| 14 | +the parachain finality works and how to build a light client for a parachain. |
| 15 | + |
| 16 | +The main thing there is that the parachain generates blocks on its own, but it can't achieve finality without |
| 17 | +help of its relay chain. Instead, the parachain collators create a block and hand it over to the relay chain |
| 18 | +validators. Validators validate the block and register the new parachain head in the |
| 19 | +[`Heads` map](https://github.com/paritytech/polkadot/blob/88013730166ba90745ae7c9eb3e0c1be1513c7cc/runtime/parachains/src/paras/mod.rs#L645) |
| 20 | +of the [`paras`](https://github.com/paritytech/polkadot/tree/master/runtime/parachains/src/paras) pallet, |
| 21 | +deployed at the relay chain. Keep in mind that this pallet, deployed at a relay chain, is **NOT** a bridge pallet, |
| 22 | +even though the names are similar. |
| 23 | + |
| 24 | +And what the bridge parachains pallet does, is simply verifying storage proofs of parachain heads within that |
| 25 | +`Heads` map. It does that using relay chain header, that has been previously imported by the |
| 26 | +[bridge GRANDPA pallet](../grandpa/). Once the proof is verified, the pallet knows that the given parachain |
| 27 | +header has been finalized by the relay chain. The parachain header fields may then be used to verify storage |
| 28 | +proofs, coming from the parachain. This allows the pallet to be used e.g. as a source of finality for the messages |
| 29 | +pallet. |
| 30 | + |
| 31 | +## Pallet Operations |
| 32 | + |
| 33 | +The main entrypoint of the pallet is the `submit_parachain_heads` call. It has three arguments: |
| 34 | + |
| 35 | +- storage proof of parachain heads from the `Heads` map; |
| 36 | + |
| 37 | +- parachain identifiers and hashes of their heads from the storage proof; |
| 38 | + |
| 39 | +- the relay block, at which the storage proof has been generated. |
| 40 | + |
| 41 | +The pallet may track multiple parachains. And the parachains may use different primitives - one may use 128-bit block |
| 42 | +numbers, other - 32-bit. To avoid extra decode operations, the pallet is using relay chain block number to order |
| 43 | +parachain headers. Any finalized descendant of finalized relay block `RB`, which has parachain block `PB` in |
| 44 | +its `Heads` map, is guaranteed to have either `PB`, or its descendant. So parachain block number grows with relay |
| 45 | +block number. |
| 46 | + |
| 47 | +The pallet may reject parachain head if it already knows better (or the same) head. In addition, pallet rejects |
| 48 | +heads of untracked parachains. |
| 49 | + |
| 50 | +The pallet doesn't track anything behind parachain heads. So it requires no initialization - it is ready to accept |
| 51 | +headers right after deployment. |
| 52 | + |
| 53 | +## Non-Essential Functionality |
| 54 | + |
| 55 | +There may be a special account in every runtime where the bridge parachains module is deployed. This |
| 56 | +account, named 'module owner', is like a module-level sudo account - he's able to halt and |
| 57 | +resume all module operations without requiring runtime upgrade. Calls that are related to this |
| 58 | +account are: |
| 59 | + |
| 60 | +- `fn set_owner()`: current module owner may call it to transfer "ownership" to another account; |
| 61 | + |
| 62 | +- `fn set_operating_mode()`: the module owner (or sudo account) may call this function to stop all |
| 63 | + module operations. After this call, all finality proofs will be rejected until further `set_operating_mode` call'. |
| 64 | + This call may be used when something extraordinary happens with the bridge. |
| 65 | + |
| 66 | +If pallet owner is not defined, the governance may be used to make those calls. |
| 67 | + |
| 68 | +## Signed Extension to Reject Obsolete Headers |
| 69 | + |
| 70 | +It'd be better for anyone (for chain and for submitters) to reject all transactions that are submitting |
| 71 | +already known parachain heads to the pallet. This way, we leave block space to other useful transactions and |
| 72 | +we don't charge concurrent submitters for their honest actions. |
| 73 | + |
| 74 | +To deal with that, we have a [signed extension](./src/extension.rs) that may be added to the runtime. |
| 75 | +It does exactly what is required - rejects all transactions with already known heads. The submitter |
| 76 | +pays nothing for such transactions - they're simply removed from the transaction pool, when the block |
| 77 | +is built. |
| 78 | + |
| 79 | +The signed extension, however, is a bit limited - it only works with transactions that provide single |
| 80 | +parachain head. So it won't work with multiple parachain heads transactions. This fits our needs |
| 81 | +for [Kusama <> Polkadot bridge](../../docs/polkadot-kusama-bridge-overview.md). If you need to deal |
| 82 | +with other transaction formats, you may implement similar extension for your runtime. |
| 83 | + |
| 84 | +You may also take a look at the [`generate_bridge_reject_obsolete_headers_and_messages`](../../bin/runtime-common/src/lib.rs) |
| 85 | +macro that bundles several similar signed extensions in a single one. |
| 86 | + |
| 87 | +## Parachains Finality Relay |
| 88 | + |
| 89 | +We have an offchain actor, who is watching for new parachain heads and submits them to the bridged chain. |
| 90 | +It is the parachains relay - you may look at the [crate level documentation and the code](../../relays/parachains/). |
0 commit comments