mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 06:41:02 +00:00
Update project level docs (#1734)
* updated project level document * updated high level overview document * GRANDPA finality relay sequence diagram * Parachains Finality Relay Sequence Diagram * Messages Relay Sequence Diagram * Complex Relayer Sequence Diagram * small fix * Polkadot <> Kusama bridge flowchart * remove obsolete files * started polkadot-kusama-bridge-overview.md * continue polkadot-kusama-bridge-overview.md * couple more sections in polkadot-kusama-bridge-overview.md * continue polkadot-kusama-bridge-overview.md * renew deployments readme * fixed review suggestions * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * removed obsolete section * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * typo * Update docs/polkadot-kusama-bridge-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/high-level-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/polkadot-kusama-bridge-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/polkadot-kusama-bridge-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/polkadot-kusama-bridge-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update docs/polkadot-kusama-bridge-overview.md Co-authored-by: Adrian Catangiu <adrian@parity.io> Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
committed by
Bastian Köcher
parent
64f03aaa0b
commit
7821e66bcd
+132
-116
@@ -1,165 +1,181 @@
|
||||
# High-Level Bridge Documentation
|
||||
|
||||
This document gives a brief, abstract description of main components that may be found in this repository.
|
||||
If you want to see how we're using them to build Rococo <> Wococo (Kusama <> Polkadot) bridge, please
|
||||
refer to the [Polkadot <> Kusama Bridge](./polkadot-kusama-bridge-overview.md).
|
||||
|
||||
## Purpose
|
||||
|
||||
Trustless connecting between two Substrate-based chains using GRANDPA finality.
|
||||
This repo contains all components required to build a trustless connection between standalone Substrate chains,
|
||||
that are using GRANDPA finality, their parachains or any combination of those. On top of this connection, we
|
||||
offer a messaging pallet that provides means to organize messages exchange.
|
||||
|
||||
## Overview
|
||||
On top of that layered infrastructure, anyone may build their own bridge applications - e.g. [XCM messaging](./polkadot-kusama-bridge-overview.md),
|
||||
[encoded calls messaging](https://github.com/paritytech/parity-bridges-common/releases/tag/encoded-calls-messaging) and so on.
|
||||
|
||||
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.
|
||||
## Terminology
|
||||
|
||||
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.
|
||||
Even though we support (and require) two-way bridging, the documentation will generally talk about
|
||||
a one-sided interaction. That's to say, we will only talk about syncing finality proofs 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.
|
||||
|
||||
The bridge is built from various components. Here is a quick overview of the important ones.
|
||||
The bridge has both on-chain (pallets) and offchain (relayers) components.
|
||||
|
||||
### Header Sync
|
||||
## On-chain components
|
||||
|
||||
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.
|
||||
On-chain bridge components are pallets that are deployed at the chain runtime. Finality pallets require
|
||||
deployment at the target chain, while messages pallet needs to be deployed at both, source
|
||||
and target chains.
|
||||
|
||||
### Headers Relayer
|
||||
### Bridge GRANDPA Finality Pallet
|
||||
|
||||
A standalone application connected to both chains. It submits every source chain header it sees to
|
||||
the target chain through RPC.
|
||||
A GRANDPA light client of the source chain built into the target chain's runtime. It provides a "source of truth"
|
||||
about the source chain headers which have been finalized. This is useful for higher level applications.
|
||||
|
||||
### Message Delivery
|
||||
The pallet tracks current GRANDPA authorities set and only accepts finality proofs (GRANDPA justifications),
|
||||
generated by the current authorities set. The GRANDPA protocol itself requires current authorities set to
|
||||
generate explicit justificaion for the header that enacts next authorities set. Such headers and their finality
|
||||
proofs are called mandatory in the pallet and relayer pays no fee for such headers submission.
|
||||
|
||||
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.
|
||||
The pallet does not require all headers to be imported or provided. The relayer itself chooses which headers
|
||||
he wants to submit (with the exception of mandatory headers).
|
||||
|
||||
### Message Dispatch
|
||||
More: [code](../modules/grandpa/).
|
||||
|
||||
A FRAME pallet responsible for interpreting the payload of delivered messages.
|
||||
### Bridge Parachains Finality Pallet
|
||||
|
||||
### Message Relayer
|
||||
Parachains are not supposed to have their own finality, so we can't use bridge GRANDPA pallet to verify their
|
||||
finality proofs. Instead, they rely on their relay chain finality. The parachain header is considered final,
|
||||
when it is accepted by the [`paras` pallet](https://github.com/paritytech/polkadot/tree/1a034bd6de0e76721d19aed02a538bcef0787260/runtime/parachains/src/paras)
|
||||
at its relay chain. Obviously, the relay chain block, where it is accepted, must also be finalized by the relay
|
||||
chain GRANDPA gadget.
|
||||
|
||||
A standalone application handling delivery of the messages from source chain to the target chain.
|
||||
That said, the bridge parachains pallet accepts storage proof of one or several parachain heads, inserted to the
|
||||
[`Heads`](https://github.com/paritytech/polkadot/blob/1a034bd6de0e76721d19aed02a538bcef0787260/runtime/parachains/src/paras/mod.rs#L642)
|
||||
map of the [`paras` pallet](https://github.com/paritytech/polkadot/tree/1a034bd6de0e76721d19aed02a538bcef0787260/runtime/parachains/src/paras).
|
||||
To verify this storage proof, the pallet uses relay chain header, imported earlier by the bridge GRANDPA pallet.
|
||||
|
||||
## Processes
|
||||
The pallet may track multiple parachains at once and those parachains may use different primitives. So the
|
||||
parachain header decoding never happens at the pallet level. For maintaining the headers order, the pallet
|
||||
uses relay chain header number.
|
||||
|
||||
High level sequence charts of the process can be found in [a separate document](./high-level.html).
|
||||
More: [code](../modules/parachains/).
|
||||
|
||||
### Substrate (GRANDPA) Header Sync
|
||||
### Bridge Messages Pallet
|
||||
|
||||
The header sync pallet (`pallet-bridge-grandpa`) is an on-chain light client for chains which use
|
||||
GRANDPA finality. It is part of the target chain's runtime, and accepts finality proofs from the source
|
||||
chain. Verify GRANDPA finality proofs (a.k.a justifications) and track GRANDPA finality set changes.
|
||||
The pallet is responsible for queuing messages at the source chain and receiving the messages proofs at the
|
||||
target chain. The messages are sent to the particular _lane_, where they are guaranteed to be received in the
|
||||
same order they are sent. The pallet supports many lanes.
|
||||
|
||||
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. In fact the pallet does not
|
||||
necessarily store all produced headers, we only import headers with valid GRANDPA justifications.
|
||||
The lane has two ends. Outbound lane end is storing number of messages that have been sent and the number of
|
||||
messages that have been received. Inbound lane end stores the number of messages that have been received and
|
||||
also a map that maps messages to relayers that have delivered those messages to the target chain.
|
||||
|
||||
Referer to the [pallet documentation](../modules/grandpa/src/lib.rs) for more details.
|
||||
The pallet has three main entrypoints:
|
||||
- the `send_message` may be used by the other runtime pallets to send the messages;
|
||||
- the `receive_messages_proof` is responsible for parsing the messages proof and handing messages over to the
|
||||
dispatch code;
|
||||
- the `receive_messages_delivery_proof` is responsible for parsing the messages delivery proof and rewarding
|
||||
relayers that have delivered the message.
|
||||
|
||||
#### Header Relayer strategy
|
||||
Many things are abstracted by the pallet:
|
||||
- the message itself may mean anything, the pallet doesn't care about its content;
|
||||
- the message dispatch happens during delivery, but it is decoupled from the pallet code;
|
||||
- the messages proof and messages delivery proof are verified outside of the pallet;
|
||||
- the relayers incentivization scheme is defined outside of the pallet.
|
||||
|
||||
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 incentivization should be happening on the higher layers.
|
||||
Outside of the messaging pallet, we have a set of adapters, where messages and delivery proofs are regular
|
||||
storage proofs. The proofs are generated at the bridged chain and require bridged chain finality. So messages
|
||||
pallet, in this case, depends on one of the finality pallets. The messages are XCM messages and we are using
|
||||
XCM executor to dispatch them on receival. You may find more info in [Polkadot <> Kusama Bridge](./polkadot-kusama-bridge-overview.md)
|
||||
document.
|
||||
|
||||
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.
|
||||
More: [code](../modules/messages/).
|
||||
|
||||
### Message Passing
|
||||
### Bridge Relayers Pallet
|
||||
|
||||
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.
|
||||
The pallet is quite simple. It just registers relayer rewards and has an entrypoint to collect them. When
|
||||
the rewards are registered and the reward amount is configured outside of the pallet.
|
||||
|
||||
#### Message Lanes Delivery
|
||||
More: [code](../modules/relayers/).
|
||||
|
||||
The [Message delivery pallet](../modules/messages/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.
|
||||
## Offchain Components
|
||||
|
||||
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.
|
||||
Offchain bridge components are separate processes, called relayers. Relayers are connected both to the
|
||||
source chain and target chain nodes. Relayers are reading state of the source chain, compare it to the
|
||||
state of the target chain and, if state at target chain needs to be updated, submits target chain
|
||||
transaction.
|
||||
|
||||
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.
|
||||
### GRANDPA Finality Relay
|
||||
|
||||
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 successfully 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.
|
||||
The task of relay is to submit source chain GRANDPA justifications and their corresponding headers to
|
||||
the Bridge GRANDPA Finality Pallet, deployed at the target chain. For that, the relay subscribes to
|
||||
the source chain GRANDPA justifications stream and submits every new justification it sees to the
|
||||
target chain GRANDPA light client. In addition, relay is searching for mandatory headers and
|
||||
submits their justifications - without that the pallet will be unable to move forward.
|
||||
|
||||
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.
|
||||
More: [GRANDPA Finality Relay Sequence Diagram](./grandpa-finality-relay.html), [code](../relays/finality/).
|
||||
|
||||
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.
|
||||
### Parachains Finality Relay
|
||||
|
||||
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).
|
||||
The relay connects to the source _relay_ chain and the target chain nodes. It doesn't need to connect to the
|
||||
tracked parachain nodes. The relay looks at the [`Heads`](https://github.com/paritytech/polkadot/blob/1a034bd6de0e76721d19aed02a538bcef0787260/runtime/parachains/src/paras/mod.rs#L642)
|
||||
map of the [`paras` pallet](https://github.com/paritytech/polkadot/tree/1a034bd6de0e76721d19aed02a538bcef0787260/runtime/parachains/src/paras)
|
||||
in source chain, and compares the value with the best parachain head, stored in the bridge parachains pallet at
|
||||
the taget chain. If new parachain head appears at the relay chain block `B`, the relay process **waits**
|
||||
until header `B` or one of its ancestors appears at the target chain. Once it is available, the storage
|
||||
proof of the map entry is generated and is submitted to the target chain.
|
||||
|
||||
#### Dispatching Messages
|
||||
As its on-chain component (which requires bridge GRANDPA pallet to be deployed nearby), the parachains
|
||||
finality relay requires GRANDPA finality relay to be running in parallel. Without it, the header `B` or
|
||||
any of its children's finality at source won't be relayed at target, and target chain
|
||||
won't be able to verify generated storage proof.
|
||||
|
||||
The [Message dispatch pallet](../modules/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.
|
||||
More: [Parachains Finality Relay Sequence Diagram](./parachains-finality-relay.html), [code](../relays/parachains/).
|
||||
|
||||
An example `Call` of the target chain would look something like this:
|
||||
### Messages Relay
|
||||
|
||||
```rust
|
||||
target_runtime::Call::Balances(target_runtime::pallet_balances::Call::transfer(recipient, amount))
|
||||
```
|
||||
Messages relay is actually two relays that are running in a single process: messages delivery relay and
|
||||
delivery confirmation relay. Even though they are more complex and have many caveats, the overall algorithm
|
||||
is the same as in other relays.
|
||||
|
||||
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.
|
||||
Message delivery relay connects to the source chain and looks at the outbound lane end, waiting until new
|
||||
messages are queued there. Once they appear at the source block `B`, the relay start waiting for the block
|
||||
`B` or its descendant appear at the target chain. Then the messages storage proof is generated and submitted
|
||||
to the bridge messages pallet at the target chain. In addition, the transaction may include the storage proof
|
||||
of the outbound lane state - that proves that relayer rewards have been paid and this data (map of relay
|
||||
accounts to the delivered messages) may be pruned from the inbound lane state at the target 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
|
||||
Delivery confirmation relay connects to the target chain and starts watching the inbound lane end. When new
|
||||
messages are delivered to the target chain, the corresponding _source chain account_ is inserted to the
|
||||
map in the inbound lane data. Relay detects that, say, at the target chain block `B` and waits until that
|
||||
block or its descendant appears at the source chain. Once that happens, the relay crafts a storage proof of
|
||||
that data and sends it to the messages pallet, deployed at the source chain.
|
||||
|
||||
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.
|
||||
As you can see, the messages relay also requires finality relay to be operating in parallel. Since messages
|
||||
relay submits transactions to both source and target chains, it requires both _source-to-target_ and
|
||||
_target-to-source_ finality relays. They can be GRANDPA finality relays or GRANDPA+parachains finality relays,
|
||||
depending on the type of connected chain.
|
||||
|
||||
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.
|
||||
More: [Messages Relay Sequence Diagram](./messages-relay.html), [code](../relays/messages/).
|
||||
|
||||
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.
|
||||
### Complex Relay
|
||||
|
||||
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.
|
||||
Every relay transaction has its cost. The only transaction, that is "free" to relayer is when the mandatory
|
||||
GRANDPA header is submitted. The relay that feeds the bridge with every relay chain and/or parachain head it
|
||||
sees, will have to pay a (quite large) cost. And if no messages are sent through the bridge, that is just
|
||||
waste of money.
|
||||
|
||||
See [`CallOrigin` documentation](../primitives/message-dispatch/src/lib.rs) for more details.
|
||||
We have a special relay mode, called _complex relay_, where relay mostly sleeps and only submits transactions
|
||||
that are required for the messages/confirmations delivery. This mode starts two message relays (in both
|
||||
directions). All required finality relays are also started in a special _on-demand_ mode. In this mode they
|
||||
do not submit any headers without special request. As always, the only exception is when GRANDPA finality
|
||||
relay sees the mandatory header - it is submitted without such request.
|
||||
|
||||
#### Message Relayers Strategy
|
||||
The message relays are watching their lanes and when, at some block `B`, they see new messages/confirmations
|
||||
to be delivered, they are asking on-demand relays to relay this block `B`. On-demand relays does that and
|
||||
then message relay may perform its job. If on-demand relay is a parachain finality relay, it also runs its
|
||||
own on-demand GRANDPA relay, which is used to relay required relay chain headers.
|
||||
|
||||
More: [Complex Relay Sequence Diagram](./complex-relay.html), [code](../relays/bin-substrate/src/cli/relay_headers_and_messages/).
|
||||
|
||||
Reference in New Issue
Block a user