407bf44a8a add missing license header (#1204) 9babb19810 Custom relay strategy (#1198) c287872a11 fix clippy things (#1200) 3a40e62789 Expose some const value and type (#1186) 32b61476d1 increase sleep before connectingMillau (#1195) aabe7041fa revert messages transactions mortality (#1194) 3651f4f909 Message transactions mortality (#1191) 364d6e155d Bump dependencies (#1180) f0389acc08 cargo +nightly fmt --all (#1192) b270b6a016 Unify error enums in substrate and ethereum clients with `thiserror` (#1094) 58c4946f74 Limit max call size of Rialto/Millau runtimes (#1187) fd56a8cd56 Add UI to the deployment (#1047) 16f01dc736 Westend -> Millau alerts are pending before notifications are sent (#1184) 5628c11ece replace collective flip with babe randomness in Rialto (#1188) 1094a63b00 ignore another (pretty bad) RUSTSEC (#1185) 379fe323ea fix/ignore cargo deny issues (#1183) 92af5e6e64 additional log in finality relay + rephrase "failed" (#1182) b996a3b681 Rialto parachain in test deployments (#1178) 28d9332b44 Resubmit transactions strategy for Polkadot/Kusama (#1175) d0172c6847 Playing with CI (#1179) fb6f42456d fix checks order when registering parachain (#1177) ee828c005a Register-parachain subcommand of substrate-relay (#1170) 8cd2b1a112 Token swap pallet benchmarks (#1174) bb811accb1 fix collision with westend bridge (#1172) 8d2fba70ed add token swaps to test deployments (#1169) b6d1bdfe2c publish rialto parachain collator image (#1171) 834ae4a10a Fix OutboundLaneData types (#1159) 5ee0ea1626 copypasted -> copied (#1168) c3bb835f18 fix spelling (#1167) f90d041dc9 Upgrade `jsonrpsee` to v0.3 (#1051) 598c9b6d0d add some basic tests for swap tokens (#1164) 05e88c61f5 publish images when tag of specific format(e.g. v2021-09-27 + v2021-09-27-1) is published (#1166) 7f3f94a6e0 Fix CI again (#1165) ff37de332f Move calculation relayer reward into `MessageDeliveryAndDispatchPayment` (#1153) 36fbba839b fix clippy warning (#1163) 16da44d018 explicit wasm build (#1158) c9c8226449 Match substrate's fmt (#1148) 2fdd7f3e5e Fix/ignore clippy warnings (#1157) 43dfcc2686 Adding LookupAddress (#1156) 951eaa5582 Add rialto-parachain runtime and node (#1142) 803d266d61 Rename MessageId -> BridgeMessageId (#1152) 5f234484fc Box large arguments of GRANDPA pallet (#1154) cf9abc1011 Fix spelling (#1150) ab83ba2e58 Relay subcommand that performs token RLT <> MLAU token swap (#1141) 832536caf0 Polkadot <> Kusama relayers (#1122) 6d0daa8975 Add `OnMessageAccepted` callback (#1134) 5d03a20b3e Integrate token swap pallet into Millau runtime (#1099) ea4cfa833e Adding MultiAddress type and ValidationCodeHash (#1139) c20325a784 Add tests for `Raw` and `BridgeSendMessage` enum `Call` variants (#1125) 6d802416e2 increase pause before pining Rialto nodes (#1137) b54fa56b62 calculate fee using full message payload (#1132) ca5d8178f5 Add parachain pallets to rialto runtime (#1053) 9eaae4142e fix transaction resubmitter limits for Millau -> Rialto transactions (#1135) 9d4e17783c add --mandatory-headers-only cli option to complex relay (#1129) 1c5e0ec1cb Add local CI info to README (#1131) a8e0929e14 chore: spellchecker fixes (#1130) 3b8e2118e3 set fee for importing mandatory headers to zero (#1127) 49bba9aa52 another bunch of words for spellchecker (#1128) 8a72eafef6 Increase pause before messages generation start (#1126) 1f0ba9a191 Move some associated types from relay_substrate_client::Chain to bp_runtime::Chain (#1087) 74bc1a5b54 Transactions resubmitter (#1083) 21ba001f26 log max balance drop when sending message (#1117) 638a7ddffa Code Cleaning (#1124) be6555c51b Fix buildah logout (#1120) 87539c4a98 Format code work (#1116) 526fe7fdd7 fix spelling (#1119) bd4ce7f241 Fix spelling (#1118) 3c1147858e added missing constants to Kusama/Polkadot primitives (#1114) 52093b22ab Fix delivery transaction estimation used by rational relayer (#1109) 77a2f2fbed Remove fund account checks from upgrade. (#1111) 824334802b Rename param and update comment (#1108) d7784bfe06 Fix spellcheck (#1110) 0b18f5906a Refactor substrate messages source and substrate messages target (#1105) b27240bbff fix compilation (#1107) 9697da4fe8 Emit mortal transactions from relay (#1073) b29396c077 Change vault vars type to env vars (#1084) 35e0bbdc0c Make clippy mandatory. (#1103) a517e8541f Remove unused deps (#1102) 873dae608a Remove unnessary deps (#1101) 13450b74ee Stored conversion rate updater (#1005) 74389829f3 [BREAKING] Migrate messages pallet to frame v2 (#1088) 424da938dd README fix (#1100) 865744c909 upgrade currency exchange pallet to frame v2 (#1097) b5038148b3 Add missing docs (#1095) 0791e911c1 Common crate for substrate-relay (#1082) 3834c9d880 Update high-level-overview.md (#1093) c93553face Increase the time window for messaging alerts. (#1092) 8b9cc3cecd migrate pallet-shift-session-manager to frame v2 (#1090) dc91813c22 migrate eth PoA pallet to frame v2 (#1091) f16bb098cc Migrate dispatch pallet to frame v2 (#1089) 19f4325348 Bridge/This Chain Ids should be exposed as constants on pallet level. (#1085) 6381122df7 Change ChainSpec::from_genesis for Rialto and Millau chains to reflect the chain names. (#1079) 0f1d33e973 Make CI happy again (#1086) 238e65d96f fix typo (#1080) fc008457b6 Token-swap-over-bridge pallet (#944) 3fb97fa5ef Fix full spellcheck (#1076) eae4ed7170 fixed wrong trace (#1075) 219a0fad04 merge two weight-related loops in messages pallet (#1071) fc85632fdb increase_message_fee depends on stored mesage size (#1066) 530f37a23b companion for https://github.com/paritytech/polkadot/pull/3507 (#1067) 53b8cba683 sc_basic_authorship=trace for millau nodes (#1074) 9874e05e98 Improve traces of message generator scripts (#1069) 7b5ee84fbb extract message_details impl into runtime common (#1070) 5a4aed5a8b refund weight for mot pruning messages (#1062) 90e3d1e111 Fix Westend -> Millau sync (#1064) 427d30ddfc When restarting client, also "restart" tokio runtime (#1065) d47c05eeef Change get pipeline sensitive variables from Vault instead of GitLab settings (#1063) d775a85415 use tokio reactor to execute jsonrpsee futures (#1061) 15c8cd61cb Use BABE to author blocks on Rialto (previously: Aura) (#1050) 5186293500 Allow reading suri && password override from file (#1059) b506298262 Update jsonrpsee reference (#1049) 1734d00517 enable weight fee adjustent in Rialto/Millau (#1044) 607265afae Pay dispatch fee at target chain cli option (#1043) ce79ef91be bump dependencies before start referencing polkadot repo (#1048) 924fa24f6d Cli option for greedy relayer + run no-losses relayer by default (#1042) e21eba7b59 Yrong README Fixup + M1 Fixes (#1045) 20d08204a2 Confirm delivery detects when more than expected messages are confirmed (#1039) 994b846b52 pre and post dispatch weights of OnDeliveryConfirmed callback (#1040) 1dd5297e84 give real value to Rialto and Millau tokens (#1038) 035bee8715 Use real conversion rate in greedy relayer strategy (#1035) 9cfaecd0f7 fixed metrics prefix (#1037) 1d8d224937 Use kebab-case for bridge arguments (#1036) f30a4c79a6 Shared reference to conversion rate metric value (#1034) c34d7a5cbb estimate transaction fee (#1015) 93404b18bb change alert period from 2m to 10m for Westend -> Millau (GRANDPA or public node itself is lagging sometimes) (#1032) git-subtree-dir: bridges git-subtree-split: 407bf44a8a5f4e60aceef2dc755cd9ff09929ac3
11 KiB
Helpers for Messages Module Integration
The messages 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, Substrate bridge module and the call dispatch module;
- 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;
- the messages are
bp_message_dispatch::MessagePayloadstructures, wherecallfield is encodedCallof the target chain. This means that theCallis opaque to the messages module instance at the source chain. It is pre-encoded by the message submitter; - all proofs in the messages module transactions are
based on the storage proofs from the bridged chain: storage proof of the outbound message (value
from the
pallet_bridge_messages::Store::MessagePayloadmap), storage proof of the outbound lane state (value from thepallet_bridge_messages::Store::OutboundLanesmap) and storage proof of the inbound lane state (value from thepallet_bridge_messages::Store::InboundLanesmap); - 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 and/or millau_messages.rs) to see how to use these helpers.
Contents
MessageBridgeTraitChainWithMessagesTrait- Helpers for the Source 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.
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_outbound_lane_enabled: is used to check whether given lane accepts outbound messages. -
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 ofinclude_pay_dispatch_fee_costargument. -
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 theThisChainWithMessages::transaction_paymentimplementation. 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 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:
-
it'll verify that the used outbound lane is enabled in our runtime;
-
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;
-
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::SourceRootorigin. Or he has provided wrong signature in thebp_message_dispatch::CallOrigin::TargetAccountorigin; -
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_feefunction.
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:
-
that the message size is less than or equal to the
2/3of maximal extrinsic size at the target chain. We leave1/3for signed extras and for the storage proof overhead; -
that the message dispatch weight is less than or equal to the
1/2of maximal normal extrinsic weight at the target chain. We leave1/2for the delivery transaction overhead.
Helpers for the Target Chain
The helpers for the target chain reside in the target submodule of the
messages 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. 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
for details). This proof is verified by the verify_messages_proof function.