From 82e1083539cfe5358148e189d054d934c4b0427b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 20 Jan 2023 11:39:36 +0300 Subject: [PATCH] Remove chain-specific dependencies from crates that will be used in Cumulus (#1783) * leave-modules.sh * remove bp-rialto dependency from bp-relayers * update leave-modules.sh * fix Cargo.toml of pallet-bridge-relayers * update leave-modules.sh * remove bp-rialto and millau-runtime frombridge-runtime-common Cargo.toml * update leave-modules.sh * remove chain dependencies from bridge-runtime-common crate * fix tests * cleanup script * rename script * kind of success message * remove leave-modules.sh * use TargetHeaderChainAdapter and SourceHeaderChainAdapter in our testnets * update script --- bin/millau/runtime/src/lib.rs | 8 +- bin/millau/runtime/src/rialto_messages.rs | 51 +-- .../runtime/src/rialto_parachain_messages.rs | 64 +-- bin/rialto-parachain/runtime/src/lib.rs | 4 +- .../runtime/src/millau_messages.rs | 51 +-- bin/rialto/runtime/src/lib.rs | 4 +- bin/rialto/runtime/src/millau_messages.rs | 51 +-- bin/runtime-common/Cargo.toml | 5 +- bin/runtime-common/src/integrity.rs | 8 +- bin/runtime-common/src/lib.rs | 1 + bin/runtime-common/src/messages.rs | 305 ++++--------- .../src/messages_benchmarking.rs | 1 - bin/runtime-common/src/messages_extension.rs | 54 ++- bin/runtime-common/src/mock.rs | 422 ++++++++++++++++++ .../src/refund_relayer_extension.rs | 95 ++-- modules/relayers/Cargo.toml | 1 + primitives/messages/src/target_chain.rs | 18 +- primitives/relayers/Cargo.toml | 1 - primitives/relayers/src/lib.rs | 17 +- relays/bin-substrate/src/chains/mod.rs | 6 +- 20 files changed, 660 insertions(+), 507 deletions(-) create mode 100644 bin/runtime-common/src/mock.rs diff --git a/bin/millau/runtime/src/lib.rs b/bin/millau/runtime/src/lib.rs index 6c401b9a94bd..5aba458216d2 100644 --- a/bin/millau/runtime/src/lib.rs +++ b/bin/millau/runtime/src/lib.rs @@ -473,7 +473,7 @@ impl pallet_bridge_messages::Config for Runtime { type InboundRelayer = bp_rialto::AccountId; type DeliveryPayments = (); - type TargetHeaderChain = crate::rialto_messages::Rialto; + type TargetHeaderChain = crate::rialto_messages::RialtoAsTargetHeaderChain; type LaneMessageVerifier = crate::rialto_messages::ToRialtoMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, @@ -481,7 +481,7 @@ impl pallet_bridge_messages::Config for Runtime { frame_support::traits::ConstU64<10_000>, >; - type SourceHeaderChain = crate::rialto_messages::Rialto; + type SourceHeaderChain = crate::rialto_messages::RialtoAsSourceHeaderChain; type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch; type BridgedChainId = RialtoChainId; } @@ -504,7 +504,7 @@ impl pallet_bridge_messages::Config for Run type InboundRelayer = bp_rialto_parachain::AccountId; type DeliveryPayments = (); - type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachain; + type TargetHeaderChain = crate::rialto_parachain_messages::RialtoParachainAsTargetHeaderChain; type LaneMessageVerifier = crate::rialto_parachain_messages::ToRialtoParachainMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, @@ -512,7 +512,7 @@ impl pallet_bridge_messages::Config for Run frame_support::traits::ConstU64<10_000>, >; - type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachain; + type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachainAsSourceHeaderChain; type MessageDispatch = crate::rialto_parachain_messages::FromRialtoParachainMessageDispatch; type BridgedChainId = RialtoParachainChainId; } diff --git a/bin/millau/runtime/src/rialto_messages.rs b/bin/millau/runtime/src/rialto_messages.rs index ac203a2f6dde..1bc361d58823 100644 --- a/bin/millau/runtime/src/rialto_messages.rs +++ b/bin/millau/runtime/src/rialto_messages.rs @@ -18,13 +18,11 @@ use crate::{RialtoGrandpaInstance, Runtime, RuntimeCall, RuntimeOrigin}; -use bp_messages::{ - source_chain::TargetHeaderChain, - target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, -}; +use bp_messages::{LaneId, MessageNonce}; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; -use bridge_runtime_common::messages::{self, MessageBridge}; +use bridge_runtime_common::messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +}; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Default lane that is used to send messages to Rialto. @@ -110,6 +108,10 @@ impl messages::ThisChainWithMessages for Millau { /// Rialto chain from message lane point of view. #[derive(RuntimeDebug, Clone, Copy)] pub struct Rialto; +/// Rialto as source header chain. +pub type RialtoAsSourceHeaderChain = SourceHeaderChainAdapter; +/// Rialto as target header chain. +pub type RialtoAsTargetHeaderChain = TargetHeaderChainAdapter; impl messages::UnderlyingChainProvider for Rialto { type Chain = bp_rialto::Rialto; @@ -121,43 +123,6 @@ impl messages::BridgedChainWithMessages for Rialto { } } -impl TargetHeaderChain for Rialto { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof or one or several keys; - // - id of the lane we prove state of. - type MessagesDeliveryProof = ToRialtoMessagesDeliveryProof; - - fn verify_message(payload: &ToRialtoMessagePayload) -> Result<(), Self::Error> { - messages::source::verify_chain_message::(payload) - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData), Self::Error> { - messages::source::verify_messages_delivery_proof::(proof) - } -} - -impl SourceHeaderChain for Rialto { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof or one or several keys; - // - id of the lane we prove messages for; - // - inclusive range of messages nonces that are proved. - type MessagesProof = FromRialtoMessagesProof; - - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result, Self::Error> { - messages::target::verify_messages_proof::(proof, messages_count) - .map_err(Into::into) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/bin/millau/runtime/src/rialto_parachain_messages.rs b/bin/millau/runtime/src/rialto_parachain_messages.rs index 097e2798227c..d19e41364083 100644 --- a/bin/millau/runtime/src/rialto_parachain_messages.rs +++ b/bin/millau/runtime/src/rialto_parachain_messages.rs @@ -18,13 +18,11 @@ use crate::{Runtime, RuntimeCall, RuntimeOrigin, WithRialtoParachainsInstance}; -use bp_messages::{ - source_chain::TargetHeaderChain, - target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, -}; +use bp_messages::{LaneId, MessageNonce}; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_PARACHAIN_CHAIN_ID}; -use bridge_runtime_common::messages::{self, MessageBridge}; +use bridge_runtime_common::messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +}; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Default lane that is used to send messages to Rialto parachain. @@ -53,14 +51,6 @@ pub type ToRialtoParachainMessageVerifier = pub type FromRialtoParachainMessagePayload = messages::target::FromBridgedChainMessagePayload; -/// Messages proof for RialtoParachain -> Millau messages. -type FromRialtoParachainMessagesProof = - messages::target::FromBridgedChainMessagesProof; - -/// Messages delivery proof for Millau -> RialtoParachain messages. -type ToRialtoParachainMessagesDeliveryProof = - messages::source::FromBridgedChainMessagesDeliveryProof; - /// Call-dispatch based message dispatch for RialtoParachain -> Millau messages. pub type FromRialtoParachainMessageDispatch = messages::target::FromBridgedChainMessageDispatch< WithRialtoParachainMessageBridge, @@ -115,6 +105,12 @@ impl messages::ThisChainWithMessages for Millau { /// RialtoParachain chain from message lane point of view. #[derive(RuntimeDebug, Clone, Copy)] pub struct RialtoParachain; +/// RialtoParachain as source header chain. +pub type RialtoParachainAsSourceHeaderChain = + SourceHeaderChainAdapter; +/// RialtoParachain as target header chain. +pub type RialtoParachainAsTargetHeaderChain = + TargetHeaderChainAdapter; impl messages::UnderlyingChainProvider for RialtoParachain { type Chain = bp_rialto_parachain::RialtoParachain; @@ -125,43 +121,3 @@ impl messages::BridgedChainWithMessages for RialtoParachain { true } } - -impl TargetHeaderChain for RialtoParachain { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof or one or several keys; - // - id of the lane we prove state of. - type MessagesDeliveryProof = ToRialtoParachainMessagesDeliveryProof; - - fn verify_message(payload: &ToRialtoParachainMessagePayload) -> Result<(), Self::Error> { - messages::source::verify_chain_message::(payload) - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData), Self::Error> { - messages::source::verify_messages_delivery_proof::(proof) - } -} - -impl SourceHeaderChain for RialtoParachain { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof or one or several keys; - // - id of the lane we prove messages for; - // - inclusive range of messages nonces that are proved. - type MessagesProof = FromRialtoParachainMessagesProof; - - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result, Self::Error> { - messages::target::verify_messages_proof::( - proof, - messages_count, - ) - .map_err(Into::into) - } -} diff --git a/bin/rialto-parachain/runtime/src/lib.rs b/bin/rialto-parachain/runtime/src/lib.rs index 5ad8506acbf3..2bc787c49535 100644 --- a/bin/rialto-parachain/runtime/src/lib.rs +++ b/bin/rialto-parachain/runtime/src/lib.rs @@ -581,7 +581,7 @@ impl pallet_bridge_messages::Config for Runtime { type InboundRelayer = bp_millau::AccountId; type DeliveryPayments = (); - type TargetHeaderChain = crate::millau_messages::Millau; + type TargetHeaderChain = crate::millau_messages::MillauAsTargetHeaderChain; type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, @@ -589,7 +589,7 @@ impl pallet_bridge_messages::Config for Runtime { frame_support::traits::ConstU128<100_000>, >; - type SourceHeaderChain = crate::millau_messages::Millau; + type SourceHeaderChain = crate::millau_messages::MillauAsSourceHeaderChain; type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch; type BridgedChainId = BridgedChainId; } diff --git a/bin/rialto-parachain/runtime/src/millau_messages.rs b/bin/rialto-parachain/runtime/src/millau_messages.rs index e21cf76a82c8..850ec1da60db 100644 --- a/bin/rialto-parachain/runtime/src/millau_messages.rs +++ b/bin/rialto-parachain/runtime/src/millau_messages.rs @@ -21,13 +21,11 @@ use crate::{MillauGrandpaInstance, Runtime, RuntimeCall, RuntimeOrigin}; -use bp_messages::{ - source_chain::TargetHeaderChain, - target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, -}; +use bp_messages::{LaneId, MessageNonce}; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_PARACHAIN_CHAIN_ID}; -use bridge_runtime_common::messages::{self, MessageBridge}; +use bridge_runtime_common::messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +}; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Default lane that is used to send messages to Millau. @@ -114,6 +112,10 @@ impl messages::ThisChainWithMessages for RialtoParachain { /// Millau chain from message lane point of view. #[derive(RuntimeDebug, Clone, Copy)] pub struct Millau; +/// Millau as source header chain. +pub type MillauAsSourceHeaderChain = SourceHeaderChainAdapter; +/// Millau as target header chain. +pub type MillauAsTargetHeaderChain = TargetHeaderChainAdapter; impl messages::UnderlyingChainProvider for Millau { type Chain = bp_millau::Millau; @@ -124,40 +126,3 @@ impl messages::BridgedChainWithMessages for Millau { true } } - -impl TargetHeaderChain for Millau { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof of one or several keys; - // - id of the lane we prove state of. - type MessagesDeliveryProof = ToMillauMessagesDeliveryProof; - - fn verify_message(payload: &ToMillauMessagePayload) -> Result<(), Self::Error> { - messages::source::verify_chain_message::(payload) - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData), Self::Error> { - messages::source::verify_messages_delivery_proof::(proof) - } -} - -impl SourceHeaderChain for Millau { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof of one or several keys; - // - id of the lane we prove messages for; - // - inclusive range of messages nonces that are proved. - type MessagesProof = FromMillauMessagesProof; - - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result, Self::Error> { - messages::target::verify_messages_proof::(proof, messages_count) - .map_err(Into::into) - } -} diff --git a/bin/rialto/runtime/src/lib.rs b/bin/rialto/runtime/src/lib.rs index 123cd477d978..d9b07d582fb2 100644 --- a/bin/rialto/runtime/src/lib.rs +++ b/bin/rialto/runtime/src/lib.rs @@ -448,7 +448,7 @@ impl pallet_bridge_messages::Config for Runtime { type InboundRelayer = bp_millau::AccountId; type DeliveryPayments = (); - type TargetHeaderChain = crate::millau_messages::Millau; + type TargetHeaderChain = crate::millau_messages::MillauAsTargetHeaderChain; type LaneMessageVerifier = crate::millau_messages::ToMillauMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, @@ -456,7 +456,7 @@ impl pallet_bridge_messages::Config for Runtime { frame_support::traits::ConstU128<100_000>, >; - type SourceHeaderChain = crate::millau_messages::Millau; + type SourceHeaderChain = crate::millau_messages::MillauAsSourceHeaderChain; type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch; type BridgedChainId = BridgedChainId; } diff --git a/bin/rialto/runtime/src/millau_messages.rs b/bin/rialto/runtime/src/millau_messages.rs index 90a63a733c33..09fbe46453df 100644 --- a/bin/rialto/runtime/src/millau_messages.rs +++ b/bin/rialto/runtime/src/millau_messages.rs @@ -18,13 +18,11 @@ use crate::{MillauGrandpaInstance, Runtime, RuntimeCall, RuntimeOrigin}; -use bp_messages::{ - source_chain::TargetHeaderChain, - target_chain::{ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageNonce, -}; +use bp_messages::{LaneId, MessageNonce}; use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; -use bridge_runtime_common::messages::{self, MessageBridge}; +use bridge_runtime_common::messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +}; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; /// Lane that is used for XCM messages exchange. @@ -110,6 +108,10 @@ impl messages::ThisChainWithMessages for Rialto { /// Millau chain from message lane point of view. #[derive(RuntimeDebug, Clone, Copy)] pub struct Millau; +/// Millau as source header chain. +pub type MillauAsSourceHeaderChain = SourceHeaderChainAdapter; +/// Millau as target header chain. +pub type MillauAsTargetHeaderChain = TargetHeaderChainAdapter; impl messages::UnderlyingChainProvider for Millau { type Chain = bp_millau::Millau; @@ -121,43 +123,6 @@ impl messages::BridgedChainWithMessages for Millau { } } -impl TargetHeaderChain for Millau { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof of one or several keys; - // - id of the lane we prove state of. - type MessagesDeliveryProof = ToMillauMessagesDeliveryProof; - - fn verify_message(payload: &ToMillauMessagePayload) -> Result<(), Self::Error> { - messages::source::verify_chain_message::(payload) - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData), Self::Error> { - messages::source::verify_messages_delivery_proof::(proof) - } -} - -impl SourceHeaderChain for Millau { - type Error = &'static str; - // The proof is: - // - hash of the header this proof has been created with; - // - the storage proof of one or several keys; - // - id of the lane we prove messages for; - // - inclusive range of messages nonces that are proved. - type MessagesProof = FromMillauMessagesProof; - - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result, Self::Error> { - messages::target::verify_messages_proof::(proof, messages_count) - .map_err(Into::into) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/bin/runtime-common/Cargo.toml b/bin/runtime-common/Cargo.toml index 9153d7a05dda..9e8e6b29db22 100644 --- a/bin/runtime-common/Cargo.toml +++ b/bin/runtime-common/Cargo.toml @@ -29,7 +29,6 @@ pallet-bridge-relayers = { path = "../../modules/relayers", default-features = f frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -46,9 +45,8 @@ xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false } [dev-dependencies] -bp-rialto = { path = "../../primitives/chain-rialto" } bp-test-utils = { path = "../../primitives/test-utils" } -millau-runtime = { path = "../millau/runtime" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } [features] default = ["std"] @@ -82,7 +80,6 @@ std = [ "xcm-executor/std", ] runtime-benchmarks = [ - "pallet-balances", "pallet-bridge-grandpa/runtime-benchmarks", "pallet-bridge-messages/runtime-benchmarks", "xcm-builder/runtime-benchmarks", diff --git a/bin/runtime-common/src/integrity.rs b/bin/runtime-common/src/integrity.rs index e8e3e7f87cc6..45387b5a1683 100644 --- a/bin/runtime-common/src/integrity.rs +++ b/bin/runtime-common/src/integrity.rs @@ -81,8 +81,8 @@ macro_rules! assert_bridge_messages_pallet_types( // configuration is used), or something has broke existing configuration (meaning that all bridged chains // and relays will stop functioning) use $crate::messages::{ - source::FromThisChainMessagePayload, - target::FromBridgedChainMessagePayload, + source::{FromThisChainMessagePayload, TargetHeaderChainAdapter}, + target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, AccountIdOf, BalanceOf, BridgedChain, CallOf, ThisChain, }; use pallet_bridge_messages::Config as MessagesConfig; @@ -93,8 +93,8 @@ macro_rules! assert_bridge_messages_pallet_types( assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, FromBridgedChainMessagePayload>>); assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, BridgedChain<$bridge>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::SourceHeaderChain, BridgedChain<$bridge>); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, TargetHeaderChainAdapter<$bridge>); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::SourceHeaderChain, SourceHeaderChainAdapter<$bridge>); } } ); diff --git a/bin/runtime-common/src/lib.rs b/bin/runtime-common/src/lib.rs index f8d2e7a039eb..9f31450bd28a 100644 --- a/bin/runtime-common/src/lib.rs +++ b/bin/runtime-common/src/lib.rs @@ -30,6 +30,7 @@ pub mod parachains_benchmarking; pub mod refund_relayer_extension; mod messages_generation; +mod mock; #[cfg(feature = "integrity-test")] pub mod integrity; diff --git a/bin/runtime-common/src/messages.rs b/bin/runtime-common/src/messages.rs index 3974966daadd..0d38e4b0d250 100644 --- a/bin/runtime-common/src/messages.rs +++ b/bin/runtime-common/src/messages.rs @@ -22,8 +22,10 @@ use bp_header_chain::{HeaderChain, HeaderChainError}; use bp_messages::{ - source_chain::LaneMessageVerifier, - target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages}, + source_chain::{LaneMessageVerifier, TargetHeaderChain}, + target_chain::{ + DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, + }, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, }; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Size, StorageProofChecker}; @@ -212,6 +214,26 @@ pub mod source { ) } + /// `TargetHeaderChain` implementation that is using default types and perform default checks. + pub struct TargetHeaderChainAdapter(PhantomData); + + impl TargetHeaderChain>> + for TargetHeaderChainAdapter + { + type Error = &'static str; + type MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof>>; + + fn verify_message(payload: &FromThisChainMessagePayload) -> Result<(), Self::Error> { + verify_chain_message::(payload) + } + + fn verify_messages_delivery_proof( + proof: Self::MessagesDeliveryProof, + ) -> Result<(LaneId, InboundLaneData>>), Self::Error> { + verify_messages_delivery_proof::(proof) + } + } + /// Do basic Bridged-chain specific verification of This -> Bridged chain message. /// /// Ok result from this function means that the delivery transaction with this message @@ -549,6 +571,21 @@ pub mod target { maximal_extrinsic_size / 3 * 2 } + /// `SourceHeaderChain` implementation that is using default types and perform default checks. + pub struct SourceHeaderChainAdapter(PhantomData); + + impl SourceHeaderChain for SourceHeaderChainAdapter { + type Error = &'static str; + type MessagesProof = FromBridgedChainMessagesProof>>; + + fn verify_messages_proof( + proof: Self::MessagesProof, + messages_count: u32, + ) -> Result, Self::Error> { + verify_messages_proof::(proof, messages_count).map_err(Into::into) + } + } + /// Verify proof of Bridged -> This chain messages. /// /// This function is used when Bridged chain is directly using GRANDPA finality. For Bridged @@ -702,206 +739,22 @@ pub type BridgeMessagesCallOf = bp_messages::BridgeMessagesCall< #[cfg(test)] mod tests { use super::*; - use crate::messages_generation::{ - encode_all_messages, encode_lane_data, prepare_messages_storage_proof, + use crate::{ + messages_generation::{ + encode_all_messages, encode_lane_data, prepare_messages_storage_proof, + }, + mock::*, }; - use codec::{Decode, Encode}; - use frame_support::weights::Weight; + use bp_header_chain::StoredHeaderDataBuilder; + use bp_runtime::HeaderId; + use codec::Encode; use sp_core::H256; - use sp_runtime::traits::{BlakeTwo256, Header as _}; - use std::cell::RefCell; - - const BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT: usize = 5; - const BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT: usize = 2048; - const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024; - - /// Bridge that is deployed on ThisChain and allows sending/receiving messages to/from - /// BridgedChain. - #[derive(Debug, PartialEq, Eq)] - struct OnThisChainBridge; - - impl MessageBridge for OnThisChainBridge { - const THIS_CHAIN_ID: ChainId = *b"this"; - const BRIDGED_CHAIN_ID: ChainId = *b"brdg"; - const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; - - type ThisChain = ThisChain; - type BridgedChain = BridgedChain; - type BridgedHeaderChain = BridgedHeaderChain; - } - - /// Bridge that is deployed on BridgedChain and allows sending/receiving messages to/from - /// ThisChain; - #[derive(Debug, PartialEq, Eq)] - struct OnBridgedChainBridge; - - impl MessageBridge for OnBridgedChainBridge { - const THIS_CHAIN_ID: ChainId = *b"brdg"; - const BRIDGED_CHAIN_ID: ChainId = *b"this"; - const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; - - type ThisChain = BridgedChain; - type BridgedChain = ThisChain; - type BridgedHeaderChain = ThisHeaderChain; - } - - #[derive(Clone, Debug)] - struct ThisChainOrigin(Result, ()>); - - impl From - for Result, ThisChainOrigin> - { - fn from( - origin: ThisChainOrigin, - ) -> Result, ThisChainOrigin> { - origin.clone().0.map_err(|_| origin) - } - } - - #[derive(Clone, Debug)] - struct BridgedChainOrigin; - - impl From - for Result, BridgedChainOrigin> - { - fn from( - _origin: BridgedChainOrigin, - ) -> Result, BridgedChainOrigin> { - unreachable!() - } - } - - struct ThisUnderlyingChain; - type ThisChainHeader = sp_runtime::generic::Header; - type ThisChainAccountId = u32; - type ThisChainBalance = u32; - #[derive(Decode, Encode)] - struct ThisChainCall; - - impl Chain for ThisUnderlyingChain { - type BlockNumber = u64; - type Hash = H256; - type Hasher = BlakeTwo256; - type Header = ThisChainHeader; - type AccountId = ThisChainAccountId; - type Balance = ThisChainBalance; - type Index = u32; - type Signature = sp_runtime::MultiSignature; - - fn max_extrinsic_size() -> u32 { - BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE - } - - fn max_extrinsic_weight() -> Weight { - Weight::zero() - } - } - - struct ThisChain; - - impl UnderlyingChainProvider for ThisChain { - type Chain = ThisUnderlyingChain; - } - - impl ThisChainWithMessages for ThisChain { - type RuntimeOrigin = ThisChainOrigin; - type RuntimeCall = ThisChainCall; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { - lane == TEST_LANE_ID - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE - } - } - - impl BridgedChainWithMessages for ThisChain { - fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { - unreachable!() - } - } - - struct BridgedUnderlyingChain; - type BridgedChainHeader = sp_runtime::generic::Header; - type BridgedChainAccountId = u128; - type BridgedChainBalance = u128; - #[derive(Decode, Encode)] - struct BridgedChainCall; - - impl Chain for BridgedUnderlyingChain { - type BlockNumber = u64; - type Hash = H256; - type Hasher = BlakeTwo256; - type Header = BridgedChainHeader; - type AccountId = BridgedChainAccountId; - type Balance = BridgedChainBalance; - type Index = u32; - type Signature = sp_runtime::MultiSignature; - - fn max_extrinsic_size() -> u32 { - BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE - } - fn max_extrinsic_weight() -> Weight { - Weight::zero() - } - } - - struct BridgedChain; - - impl UnderlyingChainProvider for BridgedChain { - type Chain = BridgedUnderlyingChain; - } - - impl ThisChainWithMessages for BridgedChain { - type RuntimeOrigin = BridgedChainOrigin; - type RuntimeCall = BridgedChainCall; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { - unreachable!() - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - unreachable!() - } - } - - impl BridgedChainWithMessages for BridgedChain { - fn verify_dispatch_weight(message_payload: &[u8]) -> bool { - message_payload.len() >= BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT && - message_payload.len() <= BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT - } - } - - thread_local! { - static TEST_BRIDGED_HEADER: RefCell> = RefCell::new(None); - } - - struct BridgedHeaderChain; - - impl HeaderChain for BridgedHeaderChain { - fn finalized_header_state_root( - _hash: HashOf, - ) -> Option> { - TEST_BRIDGED_HEADER.with(|h| h.borrow().clone()).map(|h| *h.state_root()) - } - } - - struct ThisHeaderChain; - - impl HeaderChain for ThisHeaderChain { - fn finalized_header_state_root(_hash: HashOf) -> Option> { - unreachable!() - } - } + use sp_runtime::traits::Header as _; fn test_lane_outbound_data() -> OutboundLaneData { OutboundLaneData::default() } - const TEST_LANE_ID: &LaneId = &LaneId(*b"test"); - const MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE: MessageNonce = 32; - fn regular_outbound_message_payload() -> source::FromThisChainMessagePayload { vec![42] } @@ -910,7 +763,7 @@ mod tests { fn message_is_rejected_when_sent_using_disabled_lane() { assert_eq!( source::FromThisChainMessageVerifier::::verify_message( - &ThisChainOrigin(Ok(frame_system::RawOrigin::Root)), + &frame_system::RawOrigin::Root.into(), &LaneId(*b"dsbl"), &test_lane_outbound_data(), ®ular_outbound_message_payload(), @@ -923,8 +776,8 @@ mod tests { fn message_is_rejected_when_there_are_too_many_pending_messages_at_outbound_lane() { assert_eq!( source::FromThisChainMessageVerifier::::verify_message( - &ThisChainOrigin(Ok(frame_system::RawOrigin::Root)), - TEST_LANE_ID, + &frame_system::RawOrigin::Root.into(), + &TEST_LANE_ID, &OutboundLaneData { latest_received_nonce: 100, latest_generated_nonce: 100 + MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE + 1, @@ -986,7 +839,7 @@ mod tests { test: impl Fn(target::FromBridgedChainMessagesProof) -> R, ) -> R { let (state_root, storage_proof) = prepare_messages_storage_proof::( - *TEST_LANE_ID, + TEST_LANE_ID, 1..=nonces_end, outbound_lane_data, bp_runtime::StorageProofSize::Minimal(0), @@ -995,22 +848,31 @@ mod tests { encode_outbound_lane_data, ); - TEST_BRIDGED_HEADER.with(|h| { - *h.borrow_mut() = Some(BridgedChainHeader::new( + sp_io::TestExternalities::new(Default::default()).execute_with(move || { + let bridged_header = BridgedChainHeader::new( 0, Default::default(), state_root, Default::default(), Default::default(), - )) - }); + ); + let bridged_header_hash = bridged_header.hash(); - test(target::FromBridgedChainMessagesProof { - bridged_header_hash: Default::default(), - storage_proof, - lane: *TEST_LANE_ID, - nonces_start: 1, - nonces_end, + pallet_bridge_grandpa::BestFinalized::::put(HeaderId( + 0, + bridged_header_hash, + )); + pallet_bridge_grandpa::ImportedHeaders::::insert( + bridged_header_hash, + bridged_header.build(), + ); + test(target::FromBridgedChainMessagesProof { + bridged_header_hash, + storage_proof, + lane: TEST_LANE_ID, + nonces_start: 1, + nonces_end, + }) }) } @@ -1038,7 +900,9 @@ mod tests { fn message_proof_is_rejected_if_header_is_missing_from_the_chain() { assert_eq!( using_messages_proof(10, None, encode_all_messages, encode_lane_data, |proof| { - TEST_BRIDGED_HEADER.with(|h| *h.borrow_mut() = None); + let bridged_header_hash = + pallet_bridge_grandpa::BestFinalized::::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::::remove(bridged_header_hash); target::verify_messages_proof::(proof, 10) }), Err(target::MessageProofError::HeaderChain(HeaderChainError::UnknownHeader)), @@ -1049,8 +913,19 @@ mod tests { fn message_proof_is_rejected_if_header_state_root_mismatches() { assert_eq!( using_messages_proof(10, None, encode_all_messages, encode_lane_data, |proof| { - TEST_BRIDGED_HEADER - .with(|h| h.borrow_mut().as_mut().unwrap().state_root = Default::default()); + let bridged_header_hash = + pallet_bridge_grandpa::BestFinalized::::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::::insert( + bridged_header_hash, + BridgedChainHeader::new( + 0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ) + .build(), + ); target::verify_messages_proof::(proof, 10) }), Err(target::MessageProofError::HeaderChain(HeaderChainError::StorageRootMismatch)), @@ -1138,7 +1013,7 @@ mod tests { |proof| target::verify_messages_proof::(proof, 0), ), Ok(vec![( - *TEST_LANE_ID, + TEST_LANE_ID, ProvedLaneMessages { lane_state: Some(OutboundLaneData { oldest_unpruned_nonce: 1, @@ -1168,7 +1043,7 @@ mod tests { |proof| target::verify_messages_proof::(proof, 1), ), Ok(vec![( - *TEST_LANE_ID, + TEST_LANE_ID, ProvedLaneMessages { lane_state: Some(OutboundLaneData { oldest_unpruned_nonce: 1, @@ -1176,7 +1051,7 @@ mod tests { latest_generated_nonce: 1, }), messages: vec![Message { - key: MessageKey { lane_id: *TEST_LANE_ID, nonce: 1 }, + key: MessageKey { lane_id: TEST_LANE_ID, nonce: 1 }, payload: vec![42], }], }, diff --git a/bin/runtime-common/src/messages_benchmarking.rs b/bin/runtime-common/src/messages_benchmarking.rs index 919c03583b88..afe95422d185 100644 --- a/bin/runtime-common/src/messages_benchmarking.rs +++ b/bin/runtime-common/src/messages_benchmarking.rs @@ -48,7 +48,6 @@ pub fn prepare_message_proof( ) -> (FromBridgedChainMessagesProof>>, Weight) where R: frame_system::Config>> - + pallet_balances::Config>> + pallet_bridge_grandpa::Config, R::BridgedChain: bp_runtime::Chain>, Header = BH>, B: MessageBridge, diff --git a/bin/runtime-common/src/messages_extension.rs b/bin/runtime-common/src/messages_extension.rs index 0f680f84e493..1e207dc605b3 100644 --- a/bin/runtime-common/src/messages_extension.rs +++ b/bin/runtime-common/src/messages_extension.rs @@ -96,20 +96,17 @@ impl< #[cfg(test)] mod tests { - use bp_messages::UnrewardedRelayersState; - use millau_runtime::{ - bridge_runtime_common::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, - target::FromBridgedChainMessagesProof, - }, - BridgeRuntimeFilterCall, + use crate::{ + messages::{ + source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }, - Runtime, RuntimeCall, WithRialtoMessagesInstance, + mock::{TestRuntime, ThisChainRuntimeCall}, + BridgeRuntimeFilterCall, }; + use bp_messages::UnrewardedRelayersState; fn deliver_message_10() { - pallet_bridge_messages::InboundLanes::::insert( + pallet_bridge_messages::InboundLanes::::insert( bp_messages::LaneId([0, 0, 0, 0]), bp_messages::InboundLaneData { relayers: Default::default(), last_confirmed_nonce: 10 }, ); @@ -119,10 +116,10 @@ mod tests { nonces_start: bp_messages::MessageNonce, nonces_end: bp_messages::MessageNonce, ) -> bool { - pallet_bridge_messages::Pallet::::validate( - &RuntimeCall::BridgeRialtoMessages( - pallet_bridge_messages::Call::::receive_messages_proof { - relayer_id_at_bridged_chain: [0u8; 32].into(), + pallet_bridge_messages::Pallet::::validate( + &ThisChainRuntimeCall::BridgeMessages( + pallet_bridge_messages::Call::::receive_messages_proof { + relayer_id_at_bridged_chain: 42, messages_count: (nonces_end - nonces_start + 1) as u32, dispatch_weight: frame_support::weights::Weight::zero(), proof: FromBridgedChainMessagesProof { @@ -169,7 +166,7 @@ mod tests { } fn confirm_message_10() { - pallet_bridge_messages::OutboundLanes::::insert( + pallet_bridge_messages::OutboundLanes::::insert( bp_messages::LaneId([0, 0, 0, 0]), bp_messages::OutboundLaneData { oldest_unpruned_nonce: 0, @@ -180,21 +177,20 @@ mod tests { } fn validate_message_confirmation(last_delivered_nonce: bp_messages::MessageNonce) -> bool { - pallet_bridge_messages::Pallet::::validate( - &RuntimeCall::BridgeRialtoMessages(pallet_bridge_messages::Call::< - Runtime, - WithRialtoMessagesInstance, - >::receive_messages_delivery_proof { - proof: FromBridgedChainMessagesDeliveryProof { - bridged_header_hash: Default::default(), - storage_proof: Vec::new(), - lane: bp_messages::LaneId([0, 0, 0, 0]), - }, - relayers_state: UnrewardedRelayersState { - last_delivered_nonce, - ..Default::default() + pallet_bridge_messages::Pallet::::validate( + &ThisChainRuntimeCall::BridgeMessages( + pallet_bridge_messages::Call::::receive_messages_delivery_proof { + proof: FromBridgedChainMessagesDeliveryProof { + bridged_header_hash: Default::default(), + storage_proof: Vec::new(), + lane: bp_messages::LaneId([0, 0, 0, 0]), + }, + relayers_state: UnrewardedRelayersState { + last_delivered_nonce, + ..Default::default() + }, }, - }), + ), ) .is_ok() } diff --git a/bin/runtime-common/src/mock.rs b/bin/runtime-common/src/mock.rs new file mode 100644 index 000000000000..d4b177510bf3 --- /dev/null +++ b/bin/runtime-common/src/mock.rs @@ -0,0 +1,422 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +//! A mock runtime for testing different stuff in the crate. We've been using Millau +//! runtime for that before, but it has two drawbacks: +//! +//! - circular dependencies between this crate and Millau runtime; +//! +//! - we can't use (e.g. as git subtree or by copying) this crate in repo without Millau. + +#![cfg(test)] + +use crate::messages::{ + source::{ + FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload, + FromThisChainMessageVerifier, TargetHeaderChainAdapter, + }, + target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, + BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, +}; + +use bp_header_chain::HeaderChain; +use bp_messages::{target_chain::ForbidInboundMessages, LaneId, MessageNonce}; +use bp_parachains::SingleParaStoredHeaderDataBuilder; +use bp_runtime::{Chain, ChainId, Parachain, UnderlyingChainProvider}; +use codec::{Decode, Encode}; +use frame_support::{ + parameter_types, + weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight}, +}; +use pallet_transaction_payment::Multiplier; +use sp_runtime::{ + testing::H256, + traits::{BlakeTwo256, ConstU32, ConstU64, ConstU8, IdentityLookup}, + FixedPointNumber, Perquintill, +}; + +/// Account identifier at `ThisChain`. +pub type ThisChainAccountId = u64; +/// Balance at `ThisChain`. +pub type ThisChainBalance = u64; +/// Block number at `ThisChain`. +pub type ThisChainBlockNumber = u32; +/// Hash at `ThisChain`. +pub type ThisChainHash = H256; +/// Hasher at `ThisChain`. +pub type ThisChainHasher = BlakeTwo256; +/// Runtime call at `ThisChain`. +pub type ThisChainRuntimeCall = RuntimeCall; +/// Runtime call origin at `ThisChain`. +pub type ThisChainCallOrigin = RuntimeOrigin; +/// Header of `ThisChain`. +pub type ThisChainHeader = sp_runtime::generic::Header; +/// Block of `ThisChain`. +pub type ThisChainBlock = frame_system::mocking::MockBlock; +/// Unchecked extrinsic of `ThisChain`. +pub type ThisChainUncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + +/// Account identifier at the `BridgedChain`. +pub type BridgedChainAccountId = u128; +/// Balance at the `BridgedChain`. +pub type BridgedChainBalance = u128; +/// Block number at the `BridgedChain`. +pub type BridgedChainBlockNumber = u32; +/// Hash at the `BridgedChain`. +pub type BridgedChainHash = H256; +/// Hasher at the `BridgedChain`. +pub type BridgedChainHasher = BlakeTwo256; +/// Header of the `BridgedChain`. +pub type BridgedChainHeader = + sp_runtime::generic::Header; + +/// Message lane used in tests. +pub const TEST_LANE_ID: LaneId = LaneId([0, 0, 0, 0]); +/// Maximal number of queued messages at the test lane. +pub const MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE: MessageNonce = 32; +/// Minimal extrinsic weight at the `BridgedChain`. +pub const BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT: usize = 5; +/// Maximal extrinsic weight at the `BridgedChain`. +pub const BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT: usize = 2048; +/// Maximal extrinsic size at the `BridgedChain`. +pub const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024; + +frame_support::construct_runtime! { + pub enum TestRuntime where + Block = ThisChainBlock, + NodeBlock = ThisChainBlock, + UncheckedExtrinsic = ThisChainUncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Utility: pallet_utility, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event}, + BridgeGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, + BridgeParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event}, + BridgeMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config}, + } +} + +crate::generate_bridge_reject_obsolete_headers_and_messages! { + ThisChainRuntimeCall, ThisChainAccountId, + BridgeGrandpa, BridgeParachains, BridgeMessages +} + +parameter_types! { + pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID]; + pub const BridgedChainId: ChainId = *b"brdg"; + pub const BridgedParasPalletName: &'static str = "Paras"; + pub const ExistentialDeposit: ThisChainBalance = 500; + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 1, write: 2 }; + pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); + pub const TransactionBaseFee: ThisChainBalance = 0; + pub const TransactionByteFee: ThisChainBalance = 1; + pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(3, 100_000); + pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000u128); + pub MaximumMultiplier: Multiplier = sp_runtime::traits::Bounded::max_value(); +} + +impl frame_system::Config for TestRuntime { + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type RuntimeCall = RuntimeCall; + type BlockNumber = ThisChainBlockNumber; + type Hash = ThisChainHash; + type Hashing = ThisChainHasher; + type AccountId = ThisChainAccountId; + type Lookup = IdentityLookup; + type Header = ThisChainHeader; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU32<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type BaseCallFilter = frame_support::traits::Everything; + type SystemWeightInfo = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = DbWeight; + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_utility::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = (); +} + +impl pallet_balances::Config for TestRuntime { + type Balance = ThisChainBalance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = ConstU32<50>; + type MaxReserves = ConstU32<50>; + type ReserveIdentifier = [u8; 8]; +} + +impl pallet_transaction_payment::Config for TestRuntime { + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = pallet_transaction_payment::TargetedFeeAdjustment< + TestRuntime, + TargetBlockFullness, + AdjustmentVariable, + MinimumMultiplier, + MaximumMultiplier, + >; + type RuntimeEvent = RuntimeEvent; +} + +impl pallet_bridge_grandpa::Config for TestRuntime { + type BridgedChain = BridgedUnderlyingChain; + type MaxRequests = ConstU32<50>; + type HeadersToKeep = ConstU32<8>; + type MaxBridgedAuthorities = ConstU32<1024>; + type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; +} + +impl pallet_bridge_parachains::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type BridgesGrandpaPalletInstance = (); + type ParasPalletName = BridgedParasPalletName; + type ParaStoredHeaderDataBuilder = + SingleParaStoredHeaderDataBuilder; + type HeadsToKeep = ConstU32<8>; + type MaxParaHeadDataSize = ConstU32<1024>; + type WeightInfo = pallet_bridge_parachains::weights::BridgeWeight; +} + +impl pallet_bridge_messages::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; + type ActiveOutboundLanes = ActiveOutboundLanes; + type MaxUnrewardedRelayerEntriesAtInboundLane = ConstU64<16>; + type MaxUnconfirmedMessagesAtInboundLane = ConstU64<16>; + + type MaximalOutboundPayloadSize = FromThisChainMaximalOutboundPayloadSize; + type OutboundPayload = FromThisChainMessagePayload; + + type InboundPayload = FromBridgedChainMessagePayload; + type InboundRelayer = BridgedChainAccountId; + type DeliveryPayments = (); + + type TargetHeaderChain = TargetHeaderChainAdapter; + type LaneMessageVerifier = FromThisChainMessageVerifier; + type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< + TestRuntime, + frame_support::traits::ConstU64<100_000>, + frame_support::traits::ConstU64<10_000>, + >; + + type SourceHeaderChain = SourceHeaderChainAdapter; + type MessageDispatch = + ForbidInboundMessages<(), FromBridgedChainMessagePayload>; + type BridgedChainId = BridgedChainId; +} + +impl pallet_bridge_relayers::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type Reward = ThisChainBalance; + type PaymentProcedure = (); + type WeightInfo = (); +} + +/// Bridge that is deployed on ThisChain and allows sending/receiving messages to/from +/// BridgedChain. +#[derive(Debug, PartialEq, Eq)] +pub struct OnThisChainBridge; + +impl MessageBridge for OnThisChainBridge { + const THIS_CHAIN_ID: ChainId = *b"this"; + const BRIDGED_CHAIN_ID: ChainId = *b"brdg"; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; + + type ThisChain = ThisChain; + type BridgedChain = BridgedChain; + type BridgedHeaderChain = pallet_bridge_grandpa::GrandpaChainHeaders; +} + +/// Bridge that is deployed on BridgedChain and allows sending/receiving messages to/from +/// ThisChain; +#[derive(Debug, PartialEq, Eq)] +pub struct OnBridgedChainBridge; + +impl MessageBridge for OnBridgedChainBridge { + const THIS_CHAIN_ID: ChainId = *b"brdg"; + const BRIDGED_CHAIN_ID: ChainId = *b"this"; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; + + type ThisChain = BridgedChain; + type BridgedChain = ThisChain; + type BridgedHeaderChain = ThisHeaderChain; +} + +/// Dummy implementation of `HeaderChain` for `ThisChain` at the `BridgedChain`. +pub struct ThisHeaderChain; + +impl HeaderChain for ThisHeaderChain { + fn finalized_header_state_root(_hash: HashOf) -> Option> { + unreachable!() + } +} + +/// Call origin at `BridgedChain`. +#[derive(Clone, Debug)] +pub struct BridgedChainOrigin; + +impl From + for Result, BridgedChainOrigin> +{ + fn from( + _origin: BridgedChainOrigin, + ) -> Result, BridgedChainOrigin> { + unreachable!() + } +} + +/// Underlying chain of `ThisChain`. +pub struct ThisUnderlyingChain; + +impl Chain for ThisUnderlyingChain { + type BlockNumber = ThisChainBlockNumber; + type Hash = ThisChainHash; + type Hasher = ThisChainHasher; + type Header = ThisChainHeader; + type AccountId = ThisChainAccountId; + type Balance = ThisChainBalance; + type Index = u32; + type Signature = sp_runtime::MultiSignature; + + fn max_extrinsic_size() -> u32 { + BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE + } + + fn max_extrinsic_weight() -> Weight { + Weight::zero() + } +} + +/// The chain where we are in tests. +pub struct ThisChain; + +impl UnderlyingChainProvider for ThisChain { + type Chain = ThisUnderlyingChain; +} + +impl ThisChainWithMessages for ThisChain { + type RuntimeOrigin = ThisChainCallOrigin; + type RuntimeCall = ThisChainRuntimeCall; + + fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { + *lane == TEST_LANE_ID + } + + fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { + MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE + } +} + +impl BridgedChainWithMessages for ThisChain { + fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { + unreachable!() + } +} + +/// Underlying chain of `BridgedChain`. +pub struct BridgedUnderlyingChain; +/// Some parachain under `BridgedChain` consensus. +pub struct BridgedUnderlyingParachain; +/// Runtime call of the `BridgedChain`. +#[derive(Decode, Encode)] +pub struct BridgedChainCall; + +impl Chain for BridgedUnderlyingChain { + type BlockNumber = BridgedChainBlockNumber; + type Hash = BridgedChainHash; + type Hasher = BridgedChainHasher; + type Header = BridgedChainHeader; + type AccountId = BridgedChainAccountId; + type Balance = BridgedChainBalance; + type Index = u32; + type Signature = sp_runtime::MultiSignature; + + fn max_extrinsic_size() -> u32 { + BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE + } + fn max_extrinsic_weight() -> Weight { + Weight::zero() + } +} + +impl Chain for BridgedUnderlyingParachain { + type BlockNumber = BridgedChainBlockNumber; + type Hash = BridgedChainHash; + type Hasher = BridgedChainHasher; + type Header = BridgedChainHeader; + type AccountId = BridgedChainAccountId; + type Balance = BridgedChainBalance; + type Index = u32; + type Signature = sp_runtime::MultiSignature; + + fn max_extrinsic_size() -> u32 { + BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE + } + fn max_extrinsic_weight() -> Weight { + Weight::zero() + } +} + +impl Parachain for BridgedUnderlyingParachain { + const PARACHAIN_ID: u32 = 42; +} + +/// The other, bridged chain, used in tests. +pub struct BridgedChain; + +impl UnderlyingChainProvider for BridgedChain { + type Chain = BridgedUnderlyingChain; +} + +impl ThisChainWithMessages for BridgedChain { + type RuntimeOrigin = BridgedChainOrigin; + type RuntimeCall = BridgedChainCall; + + fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { + unreachable!() + } + + fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { + unreachable!() + } +} + +impl BridgedChainWithMessages for BridgedChain { + fn verify_dispatch_weight(message_payload: &[u8]) -> bool { + message_payload.len() >= BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT && + message_payload.len() <= BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT + } +} diff --git a/bin/runtime-common/src/refund_relayer_extension.rs b/bin/runtime-common/src/refund_relayer_extension.rs index 0038af975db7..51a7db3b53b0 100644 --- a/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bin/runtime-common/src/refund_relayer_extension.rs @@ -19,12 +19,7 @@ //! with calls that are: delivering new messsage and all necessary underlying headers //! (parachain or relay chain). -// hack because we have circular (test-level) dependency between `millau-runtime` -// and `bridge-runtime-common` crates -#[cfg(not(test))] use crate::messages::target::FromBridgedChainMessagesProof; -#[cfg(test)] -use millau_runtime::bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use bp_messages::{target_chain::SourceHeaderChain, LaneId, MessageNonce}; use bp_polkadot_core::parachains::ParaId; @@ -475,36 +470,37 @@ where #[cfg(test)] mod tests { use super::*; + use crate::{messages::target::FromBridgedChainMessagesProof, mock::*}; use bp_messages::InboundLaneData; use bp_parachains::{BestParaHeadHash, ParaInfo}; use bp_polkadot_core::parachains::ParaHeadsProof; use bp_runtime::HeaderId; use bp_test_utils::make_default_justification; use frame_support::{assert_storage_noop, parameter_types, weights::Weight}; - use millau_runtime::{ - RialtoGrandpaInstance, Runtime, RuntimeCall, WithRialtoParachainMessagesInstance, - WithRialtoParachainsInstance, - }; use sp_runtime::{transaction_validity::InvalidTransaction, DispatchError}; parameter_types! { pub TestParachain: u32 = 1000; - pub TestLaneId: LaneId = LaneId([0, 0, 0, 0]); + pub TestLaneId: LaneId = TEST_LANE_ID; } type TestExtension = RefundRelayerForMessagesFromParachain< - millau_runtime::Runtime, - RialtoGrandpaInstance, - WithRialtoParachainsInstance, - WithRialtoParachainMessagesInstance, - millau_runtime::BridgeRejectObsoleteHeadersAndMessages, + TestRuntime, + (), + (), + (), + BridgeRejectObsoleteHeadersAndMessages, TestParachain, TestLaneId, - millau_runtime::Runtime, + TestRuntime, >; - fn relayer_account() -> millau_runtime::AccountId { - [0u8; 32].into() + fn relayer_account_at_this_chain() -> ThisChainAccountId { + 0 + } + + fn relayer_account_at_bridged_chain() -> BridgedChainAccountId { + 0 } fn initialize_environment( @@ -513,9 +509,7 @@ mod tests { best_delivered_message: MessageNonce, ) { let best_relay_header = HeaderId(best_relay_header_number, RelayBlockHash::default()); - pallet_bridge_grandpa::BestFinalized::::put( - best_relay_header, - ); + pallet_bridge_grandpa::BestFinalized::::put(best_relay_header); let para_id = ParaId(TestParachain::get()); let para_info = ParaInfo { @@ -525,18 +519,16 @@ mod tests { }, next_imported_hash_position: 0, }; - pallet_bridge_parachains::ParasInfo::::insert( - para_id, para_info, - ); + pallet_bridge_parachains::ParasInfo::::insert(para_id, para_info); let lane_id = TestLaneId::get(); let lane_data = InboundLaneData { last_confirmed_nonce: best_delivered_message, ..Default::default() }; - pallet_bridge_messages::InboundLanes::::insert(lane_id, lane_data); + pallet_bridge_messages::InboundLanes::::insert(lane_id, lane_data); } fn submit_relay_header_call(relay_header_number: RelayBlockNumber) -> RuntimeCall { - let relay_header = bp_rialto::Header::new( + let relay_header = BridgedChainHeader::new( relay_header_number, Default::default(), Default::default(), @@ -545,7 +537,7 @@ mod tests { ); let relay_justification = make_default_justification(&relay_header); - RuntimeCall::BridgeRialtoGrandpa(GrandpaCall::submit_finality_proof { + RuntimeCall::BridgeGrandpa(GrandpaCall::submit_finality_proof { finality_target: Box::new(relay_header), justification: relay_justification, }) @@ -554,7 +546,7 @@ mod tests { fn submit_parachain_head_call( parachain_head_at_relay_header_number: RelayBlockNumber, ) -> RuntimeCall { - RuntimeCall::BridgeRialtoParachains(ParachainsCall::submit_parachain_heads { + RuntimeCall::BridgeParachains(ParachainsCall::submit_parachain_heads { at_relay_block: (parachain_head_at_relay_header_number, RelayBlockHash::default()), parachains: vec![(ParaId(TestParachain::get()), [1u8; 32].into())], parachain_heads_proof: ParaHeadsProof(vec![]), @@ -562,9 +554,9 @@ mod tests { } fn message_delivery_call(best_message: MessageNonce) -> RuntimeCall { - RuntimeCall::BridgeRialtoParachainMessages(MessagesCall::receive_messages_proof { - relayer_id_at_bridged_chain: relayer_account(), - proof: millau_runtime::bridge_runtime_common::messages::target::FromBridgedChainMessagesProof { + RuntimeCall::BridgeMessages(MessagesCall::receive_messages_proof { + relayer_id_at_bridged_chain: relayer_account_at_bridged_chain(), + proof: FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), storage_proof: vec![], lane: TestLaneId::get(), @@ -602,9 +594,9 @@ mod tests { }) } - fn all_finality_pre_dispatch_data() -> PreDispatchData { + fn all_finality_pre_dispatch_data() -> PreDispatchData { PreDispatchData { - relayer: relayer_account(), + relayer: relayer_account_at_this_chain(), call_type: CallType::AllFinalityAndDelivery( ExpectedRelayChainState { best_block_number: 200 }, ExpectedParachainState { at_relay_block_number: 200 }, @@ -613,9 +605,9 @@ mod tests { } } - fn parachain_finality_pre_dispatch_data() -> PreDispatchData { + fn parachain_finality_pre_dispatch_data() -> PreDispatchData { PreDispatchData { - relayer: relayer_account(), + relayer: relayer_account_at_this_chain(), call_type: CallType::ParachainFinalityAndDelivery( ExpectedParachainState { at_relay_block_number: 200 }, MessagesState { best_nonce: 100 }, @@ -623,9 +615,9 @@ mod tests { } } - fn delivery_pre_dispatch_data() -> PreDispatchData { + fn delivery_pre_dispatch_data() -> PreDispatchData { PreDispatchData { - relayer: relayer_account(), + relayer: relayer_account_at_this_chain(), call_type: CallType::Delivery(MessagesState { best_nonce: 100 }), } } @@ -636,14 +628,14 @@ mod tests { fn run_validate(call: RuntimeCall) -> TransactionValidity { let extension: TestExtension = RefundRelayerForMessagesFromParachain(PhantomData); - extension.validate(&relayer_account(), &call, &DispatchInfo::default(), 0) + extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } fn run_pre_dispatch( call: RuntimeCall, - ) -> Result>, TransactionValidityError> { + ) -> Result>, TransactionValidityError> { let extension: TestExtension = RefundRelayerForMessagesFromParachain(PhantomData); - extension.pre_dispatch(&relayer_account(), &call, &DispatchInfo::default(), 0) + extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } fn dispatch_info() -> DispatchInfo { @@ -661,7 +653,7 @@ mod tests { } fn run_post_dispatch( - pre_dispatch_data: Option>, + pre_dispatch_data: Option>, dispatch_result: DispatchResult, ) { let post_dispatch_result = TestExtension::post_dispatch( @@ -674,8 +666,8 @@ mod tests { assert_eq!(post_dispatch_result, Ok(())); } - fn expected_reward() -> millau_runtime::Balance { - pallet_transaction_payment::Pallet::::compute_actual_fee( + fn expected_reward() -> ThisChainBalance { + pallet_transaction_payment::Pallet::::compute_actual_fee( 1024, &dispatch_info(), &post_dispatch_info(), @@ -804,7 +796,7 @@ mod tests { let call = RuntimeCall::Utility(UtilityCall::batch_all { calls: vec![ - RuntimeCall::BridgeRialtoParachains(ParachainsCall::submit_parachain_heads { + RuntimeCall::BridgeParachains(ParachainsCall::submit_parachain_heads { at_relay_block: (100, RelayBlockHash::default()), parachains: vec![ (ParaId(TestParachain::get()), [1u8; 32].into()), @@ -892,7 +884,10 @@ mod tests { run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(())); assert_eq!( - RelayersPallet::::relayer_reward(relayer_account(), TestLaneId::get()), + RelayersPallet::::relayer_reward( + relayer_account_at_this_chain(), + TestLaneId::get() + ), Some(expected_reward()), ); }); @@ -905,7 +900,10 @@ mod tests { run_post_dispatch(Some(parachain_finality_pre_dispatch_data()), Ok(())); assert_eq!( - RelayersPallet::::relayer_reward(relayer_account(), TestLaneId::get()), + RelayersPallet::::relayer_reward( + relayer_account_at_this_chain(), + TestLaneId::get() + ), Some(expected_reward()), ); }); @@ -918,7 +916,10 @@ mod tests { run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(())); assert_eq!( - RelayersPallet::::relayer_reward(relayer_account(), TestLaneId::get()), + RelayersPallet::::relayer_reward( + relayer_account_at_this_chain(), + TestLaneId::get() + ), Some(expected_reward()), ); }); diff --git a/modules/relayers/Cargo.toml b/modules/relayers/Cargo.toml index c7ea1e544f2d..954818a3b505 100644 --- a/modules/relayers/Cargo.toml +++ b/modules/relayers/Cargo.toml @@ -40,6 +40,7 @@ std = [ "bp-relayers/std", "bp-runtime/std", "codec/std", + "frame-benchmarking/std", "frame-support/std", "frame-system/std", "log/std", diff --git a/primitives/messages/src/target_chain.rs b/primitives/messages/src/target_chain.rs index 1b285b065aa2..6604d425cfc4 100644 --- a/primitives/messages/src/target_chain.rs +++ b/primitives/messages/src/target_chain.rs @@ -22,7 +22,7 @@ use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode, Error as CodecError}; use frame_support::{weights::Weight, Parameter, RuntimeDebug}; use scale_info::TypeInfo; -use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*}; +use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, marker::PhantomData, prelude::*}; /// Proved messages from the source chain. pub type ProvedMessages = BTreeMap>; @@ -164,15 +164,19 @@ impl DeliveryPayments for () { /// Structure that may be used in place of `SourceHeaderChain` and `MessageDispatch` on chains, /// where inbound messages are forbidden. -pub struct ForbidInboundMessages; +pub struct ForbidInboundMessages( + PhantomData<(MessagesProof, DispatchPayload)>, +); /// Error message that is used in `ForbidOutboundMessages` implementation. const ALL_INBOUND_MESSAGES_REJECTED: &str = "This chain is configured to reject all inbound messages"; -impl SourceHeaderChain for ForbidInboundMessages { +impl SourceHeaderChain + for ForbidInboundMessages +{ type Error = &'static str; - type MessagesProof = (); + type MessagesProof = MessagesProof; fn verify_messages_proof( _proof: Self::MessagesProof, @@ -182,8 +186,10 @@ impl SourceHeaderChain for ForbidInboundMessages { } } -impl MessageDispatch for ForbidInboundMessages { - type DispatchPayload = (); +impl MessageDispatch + for ForbidInboundMessages +{ + type DispatchPayload = DispatchPayload; type DispatchLevelResult = (); fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { diff --git a/primitives/relayers/Cargo.toml b/primitives/relayers/Cargo.toml index acede813995d..7479811a57d7 100644 --- a/primitives/relayers/Cargo.toml +++ b/primitives/relayers/Cargo.toml @@ -20,7 +20,6 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } [dev-dependencies] -bp-rialto = { path = "../chain-rialto" } hex = "0.4" hex-literal = "0.3" diff --git a/primitives/relayers/src/lib.rs b/primitives/relayers/src/lib.rs index 207908296cbf..70a91ee941a0 100644 --- a/primitives/relayers/src/lib.rs +++ b/primitives/relayers/src/lib.rs @@ -37,6 +37,14 @@ pub trait PaymentProcedure { fn pay_reward(relayer: &Relayer, lane_id: LaneId, reward: Reward) -> Result<(), Self::Error>; } +impl PaymentProcedure for () { + type Error = &'static str; + + fn pay_reward(_: &Relayer, _: LaneId, _: Reward) -> Result<(), Self::Error> { + Ok(()) + } +} + /// Reward payment procedure that does `balances::transfer` call from the account, derived from /// given lane. pub struct PayLaneRewardFromAccount(PhantomData<(T, Relayer)>); @@ -88,21 +96,18 @@ where #[cfg(test)] mod tests { use super::*; + use sp_runtime::testing::H256; #[test] fn lanes_are_using_different_accounts() { assert_eq!( - PayLaneRewardFromAccount::<(), bp_rialto::AccountId>::lane_rewards_account(LaneId([ - 0, 0, 0, 0 - ])), + PayLaneRewardFromAccount::<(), H256>::lane_rewards_account(LaneId([0, 0, 0, 0])), hex_literal::hex!("626c616e000000006272696467652d6c616e6500000000000000000000000000") .into(), ); assert_eq!( - PayLaneRewardFromAccount::<(), bp_rialto::AccountId>::lane_rewards_account(LaneId([ - 0, 0, 0, 1 - ])), + PayLaneRewardFromAccount::<(), H256>::lane_rewards_account(LaneId([0, 0, 0, 1])), hex_literal::hex!("626c616e000000016272696467652d6c616e6500000000000000000000000000") .into(), ); diff --git a/relays/bin-substrate/src/chains/mod.rs b/relays/bin-substrate/src/chains/mod.rs index 7caba7561ddc..7aad5f44e890 100644 --- a/relays/bin-substrate/src/chains/mod.rs +++ b/relays/bin-substrate/src/chains/mod.rs @@ -52,7 +52,7 @@ mod tests { #[test] fn maximal_rialto_to_millau_message_size_is_computed_correctly() { - use rialto_runtime::millau_messages::Millau; + use rialto_runtime::millau_messages::MillauAsTargetHeaderChain; let maximal_message_size = encode_message::compute_maximal_message_size( bp_rialto::Rialto::max_extrinsic_size(), @@ -60,10 +60,10 @@ mod tests { ); let message = vec![42; maximal_message_size as _]; - assert_eq!(Millau::verify_message(&message), Ok(())); + assert_eq!(MillauAsTargetHeaderChain::verify_message(&message), Ok(())); let message = vec![42; (maximal_message_size + 1) as _]; - assert!(Millau::verify_message(&message).is_err()); + assert!(MillauAsTargetHeaderChain::verify_message(&message).is_err()); } #[test]