feat: initialize Kurdistan SDK - independent fork of Polkadot SDK
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Complex Relay</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Complex Relay</h1>
|
||||
<p>
|
||||
Both Source Chain and Target Chains have Bridge Messages pallets deployed. They also have required
|
||||
finality pallets deployed - we don't care about finality type here - they can be either Bridge GRANDPA,
|
||||
or Bridge Parachains finality pallets, or any combination of those.<br/>
|
||||
</p>
|
||||
<p>
|
||||
There are 4-6 relayer subprocesses inside the Complex Relayer. They include two message relayers,
|
||||
serving the lane in both directions and 2-4 Complex Relayers (depending on the finality type of Source
|
||||
and Target Chains).<br/>
|
||||
</p>
|
||||
<p>
|
||||
The following diagram shows the way the complex relayer serves the lane in single direction. Everything
|
||||
below may be applied to the opposite direction if you'll swap the Source and Target Chains.
|
||||
</p>
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
participant Source Chain
|
||||
participant Complex Relayer
|
||||
participant Target Chain
|
||||
|
||||
Note right of Source Chain: Finalized: 480, Target Finalized: 50, Sent Messages: 42, Confirmed Messages: 42
|
||||
Note left of Target Chain: Finalized: 60, Source Finalized: 420, Received Messages: 42
|
||||
|
||||
Source Chain ->> Source Chain: someone Sends Message 43
|
||||
Source Chain ->> Source Chain: Import and Finalize Block 481
|
||||
|
||||
Source Chain ->> Complex Relayer: notes new outbound message 43 at Source Chain Block 481
|
||||
Note right of Complex Relayer: can't deliver message 43, Source Chain Block 481 is not relayed
|
||||
Complex Relayer ->> Complex Relayer: asks on-demand Finality Relayer to relay Source Chain Block 481
|
||||
|
||||
Source Chain ->> Complex Relayer: Read Finality Proof of Block 481
|
||||
Complex Relayer ->> Target Chain: Submit Finality Proof of Block 481
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 61
|
||||
Note left of Target Chain: Finalized: 61, Source Finalized: 481, Received Messages: 42
|
||||
|
||||
Source Chain ->> Complex Relayer: Read Proof of Message 43 at Block 481
|
||||
Complex Relayer ->> Target Chain: Submit Proof of Message 43 at Block 481
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 62
|
||||
Note left of Target Chain: Finalized: 62, Source Finalized: 481, Received Messages: { rewarded: 42, messages-relayer-account: [43] }
|
||||
|
||||
Target Chain ->> Complex Relayer: notes new unrewarded relayer at Target Chain Block 62
|
||||
Note right of Complex Relayer: can't relay delivery confirmations because Target Chain Block 62 is not relayed
|
||||
Complex Relayer ->> Complex Relayer: asks on-demand Finality Relayer to relay Target Chain Block 62
|
||||
|
||||
Target Chain ->> Complex Relayer: Read Finality Proof of Block 62
|
||||
Complex Relayer ->> Source Chain: Submit Finality Proof of Block 62
|
||||
Source Chain ->> Source Chain: Import and Finalize Block 482
|
||||
Note right of Source Chain: Finalized: 482, Target Finalized: 62, Confirmed Messages: 42
|
||||
|
||||
Target Chain ->> Complex Relayer: Read Proof of Message 43 Delivery at Block 62
|
||||
Complex Relayer ->> Source Chain: Submit Proof of Message 43 Delivery at Block 612
|
||||
Source Chain ->> Source Chain: rewards messages-relayer-account for delivering message [43]
|
||||
Source Chain ->> Source Chain: prune delivered message 43 from runtime storage
|
||||
Note right of Source Chain: Finalized: 482, Target Finalized: 61, Confirmed Messages: 43
|
||||
|
||||
Source Chain ->> Source Chain: someone Sends Message 44
|
||||
Source Chain ->> Source Chain: Import and Finalize Block 483
|
||||
|
||||
Source Chain ->> Complex Relayer: notes new outbound message 44 at Source Chain Block 483 and new confirmed message 43
|
||||
Note right of Complex Relayer: can't deliver message 44, Source Chain Block 483 is not relayed
|
||||
Complex Relayer ->> Complex Relayer: asks on-demand Finality Relayer to relay Source Chain Block 483
|
||||
|
||||
Source Chain ->> Complex Relayer: Read Finality Proof of Block 483
|
||||
Complex Relayer ->> Target Chain: Submit Finality Proof of Block 483
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 63
|
||||
Note left of Target Chain: Finalized: 63, Source Finalized: 483, Received Messages: { rewarded: 42, messages-relayer-account: [43] }
|
||||
|
||||
Source Chain ->> Complex Relayer: Read Proof of Message 44 and Proof of Message 43 reward at Block 483
|
||||
Complex Relayer ->> Target Chain: Submit Proof of Message 44 and Proof of Message 43 reward at Block 483
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 64
|
||||
Note left of Target Chain: Finalized: 64, Source Finalized: 483, Received Messages: { rewarded: 43, messages-relayer-account: [44] }-->
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.8.4/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad: true})</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>GRANDPA Finality Relay</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>GRANDPA Finality Relay</h1>
|
||||
<p>
|
||||
Source Chain is running GRANDPA Finality Gadget. Bridge GRANDPA finality pallet is deployed at
|
||||
Target Chain runtime. Relayer is configured to relay Source Chain finality to Target Chain.
|
||||
</p>
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
participant Source Chain
|
||||
participant Relayer
|
||||
participant Target Chain
|
||||
Note left of Source Chain: Best: 500, Finalized: 480, Authorities Set Index: 42
|
||||
Note right of Target Chain: Uninitialized
|
||||
|
||||
Source Chain ->> Relayer: Read Initialization Data
|
||||
Relayer ->> Target Chain: Initialize Bridge GRANDPA Finality Pallet
|
||||
Note right of Target Chain: Finalized: 480, Authorities Set Index: 42
|
||||
|
||||
Source Chain ->> Source Chain: Import Block 501
|
||||
Source Chain ->> Source Chain: Import Block 502
|
||||
Source Chain ->> Source Chain: Finalize Block 495
|
||||
Source Chain ->> Relayer: Read Finality Proof of Block 495
|
||||
Relayer ->> Target Chain: Finality Proof of Block 495
|
||||
Note right of Target Chain: Finalized: 495, Authorities Set Index: 42
|
||||
|
||||
Source Chain ->> Source Chain: Import Block 503 that changes Authorities Set to 43
|
||||
Source Chain ->> Source Chain: Finalize Block 500
|
||||
Note left of Relayer: Relayer Misses Finality Notification for Block 500
|
||||
|
||||
Source Chain ->> Source Chain: Import Block 504
|
||||
Source Chain ->> Source Chain: Finalize Mandatory Block 503
|
||||
Source Chain ->> Source Chain: Finalize Block 504
|
||||
Source Chain ->> Relayer: Read Finality Proof of Mandatory Block 503
|
||||
Relayer ->> Target Chain: Finality Proof of Block 503
|
||||
Note right of Target Chain: Finalized: 503, Authorities Set Index: 43
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.8.4/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad: true})</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,184 @@
|
||||
# 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 Pezkuwichain <> Zagros (Kusama <> Pezkuwi) bridge, please refer to the [Pezkuwi <>
|
||||
Kusama Bridge](./pezkuwi-kusama-bridge-overview.md).
|
||||
|
||||
## Purpose
|
||||
|
||||
This repo contains all components required to build a trustless connection between standalone Substrate chains, that are
|
||||
using GRANDPA finality, their teyrchains or any combination of those. On top of this connection, we offer a messaging
|
||||
pallet that provides means to organize messages exchange.
|
||||
|
||||
On top of that layered infrastructure, anyone may build their own bridge applications - e.g. [XCM
|
||||
messaging](./pezkuwi-kusama-bridge-overview.md), [encoded calls
|
||||
messaging](https://github.com/paritytech/parity-bridges-common/releases/tag/encoded-calls-messaging) and so on.
|
||||
|
||||
## Terminology
|
||||
|
||||
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 has both on-chain (pallets) and offchain (relayers) components.
|
||||
|
||||
## On-chain components
|
||||
|
||||
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.
|
||||
|
||||
### Bridge GRANDPA Finality Pallet
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
justification 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.
|
||||
|
||||
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).
|
||||
|
||||
More: [pallet level documentation and code](../modules/grandpa/).
|
||||
|
||||
### Bridge Teyrchains Finality Pallet
|
||||
|
||||
Teyrchains 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 teyrchain 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.
|
||||
|
||||
That said, the bridge teyrchains pallet accepts storage proof of one or several teyrchain 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.
|
||||
|
||||
The pallet may track multiple teyrchains at once and those teyrchains may use different primitives. So the teyrchain
|
||||
header decoding never happens at the pallet level. For maintaining the headers order, the pallet uses relay chain header
|
||||
number.
|
||||
|
||||
More: [pallet level documentation and code](../modules/teyrchains/).
|
||||
|
||||
### Bridge Messages Pallet
|
||||
|
||||
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 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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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 [Pezkuwi <> Kusama Bridge](./pezkuwi-kusama-bridge-overview.md) document.
|
||||
|
||||
More: [pallet level documentation and code](../modules/messages/).
|
||||
|
||||
### Bridge Relayers Pallet
|
||||
|
||||
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.
|
||||
|
||||
More: [pallet level documentation and code](../modules/relayers/).
|
||||
|
||||
## Offchain Components
|
||||
|
||||
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.
|
||||
|
||||
### GRANDPA Finality Relay
|
||||
|
||||
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.
|
||||
|
||||
More: [GRANDPA Finality Relay Sequence Diagram](./grandpa-finality-relay.html), [pallet level documentation and
|
||||
code](../relays/finality/).
|
||||
|
||||
### Teyrchains Finality Relay
|
||||
|
||||
The relay connects to the source _relay_ chain and the target chain nodes. It doesn't need to connect to the tracked
|
||||
teyrchain 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 teyrchain head, stored in the bridge teyrchains pallet at the
|
||||
target chain. If new teyrchain 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.
|
||||
|
||||
As its on-chain component (which requires bridge GRANDPA pallet to be deployed nearby), the teyrchains 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.
|
||||
|
||||
More: [Teyrchains Finality Relay Sequence Diagram](./teyrchains-finality-relay.html), [code](../relays/teyrchains/).
|
||||
|
||||
### Messages Relay
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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+teyrchains finality relays, depending on the type of
|
||||
connected chain.
|
||||
|
||||
More: [Messages Relay Sequence Diagram](./messages-relay.html), [pallet level documentation and
|
||||
code](../relays/messages/).
|
||||
|
||||
### Complex Relay
|
||||
|
||||
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 teyrchain 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.
|
||||
|
||||
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.
|
||||
|
||||
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 teyrchain 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/).
|
||||
@@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Messages Relay</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Messages Relay</h1>
|
||||
<p>
|
||||
Both Source Chain and Target Chains have Bridge Messages pallets deployed. They also have required
|
||||
finality pallets deployed - we don't care about finality type here - they can be either Bridge GRANDPA,
|
||||
or Bridge Parachains finality pallets, or any combination of those.
|
||||
</p>
|
||||
<p>
|
||||
Finality Relayer represents two actual relayers - one relays Source Chain Finality to Target Chain.
|
||||
And another one relays Target Chain Finality to Source Chain.
|
||||
</p>
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
participant Source Chain
|
||||
participant Finality Relayer
|
||||
participant Messages Relayer
|
||||
participant Target Chain
|
||||
|
||||
Note right of Source Chain: Finalized: 480, Target Finalized: 50, Sent Messages: 42, Confirmed Messages: 42
|
||||
Note left of Target Chain: Finalized: 60, Source Finalized: 420, Received Messages: 42
|
||||
|
||||
Source Chain ->> Source Chain: someone Sends Message 43
|
||||
Source Chain ->> Source Chain: Import and Finalize Block 481
|
||||
|
||||
Source Chain ->> Messages Relayer: notes new outbound message 43 at Source Chain Block 481
|
||||
Note right of Messages Relayer: can't deliver message 43, Source Chain Block 481 is not relayed
|
||||
|
||||
Source Chain ->> Finality Relayer: Read Finality Proof of Block 481
|
||||
Finality Relayer ->> Target Chain: Submit Finality Proof of Block 481
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 61
|
||||
Note left of Target Chain: Finalized: 61, Source Finalized: 481, Received Messages: 42
|
||||
|
||||
Source Chain ->> Messages Relayer: Read Proof of Message 43 at Block 481
|
||||
Messages Relayer ->> Target Chain: Submit Proof of Message 43 at Block 481
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 62
|
||||
Note left of Target Chain: Finalized: 62, Source Finalized: 481, Received Messages: { rewarded: 42, messages-relayer-account: [43] }
|
||||
|
||||
Target Chain ->> Messages Relayer: notes new unrewarded relayer at Target Chain Block 62
|
||||
Note right of Messages Relayer: can't relay delivery confirmations because Target Chain Block 62 is not relayed
|
||||
|
||||
Target Chain ->> Finality Relayer: Read Finality Proof of Block 62
|
||||
Finality Relayer ->> Source Chain: Submit Finality Proof of Block 62
|
||||
Source Chain ->> Source Chain: Import and Finalize Block 482
|
||||
Note right of Source Chain: Finalized: 482, Target Finalized: 62, Confirmed Messages: 42
|
||||
|
||||
Target Chain ->> Messages Relayer: Read Proof of Message 43 Delivery at Block 62
|
||||
Messages Relayer ->> Source Chain: Submit Proof of Message 43 Delivery at Block 612
|
||||
Source Chain ->> Source Chain: rewards messages-relayer-account for delivering message [43]
|
||||
Source Chain ->> Source Chain: prune delivered message 43 from runtime storage
|
||||
Note right of Source Chain: Finalized: 482, Target Finalized: 61, Confirmed Messages: 43
|
||||
|
||||
Source Chain ->> Source Chain: someone Sends Message 44
|
||||
Source Chain ->> Source Chain: Import and Finalize Block 483
|
||||
|
||||
Source Chain ->> Messages Relayer: notes new outbound message 44 at Source Chain Block 483 and new confirmed message 43
|
||||
Note right of Messages Relayer: can't deliver message 44, Source Chain Block 483 is not relayed
|
||||
|
||||
Source Chain ->> Finality Relayer: Read Finality Proof of Block 483
|
||||
Finality Relayer ->> Target Chain: Submit Finality Proof of Block 483
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 63
|
||||
Note left of Target Chain: Finalized: 63, Source Finalized: 483, Received Messages: { rewarded: 42, messages-relayer-account: [43] }
|
||||
|
||||
Source Chain ->> Messages Relayer: Read Proof of Message 44 and Proof of Message 43 reward at Block 483
|
||||
Messages Relayer ->> Target Chain: Submit Proof of Message 44 and Proof of Message 43 reward at Block 483
|
||||
Target Chain ->> Target Chain: Import and Finalize Block 64
|
||||
Note left of Target Chain: Finalized: 64, Source Finalized: 483, Received Messages: { rewarded: 43, messages-relayer-account: [44] }
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.8.4/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad: true})</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,131 @@
|
||||
# Pezkuwi <> Kusama Bridge Overview
|
||||
|
||||
This document describes how we use all components, described in the [High-Level Bridge
|
||||
Documentation](./high-level-overview.md), to build the XCM bridge between Kusama and Pezkuwi. In this case, our
|
||||
components merely work as a XCM transport (like XCMP/UMP/HRMP), between chains that are not a part of the same consensus
|
||||
system.
|
||||
|
||||
The overall architecture may be seen in [this diagram](./pezkuwi-kusama-bridge.html).
|
||||
|
||||
## Bridge Hubs
|
||||
|
||||
All operations at relay chain are expensive. Ideally all non-mandatory transactions must happen on teyrchains. That's
|
||||
why we are planning to have two teyrchains - Pezkuwi Bridge Hub under Pezkuwi consensus and Kusama Bridge Hub under
|
||||
Kusama consensus.
|
||||
|
||||
The Bridge Hub will have all required bridge pallets in its runtime. We hope that later, other teams will be able to use
|
||||
our bridge hubs too and have their pallets there.
|
||||
|
||||
The Bridge Hub will use the base token of the ecosystem - KSM at Kusama Bridge Hub and HEZ at Pezkuwi Bridge Hub. The
|
||||
runtime will have minimal set of non-bridge pallets, so there's not much you can do directly on bridge hubs.
|
||||
|
||||
## Connecting Teyrchains
|
||||
|
||||
You won't be able to directly use bridge hub transactions to send XCM messages over the bridge. Instead, you'll need to
|
||||
use other teyrchains transactions, which will use HRMP to deliver messages to the Bridge Hub. The Bridge Hub will just
|
||||
queue these messages in its outbound lane, which is dedicated to deliver messages between two teyrchains.
|
||||
|
||||
Our first planned bridge will connect the Pezkuwi and Kusama Asset Hubs. A bridge between those two
|
||||
teyrchains would allow Asset Hub Pezkuwi accounts to hold wrapped KSM tokens and Asset Hub Kusama
|
||||
accounts to hold wrapped HEZ tokens.
|
||||
|
||||
For that bridge (pair of teyrchains under different consensus systems) we'll be using the lane 00000000. Later, when
|
||||
other teyrchains will join the bridge, they will be using other lanes for their messages.
|
||||
|
||||
## Running Relayers
|
||||
|
||||
We are planning to run our own complex relayer for the lane 00000000. The relayer will relay Kusama/Pezkuwi GRANDPA
|
||||
justifications to the bridge hubs at the other side. It'll also relay finalized Kusama Bridge Hub and Pezkuwi Bridge
|
||||
Hub heads. This will only happen when messages will be queued at hubs. So most of time relayer will be idle.
|
||||
|
||||
There's no any active relayer sets, or something like that. Anyone may start its own relayer and relay queued messages.
|
||||
We are not against that and, as always, appreciate any community efforts. Of course, running relayer has the cost. Apart
|
||||
from paying for the CPU and network, the relayer pays for transactions at both sides of the bridge. We have a mechanism
|
||||
for rewarding relayers.
|
||||
|
||||
### Compensating the Cost of Message Delivery Transactions
|
||||
|
||||
One part of our rewarding scheme is that the cost of message delivery, for honest relayer, is zero. The honest relayer
|
||||
is the relayer, which is following our rules:
|
||||
|
||||
- we do not reward relayers for submitting GRANDPA finality transactions. The only exception is submitting mandatory
|
||||
headers (headers which are changing the GRANDPA authorities set) - the cost of such transaction is zero. The relayer
|
||||
will pay the full cost for submitting all other headers;
|
||||
|
||||
- we do not reward relayers for submitting teyrchain finality transactions. The relayer will pay the full cost for
|
||||
submitting teyrchain finality transactions;
|
||||
|
||||
- we compensate the cost of message delivery transactions that have actually delivered the messages. So if your
|
||||
transaction has claimed to deliver messages `[42, 43, 44]`, but, because of some reasons, has actually delivered
|
||||
messages `[42, 43]`, the transaction will be free for relayer. If it has not delivered any messages, then the relayer
|
||||
pays the full cost of the transaction;
|
||||
|
||||
- we compensate the cost of message delivery and all required finality calls, if they are part of the same
|
||||
[`frame_utility::batch_all`](https://github.com/paritytech/substrate/blob/891d6a5c870ab88521183facafc811a203bb6541/frame/utility/src/lib.rs#L326)
|
||||
transaction. Of course, the calls inside the batch must be linked - e.g. the submitted teyrchain head must be used to
|
||||
prove messages. Relay header must be used to prove teyrchain head finality. If one of calls fails, or if they are not
|
||||
linked together, the relayer pays the full transaction cost.
|
||||
|
||||
Please keep in mind that the fee of "zero-cost" transactions is still withdrawn from the relayer account. But the
|
||||
compensation is registered in the `pallet_bridge_relayers::RelayerRewards` map at the target bridge hub. The relayer may
|
||||
later claim all its rewards later, using the `pallet_bridge_relayers::claim_rewards` call.
|
||||
|
||||
*A side note*: why we don't simply set the cost of useful transactions to zero? That's because the bridge has its cost.
|
||||
If we won't take any fees, it would mean that the sender is not obliged to pay for its messages. And Bridge Hub
|
||||
collators (and, maybe, "treasury") are not receiving any payment for including transactions. More about this later, in
|
||||
the [Who is Rewarding Relayers](#who-is-rewarding-relayers) section.
|
||||
|
||||
### Message Delivery Confirmation Rewards
|
||||
|
||||
In addition to the "zero-cost" message delivery transactions, the relayer is also rewarded for:
|
||||
|
||||
- delivering every message. The reward is registered during delivery confirmation transaction at the Source Bridge Hub.;
|
||||
|
||||
- submitting delivery confirmation transaction. The relayer may submit delivery confirmation that e.g. confirms delivery
|
||||
of four messages, of which the only one (or zero) messages is actually delivered by this relayer. It receives some fee
|
||||
for confirming messages, delivered by other relayers.
|
||||
|
||||
Both rewards may be claimed using the `pallet_bridge_relayers::claim_rewards` call at the Source Bridge Hub.
|
||||
|
||||
### Who is Rewarding Relayers
|
||||
|
||||
Obviously, there should be someone who is paying relayer rewards. We want bridge transactions to have a cost, so we
|
||||
can't use fees for rewards. Instead, the teyrchains using the bridge, use sovereign accounts on both sides of the bridge
|
||||
to cover relayer rewards.
|
||||
|
||||
Bridged Teyrchains will have sovereign accounts at bridge hubs. For example, the Kusama Asset Hub will
|
||||
have an account at the Pezkuwi Bridge Hub. The Pezkuwi Asset Hub will have an account at the Kusama
|
||||
Bridge Hub. The sovereign accounts are used as a source of funds when the relayer is calling the
|
||||
`pallet_bridge_relayers::claim_rewards`.
|
||||
|
||||
Since messages lane is only used by the pair of teyrchains, there's no collision between different bridges. E.g.
|
||||
Kusama Asset Hub will only reward relayers that are delivering messages from Kusama Asset Hub.
|
||||
The Kusama Asset Hub sovereign account is not used to cover rewards of bridging with some other Pezkuwi Teyrchain.
|
||||
|
||||
### Multiple Relayers and Rewards
|
||||
|
||||
Our goal is to incentivize running honest relayers. But we have no relayers sets, so at any time anyone may submit
|
||||
message delivery transaction, hoping that the cost of this transaction will be compensated. So what if some message is
|
||||
currently queued and two relayers are submitting two identical message delivery transactions at once? Without any
|
||||
special means, the cost of first included transaction will be compensated and the cost of the other one won't. A honest,
|
||||
but unlucky relayer will lose some money. In addition, we'll waste some portion of block size and weight, which may be
|
||||
used by other useful transactions.
|
||||
|
||||
To solve the problem, we have two signed extensions ([generate_bridge_reject_obsolete_headers_and_messages!
|
||||
{}](../bin/runtime-common/src/lib.rs) and
|
||||
[RefundRelayerForMessagesFromTeyrchain](../bin/runtime-common/src/refund_relayer_extension.rs)), that are preventing
|
||||
bridge transactions with obsolete data from including into the block. We are rejecting following transactions:
|
||||
|
||||
- transactions, that are submitting the GRANDPA justification for the best finalized header, or one of its ancestors;
|
||||
|
||||
- transactions, that are submitting the proof of the current best teyrchain head, or one of its ancestors;
|
||||
|
||||
- transactions, that are delivering already delivered messages. If at least one of messages is not yet delivered, the
|
||||
transaction is not rejected;
|
||||
|
||||
- transactions, that are confirming delivery of already confirmed messages. If at least one of confirmations is new, the
|
||||
transaction is not rejected;
|
||||
|
||||
- [`frame_utility::batch_all`](https://github.com/paritytech/substrate/blob/891d6a5c870ab88521183facafc811a203bb6541/frame/utility/src/lib.rs#L326)
|
||||
transactions, that have both finality and message delivery calls. All restrictions from the [Compensating the Cost of
|
||||
Message Delivery Transactions](#compensating-the-cost-of-message-delivery-transactions) are applied.
|
||||
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Polkadot <> Kusama Bridge</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Polkadot <> Kusama Bridge</h1>
|
||||
<p>
|
||||
Our bridge connects two parachains - Kusama Bridge Hub and Polkadot Bridge Hub. Messages that
|
||||
are sent over bridge have XCM format and we are using existing architecture to dispatch them.
|
||||
Since both Polkadot, Kusama and their parachains already have means to exchange XCM messages
|
||||
within the same consensus system (HRMP, VMP, ...), it means that we are able to connect all those
|
||||
chains with our bridge.
|
||||
</p>
|
||||
<p>
|
||||
In our architecture, the lane that is used to relay messages over the bridge is determined by
|
||||
the XCM source and destinations. So e.g. bridge between Asset Hubs Polkadot and Kusama (and opposite direction)
|
||||
will use the lane 00000000, bridge between some other Polkadot Parachain and some other Kusama Parachain
|
||||
will use the lane 00000001 and so on.
|
||||
</p>
|
||||
<div class="mermaid">
|
||||
flowchart LR
|
||||
subgraph Polkadot Consensus
|
||||
polkadot(((Polkadot)))
|
||||
asset_hub_polkadot(((Polkadot Asset Hub)))
|
||||
polkadot_bh(((Polkadot Bridge Hub)))
|
||||
|
||||
polkadot---asset_hub_polkadot
|
||||
polkadot---polkadot_bh
|
||||
|
||||
asset_hub_polkadot-->|Send Message Using HRMP|polkadot_bh
|
||||
|
||||
polkadot_bh-->|Send Message Using HRMP|asset_hub_polkadot
|
||||
asset_hub_polkadot-->|Dispatch the Message|asset_hub_polkadot
|
||||
end
|
||||
subgraph Kusama Consensus
|
||||
kusama_bh(((Kusama Bridge Hub)))
|
||||
asset_hub_kusama(((Kusama Asset Hub)))
|
||||
kusama(((Kusama)))
|
||||
|
||||
kusama---asset_hub_kusama
|
||||
kusama---kusama_bh
|
||||
|
||||
kusama_bh-->|Send Message Using HRMP|asset_hub_kusama
|
||||
asset_hub_kusama-->|Dispatch the Message|asset_hub_kusama
|
||||
|
||||
asset_hub_kusama-->|Send Message Using HRMP|kusama_bh
|
||||
end
|
||||
|
||||
polkadot_bh<===>|Message is relayed to the Bridged Chain using lane 00000000|kusama_bh
|
||||
|
||||
linkStyle 2 stroke:red
|
||||
linkStyle 7 stroke:red
|
||||
linkStyle 8 stroke:red
|
||||
|
||||
linkStyle 3 stroke:green
|
||||
linkStyle 4 stroke:green
|
||||
linkStyle 9 stroke:green
|
||||
</div>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,343 @@
|
||||
# Running your own bridge relayer
|
||||
|
||||
:warning: :construction: Please read the [Disclaimer](#disclaimer) section first :construction: :warning:
|
||||
|
||||
## Disclaimer
|
||||
|
||||
There are several things you should know before running your own relayer:
|
||||
|
||||
- initial bridge version (we call it bridges v1) supports any number of relayers, but **there's no guaranteed
|
||||
compensation** for running a relayer and/or submitting valid bridge transactions. Most probably you'll end up
|
||||
spending more funds than getting from rewards - please accept this fact;
|
||||
|
||||
- even if your relayer has managed to submit a valid bridge transaction that has been included into the bridge
|
||||
hub block, there's no guarantee that you will be able to claim your compensation for that transaction. That's
|
||||
because compensations are paid from the account, controlled by relay chain governance and it could have no funds
|
||||
to compensate your useful actions. We'll be working on a proper process to resupply it on-time, but we can't
|
||||
provide any guarantee until that process is well established.
|
||||
|
||||
## A Brief Introduction into Relayers and our Compensations Scheme
|
||||
|
||||
Omitting details, relayer is an offchain process that is connected to both bridged chains. It looks at the
|
||||
outbound bridge messages queue and submits message delivery transactions to the target chain. There's a lot
|
||||
of details behind that simple phrase - you could find more info in the
|
||||
[High-Level Bridge Overview](./high-level-overview.md) document.
|
||||
|
||||
Reward that is paid to relayer has two parts. The first part static and is controlled by the governance.
|
||||
It is rather small initially - e.g. you need to deliver `10_000` Kusama -> Pezkuwi messages to gain single
|
||||
KSM token.
|
||||
|
||||
The other reward part is dynamic. So to deliver an XCM message from one BridgeHub to another, we'll need to
|
||||
submit two transactions on different chains. Every transaction has its cost, which is:
|
||||
|
||||
- dynamic, because e.g. message size can change and/or fee factor of the target chain may change;
|
||||
|
||||
- quite large, because those transactions are quite heavy (mostly in terms of size, not weight).
|
||||
|
||||
We are compensating the cost of **valid**, **minimal** and **useful** bridge-related transactions to
|
||||
relayer, that has submitted such transaction. Valid here means that the transaction doesn't fail. Minimal
|
||||
means that all data within transaction call is actually required for the transaction to succeed. Useful
|
||||
means that all supplied data in transaction is new and yet unknown to the target chain.
|
||||
|
||||
We have implemented a relayer that is able to craft such transactions. The rest of document contains a detailed
|
||||
information on how to deploy this software on your own node.
|
||||
|
||||
## Relayers Concurrency
|
||||
|
||||
As it has been said above, we are not compensating cost of transactions that are not **useful**. For
|
||||
example, if message `100` has already been delivered from Kusama Bridge Hub to Pezkuwi Bridge Hub, then another
|
||||
transaction that delivers the same message `100` won't be **useful**. Hence, no compensation to relayer that
|
||||
has submitted that second transaction.
|
||||
|
||||
But what if there are several relayers running? They are noticing the same queued message `100` and
|
||||
simultaneously submit identical message delivery transactions. You may expect that there'll be one lucky
|
||||
relayer, whose transaction would win the "race" and which will receive the compensation and reward. And
|
||||
there'll be several other relayers, losing some funds on their unuseful transactions.
|
||||
|
||||
But actually, we have a solution that invalidates transactions of "unlucky" relayers before they are
|
||||
included into the block. So at least you may be sure that you won't waste your funds on duplicate transactions.
|
||||
|
||||
<details>
|
||||
<summary>Some details?</summary>
|
||||
|
||||
All **unuseful** transactions are rejected by our
|
||||
[transaction extension](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/bridges/bin/runtime-common/src/refund_relayer_extension.rs),
|
||||
which also handles transaction fee compensations. You may find more info on unuseful (aka obsolete) transactions
|
||||
by lurking in the code.
|
||||
|
||||
We also have the WiP prototype of relayers coordination protocol, where relayers will get some guarantee
|
||||
that their transactions will be prioritized over other relayers transactions at their assigned slots.
|
||||
That is planned for the future version of bridge and the progress is
|
||||
[tracked here](https://github.com/paritytech/parity-bridges-common/issues/2486).
|
||||
|
||||
</details>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Let's focus on the bridge between Pezkuwi and Kusama Bridge Hubs. Let's also assume that we want to start
|
||||
a relayer that "serves" an initial lane [`0x00000001`](https://github.com/polkadot-fellows/runtimes/blob/9ce1bbbbcd7843b3c76ba4d43c036bc311959e9f/system-parachains/bridge-hubs/bridge-hub-kusama/src/bridge_to_polkadot_config.rs#L54).
|
||||
|
||||
<details>
|
||||
<summary>Lane?</summary>
|
||||
|
||||
Think of lane as a queue of messages that need to be delivered to the other/bridged chain. The lane is
|
||||
bidirectional, meaning that there are four "endpoints". Two "outbound" endpoints (one at every chain), contain
|
||||
messages that need to be delivered to the bridged chain. Two "inbound" are accepting messages from the bridged
|
||||
chain and also remember the relayer, who has delivered message(s) to reward it later.
|
||||
|
||||
</details>
|
||||
|
||||
The same steps may be performed for other lanes and bridges as well - you'll just need to change several parameters.
|
||||
|
||||
So to start your relayer instance, you'll need to prepare:
|
||||
|
||||
- an address of ws/wss RPC endpoint of the Kusama relay chain;
|
||||
|
||||
- an address of ws/wss RPC endpoint of the Pezkuwi relay chain;
|
||||
|
||||
- an address of ws/wss RPC endpoint of the Kusama Bridge Hub chain;
|
||||
|
||||
- an address of ws/wss RPC endpoint of the Pezkuwi Bridge Hub chain;
|
||||
|
||||
- an account on Kusama Bridge Hub;
|
||||
|
||||
- an account on Pezkuwi Bridge Hub.
|
||||
|
||||
For RPC endpoints, you could start your own nodes, or use some public community nodes. Nodes are not meant to be
|
||||
archive or provide access to insecure RPC calls.
|
||||
|
||||
To create an account on Bridge Hubs, you could use XCM teleport functionality. E.g. if you have an account on
|
||||
the relay chain, you could use the `teleportAssets` call of `xcmPallet` and send asset
|
||||
`V3 { id: Concrete(0, Here), Fungible: <your-amount> }` to beneficiary `V3(0, X1(AccountId32(<your-account>)))`
|
||||
on destination `V3(0, X1(Teyrchain(1002)))`. To estimate amounts you need, please refer to the [Costs](#costs)
|
||||
section of the document.
|
||||
|
||||
## Registering your Relayer Account (Optional, But Please Read)
|
||||
|
||||
Bridge transactions are quite heavy and expensive. We want to minimize block space that can be occupied by
|
||||
invalid bridge transactions and prioritize valid transactions over invalid. That is achieved by **optional**
|
||||
relayer registration. Transactions, signed by relayers with active registration, gain huge priority boost.
|
||||
In exchange, such relayers may be slashed if they submit **invalid** or **non-minimal** transaction.
|
||||
|
||||
Transactions, signed by relayers **without** active registration, on the other hand, receive no priority
|
||||
boost. It means that if there is active registered relayer, most likely all transactions from unregistered
|
||||
will be counted as **unuseful**, not included into the block and unregistered relayer won't get any reward
|
||||
for his operations.
|
||||
|
||||
Before registering, you should know several things about your funds:
|
||||
|
||||
- to register, you need to hold significant amount of funds on your relayer account. As of now, it is
|
||||
[100 KSM](https://github.com/polkadot-fellows/runtimes/blob/9ce1bbbbcd7843b3c76ba4d43c036bc311959e9f/system-parachains/bridge-hubs/bridge-hub-kusama/src/bridge_to_polkadot_config.rs#L71C14-L71C43)
|
||||
for registration on Kusama Bridge Hub and
|
||||
[500 HEZ](https://github.com/polkadot-fellows/runtimes/blob/9ce1bbbbcd7843b3c76ba4d43c036bc311959e9f/system-parachains/bridge-hubs/bridge-hub-polkadot/src/bridge_to_kusama_config.rs#L71C14-L71C43)
|
||||
for registration on Pezkuwi Bridge Hub;
|
||||
|
||||
- when you are registered, those funds are reserved on relayer account and you can't transfer them.
|
||||
|
||||
The registration itself, has three states: active, inactive or expired. Initially, it is active, meaning that all
|
||||
your transactions that are **validated** on top of block, where it is active get priority boost. Registration
|
||||
becomes expired when the block with the number you have specified during registration is "mined". It is the
|
||||
`validTill` parameter of the `register` call (see below). After that `validTill` block, you may unregister and get
|
||||
your reserved funds back. There's also an intermediate point between those blocks - it is the `validTill - LEASE`,
|
||||
where `LEASE` is the chain constant, controlled by the governance. Initially it is set to `300` blocks.
|
||||
All your transactions, **validated** between the `validTill - LEASE` and `validTill` blocks do not get the
|
||||
priority boost. Also, it is forbidden to specify `validTill` such that the `validTill - currentBlock` is less
|
||||
than the `LEASE`.
|
||||
|
||||
<details>
|
||||
<summary>Example?</summary>
|
||||
|
||||
| Bridge Hub Block | Registration State | Comment |
|
||||
| ----------------- | ------------------ | ------------------------------------------------------ |
|
||||
| 100 | Active | You have submitted a tx with the `register(1000)` call |
|
||||
| 101 | Active | Your message delivery transactions are boosted |
|
||||
| 102 | Active | Your message delivery transactions are boosted |
|
||||
| ... | Active | Your message delivery transactions are boosted |
|
||||
| 700 | Inactive | Your message delivery transactions are not boosted |
|
||||
| 701 | Inactive | Your message delivery transactions are not boosted |
|
||||
| ... | Inactive | Your message delivery transactions are not boosted |
|
||||
| 1000 | Expired | You may submit a tx with the `deregister` call |
|
||||
|
||||
</details>
|
||||
|
||||
So once you have enough funds on your account and have selected the `validTill` parameter value, you
|
||||
could use the Pezkuwi JS apps to submit an extrinsic. If you want priority boost for your transactions
|
||||
on the Kusama Bridge Hub, open the
|
||||
[Pezkuwi JS Apps](https://pezkuwichain.io/?rpc=wss%3A%2F%2Fkusama-bridge-hub-rpc.polkadot.io#/extrinsics)
|
||||
and submit the `register` extrinsic from the `bridgeRelayers` pallet:
|
||||
|
||||

|
||||
|
||||
To deregister, submit the simple `deregister` extrinsic when registration is expired:
|
||||
|
||||

|
||||
|
||||
At any time, you can prolong your registration by calling the `register` with the larger `validTill`.
|
||||
|
||||
## Costs
|
||||
|
||||
Your relayer account (on both Bridge Hubs) must hold enough funds to be able to pay costs of bridge
|
||||
transactions. If your relayer behaves correctly, those costs will be compensated and you will be
|
||||
able to claim it later.
|
||||
|
||||
**IMPORTANT**: you may add tip to your bridge transactions to boost their priority. But our
|
||||
compensation mechanism never refunds transaction tip, so all tip tokens will be lost.
|
||||
|
||||
<details>
|
||||
<summary>Types of bridge transactions</summary>
|
||||
|
||||
There are two types of bridge transactions:
|
||||
|
||||
- message delivery transaction brings queued message(s) from one Bridge Hub to another. We record
|
||||
the fact that this specific (your) relayer has delivered those messages;
|
||||
|
||||
- message confirmation transaction confirms that some message have been delivered and also brings
|
||||
back information on how many messages (your) relayer has delivered. We use this information later
|
||||
to register delivery rewards on the source chain.
|
||||
|
||||
Several messages/confirmations may be included in a single bridge transaction. Apart from this
|
||||
data, bridge transaction may include finality and storage proofs, required to prove authenticity of
|
||||
this data.
|
||||
|
||||
</details>
|
||||
|
||||
To deliver and get reward for a single message, the relayer needs to submit two transactions. One
|
||||
at the source Bridge Hub and one at the target Bridge Hub. Below are costs for Pezkuwi <> Kusama
|
||||
messages (as of today):
|
||||
|
||||
- to deliver a single Pezkuwi -> Kusama message, you would need to pay around `0.06 KSM` at Kusama
|
||||
Bridge Hub and around `1.62 HEZ` at Pezkuwi Bridge Hub;
|
||||
|
||||
- to deliver a single Kusama -> Pezkuwi message, you would need to pay around `1.70 HEZ` at Pezkuwi
|
||||
Bridge Hub and around `0.05 KSM` at Kusama Bridge Hub.
|
||||
|
||||
Those values are not constants - they depend on call weights (that may change from release to release),
|
||||
on transaction sizes (that depends on message size and chain state) and congestion factor. In any
|
||||
case - it is your duty to make sure that the relayer has enough funds to pay transaction fees.
|
||||
|
||||
## Claiming your Compensations and Rewards
|
||||
|
||||
Hopefully you have successfully delivered some messages and now can claim your compensation and reward.
|
||||
This requires submitting several transactions. But first, let's check that you actually have something to
|
||||
claim. For that, let's check the state of the pallet that tracks all rewards.
|
||||
|
||||
To check your rewards at the Kusama Bridge Hub, go to the
|
||||
[Pezkuwi JS Apps](https://pezkuwichain.io/?rpc=wss%3A%2F%2Fkusama-bridge-hub-rpc.polkadot.io#/chainstate)
|
||||
targeting Kusama Bridge Hub, select the `bridgeRelayers` pallet, choose `relayerRewards` map and
|
||||
your relayer account. Then:
|
||||
|
||||
- set the `laneId` to `0x00000001`
|
||||
|
||||
- set the `bridgedChainId` to `bhpd`;
|
||||
|
||||
- check both variants of the `owner` field: `ThisChain` is used to pay for message delivery transactions
|
||||
and `BridgedChain` is used to pay for message confirmation transactions.
|
||||
|
||||
If check shows that you have some rewards, you can craft the claim transaction, with similar parameters.
|
||||
For that, go to `Extrinsics` tab of the
|
||||
[Pezkuwi JS Apps](https://pezkuwichain.io/?rpc=wss%3A%2F%2Fkusama-bridge-hub-rpc.polkadot.io#/extrinsics)
|
||||
and submit the following transaction (make sure to change `owner` before):
|
||||
|
||||

|
||||
|
||||
To claim rewards on Pezkuwi Bridge Hub you can follow the same process. The only difference is that you
|
||||
need to set value of the `bridgedChainId` to `bhks`.
|
||||
|
||||
## Starting your Relayer
|
||||
|
||||
### Starting your Pezkuwichain <> Zagros Relayer
|
||||
|
||||
You may find the relayer image reference in the
|
||||
[Releases](https://github.com/paritytech/parity-bridges-common/releases)
|
||||
of this repository. Make sure to check supported (bundled) versions
|
||||
of release there. For Pezkuwichain <> Zagros bridge, normally you may use the
|
||||
latest published release. The release notes always contain the docker
|
||||
image reference and source files, required to build relayer manually.
|
||||
|
||||
Once you have the docker image, update variables and run the following script:
|
||||
```sh
|
||||
export DOCKER_IMAGE=<image-of-substrate-relay>
|
||||
|
||||
export PEZKUWICHAIN_HOST=<pezkuwichain-ws-rpc-host-here>
|
||||
export PEZKUWICHAIN_PORT=<pezkuwichain-ws-rpc-port-here>
|
||||
# or set it to '--pezkuwichain-secure' if wss is used above
|
||||
export PEZKUWICHAIN_IS_SECURE=
|
||||
export BRIDGE_HUB_PEZKUWICHAIN_HOST=<bridge-hub-pezkuwichain-ws-rpc-host-here>
|
||||
export BRIDGE_HUB_PEZKUWICHAIN_PORT=<bridge-hub-pezkuwichain-ws-rpc-port-here>
|
||||
# or set it to '--bridge-hub-pezkuwichain-secure' if wss is used above
|
||||
export BRIDGE_HUB_PEZKUWICHAIN_IS_SECURE=
|
||||
export BRIDGE_HUB_PEZKUWICHAIN_KEY_FILE=<absolute-path-to-file-with-account-key-at-bridge-hub-pezkuwichain>
|
||||
|
||||
export ZAGROS_HOST=<zagros-wss-rpc-host-here>
|
||||
export ZAGROS_PORT=<zagros-wss-rpc-port-here>
|
||||
# or set it to '--zagros-secure' if wss is used above
|
||||
export ZAGROS_IS_SECURE=
|
||||
export BRIDGE_HUB_ZAGROS_HOST=<bridge-hub-zagros-ws-rpc-host-here>
|
||||
export BRIDGE_HUB_ZAGROS_PORT=<bridge-hub-zagros-ws-rpc-port-here>
|
||||
# or set it to '--bridge-hub-zagros-secure ' if wss is used above
|
||||
export BRIDGE_HUB_ZAGROS_IS_SECURE=
|
||||
export BRIDGE_HUB_ZAGROS_KEY_FILE=<absolute-path-to-file-with-account-key-at-bridge-hub-zagros>
|
||||
|
||||
# you can get extended relay logs (e.g. for debugging issues) by passing `-e RUST_LOG=bridge=trace`
|
||||
# argument to the `docker` binary
|
||||
docker run \
|
||||
-v $BRIDGE_HUB_PEZKUWICHAIN_KEY_FILE:/bhr.key \
|
||||
-v $BRIDGE_HUB_ZAGROS_KEY_FILE:/bhw.key \
|
||||
$DOCKER_IMAGE \
|
||||
relay-headers-and-messages bridge-hub-pezkuwichain-bridge-hub-zagros \
|
||||
--pezkuwichain-host $PEZKUWICHAIN_HOST \
|
||||
--pezkuwichain-port $PEZKUWICHAIN_PORT \
|
||||
$PEZKUWICHAIN_IS_SECURE \
|
||||
--pezkuwichain-version-mode Auto \
|
||||
--bridge-hub-pezkuwichain-host $BRIDGE_HUB_PEZKUWICHAIN_HOST \
|
||||
--bridge-hub-pezkuwichain-port $BRIDGE_HUB_PEZKUWICHAIN_PORT \
|
||||
$BRIDGE_HUB_PEZKUWICHAIN_IS_SECURE \
|
||||
--bridge-hub-pezkuwichain-version-mode Auto \
|
||||
--bridge-hub-pezkuwichain-signer-file /bhr.key \
|
||||
--bridge-hub-pezkuwichain-transactions-mortality 16 \
|
||||
--zagros-host $ZAGROS_HOST \
|
||||
--zagros-port $ZAGROS_PORT \
|
||||
$ZAGROS_IS_SECURE \
|
||||
--zagros-version-mode Auto \
|
||||
--bridge-hub-zagros-host $BRIDGE_HUB_ZAGROS_HOST \
|
||||
--bridge-hub-zagros-port $BRIDGE_HUB_ZAGROS_PORT \
|
||||
$BRIDGE_HUB_ZAGROS_IS_SECURE \
|
||||
--bridge-hub-zagros-version-mode Auto \
|
||||
--bridge-hub-zagros-signer-file /bhw.key \
|
||||
--bridge-hub-zagros-transactions-mortality 16 \
|
||||
--lane 00000002
|
||||
```
|
||||
|
||||
### Starting your Pezkuwi <> Kusama Relayer
|
||||
|
||||
*Work in progress, coming soon*
|
||||
|
||||
### Watching your relayer state
|
||||
|
||||
Our relayer provides some Prometheus metrics that you may convert into some fancy Grafana dashboards
|
||||
and alerts. By default, metrics are exposed at port `9616`. To expose endpoint to the localhost, change
|
||||
the docker command by adding following two lines:
|
||||
|
||||
```sh
|
||||
docker run \
|
||||
..
|
||||
-p 127.0.0.1:9616:9616 \ # tell Docker to bind container port 9616 to host port 9616
|
||||
# and listen for connections on the host' localhost interface
|
||||
..
|
||||
$DOCKER_IMAGE \
|
||||
relay-headers-and-messages bridge-hub-pezkuwichain-bridge-hub-zagros \
|
||||
--prometheus-host 0.0.0.0 \ # tell `substrate-relay` binary to accept Prometheus endpoint
|
||||
# connections from everywhere
|
||||
..
|
||||
```
|
||||
|
||||
You can find more info on configuring Prometheus and Grafana in the
|
||||
[Monitor your node](https://docs.pezkuwichain.io/infrastructure/running-a-validator/operational-tasks/general-management/#monitor-your-node)
|
||||
guide from Pezkuwi wiki.
|
||||
|
||||
We have our own set of Grafana dashboards and alerts. You may use them for inspiration.
|
||||
Please find them in this folder:
|
||||
|
||||
- for Pezkuwichain <> Zagros bridge: [pezkuwichain-zagros](https://github.com/paritytech/parity-bridges-common/tree/master/deployments/bridges/rococo-westend).
|
||||
|
||||
- for Pezkuwi <> Kusama bridge: *work in progress, coming soon*
|
||||
@@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Parachains Finality Relay</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Parachains Finality Relay</h1>
|
||||
<p>
|
||||
Source Relay Chain is running GRANDPA Finality Gadget. Source Parachain is a parachain of the Source
|
||||
Relay Chain. Bridge GRANDPA finality pallet is deployed at Target Chain runtime and is "connected"
|
||||
to the Source Relay Chain. Bridge Parachains finality pallet is deployed at Target Chain and is
|
||||
configured to track the Source Parachain. GRANDPA Relayer is configured to relay Source Relay Chain
|
||||
finality to Target Chain. Parachains Relayer is configured to relay Source Parachain headers finality
|
||||
to Target Chain.
|
||||
</p>
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
participant Source Parachain
|
||||
participant Source Relay Chain
|
||||
participant GRANDPA Relayer
|
||||
participant Parachains Relayer
|
||||
participant Target Chain
|
||||
|
||||
Note left of Source Parachain: Best: 125
|
||||
Note left of Source Relay Chain: Finalized: 500, Best Parachain at Finalized: 120
|
||||
Note right of Target Chain: Best Relay: 480, Best Parachain: 110
|
||||
|
||||
Source Parachain ->> Source Parachain: Import Block 126
|
||||
Source Parachain ->> Source Relay Chain: Receives the Parachain block 126
|
||||
|
||||
Source Relay Chain ->> Source Relay Chain: Import block 501
|
||||
Source Relay Chain ->> Source Relay Chain: Finalize block 501
|
||||
Note left of Source Relay Chain: Finalized: 501, Best Parachain at Finalized: 126
|
||||
|
||||
Source Relay Chain ->> Parachains Relayer: notes new Source Parachain Block 126
|
||||
Note left of Parachains Relayer: can't relay Source Parachain Block 126, because it requires at least Source Relay Block 501 at Target Chain
|
||||
|
||||
Source Relay Chain ->> Source Relay Chain: Import block 502
|
||||
Source Relay Chain ->> Source Relay Chain: Finalize block 502
|
||||
|
||||
Source Relay Chain ->> GRANDPA Relayer: read GRANDPA Finality Proof of Block 502
|
||||
GRANDPA Relayer ->> Target Chain: submit GRANDPA Finality Proof of Block 502
|
||||
Note right of Target Chain: Best Relay: 502, Best Parachain: 110
|
||||
|
||||
Target Chain ->> Parachains Relayer: notes finalized Source Relay Block 502 at Target Chain
|
||||
Source Relay Chain ->> Parachains Relayer: read Parachain Finality Proof at Relay Block 502
|
||||
Parachains Relayer ->> Target Chain: submit Parachain Finality Proof at Relay Block 502
|
||||
Note right of Target Chain: Best Relay: 502, Best Parachain: 126
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.8.4/dist/mermaid.min.js"></script>
|
||||
<script>mermaid.initialize({startOnLoad: true})</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user