Files
pezkuwi-subxt/polkadot/bridges/bin/runtime-common/README.md
T
Svyatoslav Nikolsky 8e01ba9c03 Update bridges subtree (#5165)
* Squashed 'bridges/' changes from 1602249f0a..f220d2fcca

f220d2fcca Polkadot staging update (#1356)
02fd3d497c fix parse_transaction on Rialto+Millau (#1360)
bc191fd9a2 update parity-scale-codec to 3.1.2 (#1359)
a37226e79c update chain versions (#1358)
ff5d539fcb Update Substrate/Polkadot/Cumulus references (#1353)
1581f60cd5 Support dedicated lanes for pallets (#962)
0a7ccf5c57 ignore more "increase" alerts that are sometimes signalling NoData at startup (#1351)
31165127cc added no_stack_overflow_when_decoding_nested_call_during_dispatch test (#1349)
7000619eb8 replace From<>InboundLaneApi with direct storage reads (#1348)
515df10ccc added alerts for relay balances (#1347)
b56f6a87de Mortal conversion rate updater transactions (#1257)
20f2f331ec edition = "2021" (#1346)
99147d4f75 update regex to 1.5.5 (#1345)
686191f379 use DecodeLimit when decoding incoming calls (#1344)
a70c276006 get rid of '[No Data] Messages from Millau to Rialto are not being delivered' warnings (#1342)
01f29b8ac1 fix conversion rate metric in dashboards (#1341)
51c3bf351f Increase rate from metric when estimating fee (#1340)
3bb9c4f68f fix generator scripts to be consistent with updatedrelay output (#1339)
0475a1667b fixed mess with conversion rates (#1338)
d8fdd7d716 synchronize relay cli changes and token swap generator script (#1337)
6e928137a5 fix conversion rate override in token swap (#1336)
62d4a4811d override conversion rate in tokens swap generator (#1335)
ed9e1c839c fi typo in generator script (#1334)
3254b5af7a Override conversion rate when computing message fee (#1261)
66df68b5b8 Revert "Revert "override conversion rate in estimate-message-fee RPC (#1189)" (#1275)" (#1333)
0ca6fc6ef8 fix clippy issues (#1332)
5414b2fffb Reinitialize bridge relay subcommand (#1331)
a63d95ba7d removed extra *_RUNTIME_VERSION consts from relay code (#1330)
59fb18a310 fix typo in alert expression (#1329)
a6267a47ee Using-same-fork metric for finality and complex relay (#1327)
88d684d37e use mortal transactions in transaction resubmitter (#1326)
8ff88b6844 impl Decode for SignedExtensions (otherwise transaction resubmitter panicks) (#1325)
1ed09854f0 Encode and estimate Rococo/Wococo/Kusama/Polkadot messages (#1322)
ddb4517e13 Add some tests to check integrity of chain constants + bridge configuration (#1316)
bdeedb7ab9 Fix issues from cargo deny (#1311)
d3d79d01e0 expose fee multiplier metrics in messages relay (#1312)
c8b3f0ea16 Endow relayer account at target chain in message benchmarks (#1310)
f51ecd92b6 fix benchmarks before using it in Polkadot/Kusama/Rococo runtimes (#1309)
6935c619ad increase relay balance guard limits for Polkadot<>Kusama bridge (#1308)
7e31834c66 Fix mandatory headers scanning in on-demand relay (#1306)
92ddc3ea7a Polkadot-staging update (#1305)
3787193a31 fix session length of Rococo and Wococo (#1304)
eb468d29c0 Revert nightly docker pin (#1301)
e2d4c073e1 Use raw balance value if tokenDecimals property is missing (#1299)
108f4b29d1 Fix ss58 prefixes of Polkadot, Kusama and Westend used by relay (#1298)
64fbd2705e bump chain spec versions (#1297)
5707777b86 Bump Substrate/Polkadot/Cumulus refs (#1295)
29eecdf1fa Merge pull request #1294 from paritytech/polkadot-staging-update
1f0c05368e Relay balance metrics (#1291)
6356bb90b3 when messages pallet is halted, relay shall not submit messages delivery/confirmation transactions (#1289)
800dc2df8d when GRANDPA pallet is halted, relay shall not submit finality transactions (#1288)
3dd8e4f936 disable BEEFY allerts for Rialto (#1285)
f58fed7380 support version mode cli options in send-message subcommand (#1284)
3aac448da3 reuse polkadot-service code (#1273)
2bdbb651e1 replace latest_confirmed_nonce runtime APIs with direct storage reads (#1282)
5f9c6d241f move "common" code of messages pallet benchmarks helpers to the common library (#1281)
173d2d8229 Merge pull request #1280 from paritytech/polkadot-staging-update
8b9c4ec16d do not start spec_version guard when version mode is set to auto (#1278)
e98d682de2 removed extra messages benchmarks (#1279)
c730e25b61 Move benchmarks from Rialto to Millau (#1277)
54146416e7 Merge pull request #1276 from paritytech/polkadot-staging-update
df70118174 Merge branch 'master' into polkadot-staging-update
ed7def64c4 Revert "override conversion rate in estimate-message-fee RPC (#1189)" (#1275)
38c6c3a49f Use "production" floating tag when uilding docker image from version git tags (#1272)
ded9ff6dbb Replace InboundLaneApi::latest_received_nonce with direct storage read (#1269)
f704a741ee Polkadot staging update (#1270)
8c65f0d7ab verify that GRANDPA pallet is not initialized before submitting initialization transaction (#1267)
e7e83d8944 remove OutboundLaneApi::latest_received_nonce (#1262)
9f4b34acf1 bump rococo version (#1263)
82c08c5a87 read latest_generated_nonce directly from storage (#1260)
50ffb5dd08 override conversion rate in estimate-message-fee RPC (#1189)
467ca5ef59 move storage keys computation to primitivs (#1254)
4f9884066b remporary use pinned bridges-ci image in Dockerfile (#1258)
edfcb74e00 Change submit transaction spec_version and transaction_version query from chain (#1248)
4009d970d0 pin bridges-ci image (#1256)
65e51b5e1c decrease startup sleep to 5s for relays and to 120s for generators + remove curl (#1251)
3bc74355d9 Add missing RPC APIs to rialto parachain node (#1250)
80c9429284 Bump relay version to 1.0.0 (#1249)
9ead06af2a runtimes: fix call_size() test (#1245)
4fc8a29357 Use same endowed accounts set on dev/local chains (#1244)
fed54371c2 Refactor message relay helpers (#1234)
a15b4faae7 post-merge build fix (#1243)
52232d8d54 Fix transactions mortality (#1196)
c07bba931f Expose prometheus BEEFY metrics and add them to grafana dashboard (#1242)
f927775bd5 Refactor finality relay helpers (#1220)
7bf76f14a8 Update Rococo/Wococo version + prepare relay for Rococo<>Wococo bridge (#1241)
e860fecd04 Enable offchain indexing for Rialto/Millau nodes (#1239)
04d4d1c6b4 Enable Beefy debug logs in test deployment (#1237)
cd771f1089 Fix storage parameter name computation (#1238)
816ddd2dd2 Integrate BEEFY with Rialto & Millau runtimes (#1227)
d94b62b1ac update dependencies (#1229)
98eb9ee13d Add mut support (#1232)
ffef6f89f9 fixed set_operational in GRANDPA pallet (#1226)
bd2f8bfbd7 Add CODEOWNERS file (#1219)
6b5cf2b591 Unify metric names (#1209)
d1541e797e remove abandoned exchange relay (#1217)
39140d0b34 Remove unused `relays/headers` (#1216)
9bc071d42b Remove unused PoA<>Substrate bridge (#1210)
877e8d01e3 Fix UI deployment. (#1211)
6cd5775ebe Add `AtLeast32BitUnsigned` for MessageLance::SourceChainBalance (#1207)

git-subtree-dir: bridges
git-subtree-split: f220d2fccabbf141101d19456ecb4e3576a1d797

* fix compilation warnings
2022-03-21 10:19:29 +00:00

182 lines
12 KiB
Markdown

# Helpers for Messages Module Integration
The [`messages`](./src/messages.rs) module of this crate contains a bunch of helpers for integrating
messages module into your runtime. Basic prerequisites of these helpers are:
- we're going to bridge Substrate-based chain with another Substrate-based chain;
- both chains have [messages module](../../modules/messages/README.md), Substrate bridge
module and the [call dispatch module](../../modules/dispatch/README.md);
- all message lanes are identical and may be used to transfer the same messages;
- the messages sent over the bridge are dispatched using
[call dispatch module](../../modules/dispatch/README.md);
- the messages are `bp_message_dispatch::MessagePayload` structures, where `call` field is
encoded `Call` of the target chain. This means that the `Call` is opaque to the
[messages module](../../modules/messages/README.md) instance at the source chain.
It is pre-encoded by the message submitter;
- all proofs in the [messages module](../../modules/messages/README.md) transactions are
based on the storage proofs from the bridged chain: storage proof of the outbound message (value
from the `pallet_bridge_messages::Store::MessagePayload` map), storage proof of the outbound lane
state (value from the `pallet_bridge_messages::Store::OutboundLanes` map) and storage proof of the
inbound lane state (value from the `pallet_bridge_messages::Store::InboundLanes` map);
- storage proofs are built at the finalized headers of the corresponding chain. So all message lane
transactions with proofs are verifying storage proofs against finalized chain headers from
Substrate bridge module.
**IMPORTANT NOTE**: after reading this document, you may refer to our test runtimes
([rialto_messages.rs](../millau/runtime/src/rialto_messages.rs) and/or
[millau_messages.rs](../rialto/runtime/src/millau_messages.rs)) to see how to use these helpers.
## Contents
- [`MessageBridge` Trait](#messagebridge-trait)
- [`ChainWithMessages` Trait ](#ChainWithMessages-trait)
- [Helpers for the Source Chain](#helpers-for-the-source-chain)
- [Helpers for the Target Chain](#helpers-for-the-target-chain)
## `MessageBridge` Trait
The essence of your integration will be a struct that implements a `MessageBridge` trait. It has
single method (`MessageBridge::bridged_balance_to_this_balance`), used to convert from bridged chain
tokens into this chain tokens. The bridge also requires two associated types to be specified -
`ThisChain` and `BridgedChain`.
Worth to say that if you're going to use hardcoded constant (conversion rate) in the
`MessageBridge::bridged_balance_to_this_balance` method (or in any other method of
`ThisChainWithMessages` or `BridgedChainWithMessages` traits), then you should take a
look at the
[messages parameters functionality](../../modules/messages/README.md#Non-Essential-Functionality).
They allow pallet owner to update constants more frequently than runtime upgrade happens.
## `ChainWithMessages` Trait
The trait is quite simple and can easily be implemented - you just need to specify types used at the
corresponding chain. There is single exception, though (it may be changed in the future):
- `ChainWithMessages::MessagesInstance`: this is used to compute runtime storage keys. There
may be several instances of messages pallet, included in the Runtime. Every instance stores
messages and these messages stored under different keys. When we are verifying storage proofs from
the bridged chain, we should know which instance we're talking to. This is fine, but there's
significant inconvenience with that - this chain runtime must have the same messages pallet
instance. This does not necessarily mean that we should use the same instance on both chains -
this instance may be used to bridge with another chain/instance, or may not be used at all.
## `ThisChainWithMessages` Trait
This trait represents this chain from bridge point of view. Let's review every method of this trait:
- `ThisChainWithMessages::is_message_accepted`: is used to check whether given lane accepts
messages. The send-message origin is passed to the function, so you may e.g. verify that only
given pallet is able to send messages over selected lane. **IMPORTANT**: if you assume that the
message must be paid by the sender, you must ensure that the sender origin has linked the account
for paying message delivery and dispatch fee.
- `ThisChainWithMessages::maximal_pending_messages_at_outbound_lane`: you should return maximal
number of pending (undelivered) messages from this function. Returning small values would require
relayers to operate faster and could make message sending logic more complicated. On the other
hand, returning large values could lead to chain state growth.
- `ThisChainWithMessages::estimate_delivery_confirmation_transaction`: you'll need to return
estimated size and dispatch weight of the delivery confirmation transaction (that happens on
this chain) from this function.
- `ThisChainWithMessages::transaction_payment`: you'll need to return fee that the submitter
must pay for given transaction on this chain. Normally, you would use transaction payment pallet
for this. However, if your chain has non-zero fee multiplier set, this would mean that the
payment will be computed using current value of this multiplier. But since this transaction
will be submitted in the future, you may want to choose other value instead. Otherwise,
non-altruistic relayer may choose not to submit this transaction until number of transactions
will decrease.
## `BridgedChainWithMessages` Trait
This trait represents this chain from bridge point of view. Let's review every method of this trait:
- `BridgedChainWithMessages::maximal_extrinsic_size`: you will need to return the maximal
extrinsic size of the target chain from this function.
- `MessageBridge::message_weight_limits`: you'll need to return a range of
dispatch weights that the outbound message may take at the target chain. Please keep in mind that
our helpers assume that the message is an encoded call of the target chain. But we never decode
this call at the source chain. So you can't simply get dispatch weight from pre-dispatch
information. Instead there are two options to prepare this range: if you know which calls are to
be sent over your bridge, then you may just return weight ranges for these particular calls.
Otherwise, if you're going to accept all kinds of calls, you may just return range `[0; maximal
incoming message dispatch weight]`. If you choose the latter, then you shall remember that the
delivery transaction itself has some weight, so you can't accept messages with weight equal to
maximal weight of extrinsic at the target chain. In our test chains, we reject all messages that
have declared dispatch weight larger than 50% of the maximal bridged extrinsic weight.
- `MessageBridge::estimate_delivery_transaction`: you will need to return estimated dispatch weight and
size of the delivery transaction that delivers a given message to the target chain. The transaction
weight must or must not include the weight of pay-dispatch-fee operation, depending on the value
of `include_pay_dispatch_fee_cost` argument.
- `MessageBridge::transaction_payment`: you'll need to return fee that the submitter
must pay for given transaction on bridged chain. The best case is when you have the same conversion
formula on both chains - then you may just reuse the `ThisChainWithMessages::transaction_payment`
implementation. Otherwise, you'll need to hardcode this formula into your runtime.
## Helpers for the Source Chain
The helpers for the Source Chain reside in the `source` submodule of the
[`messages`](./src/messages.rs) module. The structs are: `FromThisChainMessagePayload`,
`FromBridgedChainMessagesDeliveryProof`, `FromThisChainMessageVerifier`. And the helper functions
are: `maximal_message_size`, `verify_chain_message`, `verify_messages_delivery_proof` and
`estimate_message_dispatch_and_delivery_fee`.
`FromThisChainMessagePayload` is a message that the sender sends through our bridge. It is the
`bp_message_dispatch::MessagePayload`, where `call` field is encoded target chain call. So
at this chain we don't see internals of this call - we just know its size.
`FromThisChainMessageVerifier` is an implementation of `bp_messages::LaneMessageVerifier`. It
has following checks in its `verify_message` method:
1. it'll verify that the used outbound lane is enabled in our runtime;
1. it'll reject messages if there are too many undelivered outbound messages at this lane. The
sender need to wait while relayers will do their work before sending the message again;
1. it'll reject a message if it has the wrong dispatch origin declared. Like if the submitter is not
the root of this chain, but it tries to dispatch the message at the target chain using
`bp_message_dispatch::CallOrigin::SourceRoot` origin. Or he has provided wrong signature
in the `bp_message_dispatch::CallOrigin::TargetAccount` origin;
1. it'll reject a message if the delivery and dispatch fee that the submitter wants to pay is lesser
than the fee that is computed using the `estimate_message_dispatch_and_delivery_fee` function.
`estimate_message_dispatch_and_delivery_fee` returns a minimal fee that the submitter needs to pay
for sending a given message. The fee includes: payment for the delivery transaction at the target
chain, payment for delivery confirmation transaction on this chain, payment for `Call` dispatch at
the target chain and relayer interest.
`FromBridgedChainMessagesDeliveryProof` holds the lane identifier and the storage proof of this
inbound lane state at the bridged chain. This also holds the hash of the target chain header, that
was used to generate this storage proof. The proof is verified by the
`verify_messages_delivery_proof`, which simply checks that the target chain header is finalized
(using Substrate bridge module) and then reads the inbound lane state from the proof.
`verify_chain_message` function checks that the message may be delivered to the bridged chain. There
are two main checks:
1. that the message size is less than or equal to the `2/3` of maximal extrinsic size at the target
chain. We leave `1/3` for signed extras and for the storage proof overhead;
1. that the message dispatch weight is less than or equal to the `1/2` of maximal normal extrinsic
weight at the target chain. We leave `1/2` for the delivery transaction overhead.
## Helpers for the Target Chain
The helpers for the target chain reside in the `target` submodule of the
[`messages`](./src/messages.rs) module. The structs are: `FromBridgedChainMessagePayload`,
`FromBridgedChainMessagesProof`, `FromBridgedChainMessagesProof`. And the helper functions are:
`maximal_incoming_message_dispatch_weight`, `maximal_incoming_message_size` and
`verify_messages_proof`.
`FromBridgedChainMessagePayload` corresponds to the `FromThisChainMessagePayload` at the bridged
chain. We expect that messages with this payload are stored in the `OutboundMessages` storage map of
the [messages module](../../modules/messages/README.md). This map is used to build
`FromBridgedChainMessagesProof`. The proof holds the lane id, range of message nonces included in
the proof, storage proof of `OutboundMessages` entries and the hash of bridged chain header that has
been used to build the proof. Additionally, there's storage proof may contain the proof of outbound
lane state. It may be required to prune `relayers` entries at this chain (see
[messages module documentation](../../modules/messages/README.md#What-about-other-Constants-in-the-Messages-Module-Configuration-Trait)
for details). This proof is verified by the `verify_messages_proof` function.