diff --git a/Cargo.lock b/Cargo.lock index 43601b85ca20ef0dc5f9b66edbb33bc5a56c41e8..4a7d47eb0f7802b0352c57a568d634ace0ce684a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2359,7 +2359,6 @@ dependencies = [ "bp-xcm-bridge-hub-router", "frame-support", "frame-system", - "hash-db", "log", "pallet-balances", "pallet-bridge-grandpa", @@ -2370,8 +2369,6 @@ dependencies = [ "pallet-utility", "parity-scale-codec", "scale-info", - "sp-api", - "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0", @@ -8605,7 +8602,6 @@ dependencies = [ "async-std", "async-trait", "bp-messages", - "env_logger 0.11.3", "finality-relay", "futures", "hex", @@ -10069,7 +10065,6 @@ dependencies = [ "bp-header-chain", "bp-runtime", "bp-test-utils", - "finality-grandpa", "frame-benchmarking", "frame-support", "frame-system", @@ -10081,13 +10076,13 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 14.0.0", - "sp-trie", ] [[package]] name = "pallet-bridge-messages" version = "0.7.0" dependencies = [ + "bp-header-chain", "bp-messages", "bp-runtime", "bp-test-utils", @@ -10095,13 +10090,15 @@ dependencies = [ "frame-support", "frame-system", "log", - "num-traits", "pallet-balances", + "pallet-bridge-grandpa", "parity-scale-codec", "scale-info", + "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0", + "sp-trie", ] [[package]] @@ -10124,7 +10121,6 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 14.0.0", - "sp-trie", ] [[package]] @@ -16205,13 +16201,10 @@ dependencies = [ "bp-runtime", "finality-relay", "frame-support", - "frame-system", "futures", "jsonrpsee", "log", "num-traits", - "pallet-balances", - "pallet-bridge-messages", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-utility", @@ -21388,9 +21381,7 @@ dependencies = [ "bp-polkadot-core", "bp-relayers", "bp-runtime", - "bridge-runtime-common", "equivocation-detector", - "finality-grandpa", "finality-relay", "frame-support", "frame-system", @@ -21410,9 +21401,11 @@ dependencies = [ "rbtag", "relay-substrate-client", "relay-utils", + "scale-info", "sp-consensus-grandpa", "sp-core", "sp-runtime", + "sp-trie", "structopt", "strum 0.26.2", "thiserror", diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index d69a064aab81a41c946b073f232ebb8c778b9609..36f27b6aa0358fcb8027bbfe6e571bc1a50962e6 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -12,14 +12,12 @@ workspace = true [dependencies] codec = { features = ["derive"], workspace = true } -hash-db = { workspace = true } log = { workspace = true } scale-info = { features = ["derive"], workspace = true } static_assertions = { optional = true, workspace = true, default-features = true } tuplex = { workspace = true } # Bridge dependencies - bp-header-chain = { workspace = true } bp-messages = { workspace = true } bp-parachains = { workspace = true } @@ -34,25 +32,23 @@ pallet-bridge-parachains = { workspace = true } pallet-bridge-relayers = { workspace = true } # Substrate dependencies - frame-support = { workspace = true } frame-system = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-utility = { workspace = true } -sp-api = { workspace = true } -sp-core = { workspace = true } sp-io = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } -sp-trie = { workspace = true } +sp-trie = { optional = true, workspace = true } # Polkadot dependencies xcm = { workspace = true } xcm-builder = { workspace = true } [dev-dependencies] -bp-test-utils = { workspace = true, default-features = true } -pallet-balances = { workspace = true, default-features = true } +bp-test-utils = { workspace = true } +pallet-balances = { workspace = true } +pallet-bridge-messages = { features = ["std", "test-helpers"], workspace = true } [features] default = ["std"] @@ -63,13 +59,14 @@ std = [ "bp-polkadot-core/std", "bp-relayers/std", "bp-runtime/std", + "bp-test-utils/std", "bp-xcm-bridge-hub-router/std", "bp-xcm-bridge-hub/std", "codec/std", "frame-support/std", "frame-system/std", - "hash-db/std", "log/std", + "pallet-balances/std", "pallet-bridge-grandpa/std", "pallet-bridge-messages/std", "pallet-bridge-parachains/std", @@ -77,8 +74,6 @@ std = [ "pallet-transaction-payment/std", "pallet-utility/std", "scale-info/std", - "sp-api/std", - "sp-core/std", "sp-io/std", "sp-runtime/std", "sp-std/std", @@ -88,15 +83,22 @@ std = [ "xcm/std", ] runtime-benchmarks = [ + "bp-runtime/test-helpers", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-bridge-grandpa/runtime-benchmarks", "pallet-bridge-messages/runtime-benchmarks", + "pallet-bridge-messages/test-helpers", "pallet-bridge-parachains/runtime-benchmarks", "pallet-bridge-relayers/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "sp-trie", "xcm-builder/runtime-benchmarks", ] integrity-test = ["static_assertions"] +test-helpers = [ + "bp-runtime/test-helpers", + "sp-trie", +] diff --git a/bridges/bin/runtime-common/src/extensions/priority_calculator.rs b/bridges/bin/runtime-common/src/extensions/priority_calculator.rs index 92810290f95e77a7fdc04cafaa1e6ab290e1661a..9f559dc13b64d3912f0d1679c21fa682034bdb8e 100644 --- a/bridges/bin/runtime-common/src/extensions/priority_calculator.rs +++ b/bridges/bin/runtime-common/src/extensions/priority_calculator.rs @@ -319,6 +319,7 @@ mod integrity_tests { pub mod per_message { use super::*; + use bp_messages::ChainWithMessages; use pallet_bridge_messages::WeightInfoExt; /// Ensures that the value of `PriorityBoostPerMessage` matches the value of @@ -339,7 +340,7 @@ mod integrity_tests { BalanceOf<Runtime>: Send + Sync + FixedPointOperand, { let maximal_messages_in_delivery_transaction = - Runtime::MaxUnconfirmedMessagesAtInboundLane::get(); + Runtime::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; super::ensure_priority_boost_is_sane::<PriorityBoostPerMessage, BalanceOf<Runtime>>( "PriorityBoostPerMessage", maximal_messages_in_delivery_transaction, diff --git a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs index 5aa7f1c095d540a4ee5050aeb7d694c98b744683..6ba3506377d0e602bf9ee706b13c248efd6afaca 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -22,9 +22,9 @@ use crate::messages_call_ext::{ CallHelper as MessagesCallHelper, CallInfo as MessagesCallInfo, MessagesCallSubType, }; -use bp_messages::{LaneId, MessageNonce}; +use bp_messages::{ChainWithMessages, LaneId, MessageNonce}; use bp_relayers::{ExplicitOrAccountParams, RewardsAccountOwner, RewardsAccountParams}; -use bp_runtime::{Parachain, RangeInclusiveExt, StaticStrProvider}; +use bp_runtime::{Chain, Parachain, RangeInclusiveExt, StaticStrProvider}; use codec::{Codec, Decode, Encode}; use frame_support::{ dispatch::{CallableCallFor, DispatchInfo, PostDispatchInfo}, @@ -293,7 +293,7 @@ pub trait RefundSignedExtension: <Self::Msgs as RefundableMessagesLaneId>::Id::get(), <Self::Runtime as MessagesConfig< <Self::Msgs as RefundableMessagesLaneId>::Instance, - >>::BridgedChainId::get(), + >>::BridgedChain::ID, if call_info.is_receive_messages_proof_call() { RewardsAccountOwner::ThisChain } else { @@ -406,8 +406,7 @@ pub trait RefundSignedExtension: // a quick check to avoid invalid high-priority transactions let max_unconfirmed_messages_in_confirmation_tx = <Self::Runtime as MessagesConfig< <Self::Msgs as RefundableMessagesLaneId>::Instance, - >>::MaxUnconfirmedMessagesAtInboundLane::get( - ); + >>::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; if bundled_messages > max_unconfirmed_messages_in_confirmation_tx { return None } @@ -935,9 +934,6 @@ where pub(crate) mod tests { use super::*; use crate::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - }, messages_call_ext::{ BaseMessagesProofInfo, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayerOccupation, @@ -946,8 +942,10 @@ pub(crate) mod tests { }; use bp_header_chain::StoredHeaderDataBuilder; use bp_messages::{ - DeliveredMessages, InboundLaneData, MessageNonce, MessagesOperatingMode, OutboundLaneData, - UnrewardedRelayer, UnrewardedRelayersState, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, DeliveredMessages, InboundLaneData, + MessageNonce, MessagesOperatingMode, OutboundLaneData, UnrewardedRelayer, + UnrewardedRelayersState, }; use bp_parachains::{BestParaHeadHash, ParaInfo}; use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId}; @@ -1123,7 +1121,7 @@ pub(crate) mod tests { ParaId(BridgedUnderlyingParachain::PARACHAIN_ID), [parachain_head_at_relay_header_number as u8; 32].into(), )], - parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, + parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() }, }) } @@ -1136,7 +1134,7 @@ pub(crate) mod tests { ParaId(BridgedUnderlyingParachain::PARACHAIN_ID), [parachain_head_at_relay_header_number as u8; 32].into(), )], - parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, + parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() }, is_free_execution_expected: false, }) } @@ -1144,9 +1142,9 @@ pub(crate) mod tests { fn message_delivery_call(best_message: MessageNonce) -> RuntimeCall { RuntimeCall::BridgeMessages(MessagesCall::receive_messages_proof { relayer_id_at_bridged_chain: relayer_account_at_bridged_chain(), - proof: FromBridgedChainMessagesProof { + proof: Box::new(FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage_proof: vec![], + storage_proof: Default::default(), lane: TestLaneId::get(), nonces_start: pallet_bridge_messages::InboundLanes::<TestRuntime>::get( TEST_LANE_ID, @@ -1154,7 +1152,7 @@ pub(crate) mod tests { .last_delivered_nonce() + 1, nonces_end: best_message, - }, + }), messages_count: 1, dispatch_weight: Weight::zero(), }) @@ -1164,7 +1162,7 @@ pub(crate) mod tests { RuntimeCall::BridgeMessages(MessagesCall::receive_messages_delivery_proof { proof: FromBridgedChainMessagesDeliveryProof { bridged_header_hash: Default::default(), - storage_proof: vec![], + storage_proof: Default::default(), lane: TestLaneId::get(), }, relayers_state: UnrewardedRelayersState { @@ -1327,8 +1325,10 @@ pub(crate) mod tests { best_stored_nonce: 100, }, unrewarded_relayers: UnrewardedRelayerOccupation { - free_relayer_slots: MaxUnrewardedRelayerEntriesAtInboundLane::get(), - free_message_slots: MaxUnconfirmedMessagesAtInboundLane::get(), + free_relayer_slots: + BridgedUnderlyingChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + free_message_slots: + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, }, }), ), @@ -1397,8 +1397,10 @@ pub(crate) mod tests { best_stored_nonce: 100, }, unrewarded_relayers: UnrewardedRelayerOccupation { - free_relayer_slots: MaxUnrewardedRelayerEntriesAtInboundLane::get(), - free_message_slots: MaxUnconfirmedMessagesAtInboundLane::get(), + free_relayer_slots: + BridgedUnderlyingChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + free_message_slots: + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, }, }), ), @@ -1459,8 +1461,10 @@ pub(crate) mod tests { best_stored_nonce: 100, }, unrewarded_relayers: UnrewardedRelayerOccupation { - free_relayer_slots: MaxUnrewardedRelayerEntriesAtInboundLane::get(), - free_message_slots: MaxUnconfirmedMessagesAtInboundLane::get(), + free_relayer_slots: + BridgedUnderlyingChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + free_message_slots: + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, }, }), ), @@ -1499,8 +1503,10 @@ pub(crate) mod tests { best_stored_nonce: 100, }, unrewarded_relayers: UnrewardedRelayerOccupation { - free_relayer_slots: MaxUnrewardedRelayerEntriesAtInboundLane::get(), - free_message_slots: MaxUnconfirmedMessagesAtInboundLane::get(), + free_relayer_slots: + BridgedUnderlyingChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + free_message_slots: + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, }, }, )), @@ -1735,14 +1741,16 @@ pub(crate) mod tests { let fns = [run_validate, run_grandpa_validate, run_messages_validate]; for f in fns { - let priority_of_max_messages_delivery = - f(message_delivery_call(100 + MaxUnconfirmedMessagesAtInboundLane::get())) - .unwrap() - .priority; - let priority_of_more_than_max_messages_delivery = - f(message_delivery_call(100 + MaxUnconfirmedMessagesAtInboundLane::get() + 1)) - .unwrap() - .priority; + let priority_of_max_messages_delivery = f(message_delivery_call( + 100 + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + )) + .unwrap() + .priority; + let priority_of_more_than_max_messages_delivery = f(message_delivery_call( + 100 + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX + 1, + )) + .unwrap() + .priority; assert!( priority_of_max_messages_delivery > priority_of_more_than_max_messages_delivery, @@ -2103,7 +2111,7 @@ pub(crate) mod tests { [1u8; 32].into(), ), ], - parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, + parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() }, }), message_delivery_call(200), ], @@ -2865,7 +2873,8 @@ pub(crate) mod tests { #[test] fn does_not_panic_on_boosting_priority_of_empty_message_delivery_transaction() { run_test(|| { - let best_delivered_message = MaxUnconfirmedMessagesAtInboundLane::get(); + let best_delivered_message = + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; initialize_environment(100, 100, best_delivered_message); // register relayer so it gets priority boost diff --git a/bridges/bin/runtime-common/src/integrity.rs b/bridges/bin/runtime-common/src/integrity.rs index d3827a14dd6cc24e088a8d05d26aba9d769eb213..f661db8a22057ecf6c8b217336e5a98660344cb2 100644 --- a/bridges/bin/runtime-common/src/integrity.rs +++ b/bridges/bin/runtime-common/src/integrity.rs @@ -19,10 +19,9 @@ //! Most of the tests in this module assume that the bridge is using standard (see `crate::messages` //! module for details) configuration. -use crate::{messages, messages::MessageBridge}; - -use bp_messages::{InboundLaneData, MessageNonce}; -use bp_runtime::{Chain, ChainId}; +use bp_header_chain::ChainWithGrandpa; +use bp_messages::{ChainWithMessages, InboundLaneData, MessageNonce}; +use bp_runtime::Chain; use codec::Encode; use frame_support::{storage::generator::StorageValue, traits::Get, weights::Weight}; use frame_system::limits; @@ -50,23 +49,6 @@ macro_rules! assert_chain_types( } ); -/// Macro that ensures that the bridge GRANDPA pallet is configured properly to bridge with given -/// chain. -#[macro_export] -macro_rules! assert_bridge_grandpa_pallet_types( - ( runtime: $r:path, with_bridged_chain_grandpa_instance: $i:path, bridged_chain: $bridged:path ) => { - { - // if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard - // configuration is used), or something has broke existing configuration (meaning that all bridged chains - // and relays will stop functioning) - use pallet_bridge_grandpa::Config as GrandpaConfig; - use static_assertions::assert_type_eq_all; - - assert_type_eq_all!(<$r as GrandpaConfig<$i>>::BridgedChain, $bridged); - } - } -); - /// Macro that ensures that the bridge messages pallet is configured properly to bridge using given /// configuration. #[macro_export] @@ -74,32 +56,30 @@ macro_rules! assert_bridge_messages_pallet_types( ( runtime: $r:path, with_bridged_chain_messages_instance: $i:path, - bridge: $bridge:path + this_chain: $this:path, + bridged_chain: $bridged:path, ) => { { // if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard // configuration is used), or something has broke existing configuration (meaning that all bridged chains // and relays will stop functioning) - use $crate::messages::{ - source::{FromThisChainMessagePayload, TargetHeaderChainAdapter}, - target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, - AccountIdOf, BalanceOf, BridgedChain, ThisChain, - }; + use $crate::messages_xcm_extension::XcmAsPlainPayload; + use bp_messages::ChainWithMessages; + use bp_runtime::Chain; use pallet_bridge_messages::Config as MessagesConfig; use static_assertions::assert_type_eq_all; - assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, FromThisChainMessagePayload); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::ThisChain, $this); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::BridgedChain, $bridged); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf<BridgedChain<$bridge>>); - - assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, TargetHeaderChainAdapter<$bridge>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::SourceHeaderChain, SourceHeaderChainAdapter<$bridge>); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, XcmAsPlainPayload); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, XcmAsPlainPayload); } } ); /// Macro that combines four other macro calls - `assert_chain_types`, `assert_bridge_types`, -/// `assert_bridge_grandpa_pallet_types` and `assert_bridge_messages_pallet_types`. It may be used +/// and `assert_bridge_messages_pallet_types`. It may be used /// at the chain that is implementing complete standard messages bridge (i.e. with bridge GRANDPA /// and messages pallets deployed). #[macro_export] @@ -108,20 +88,15 @@ macro_rules! assert_complete_bridge_types( runtime: $r:path, with_bridged_chain_grandpa_instance: $gi:path, with_bridged_chain_messages_instance: $mi:path, - bridge: $bridge:path, this_chain: $this:path, bridged_chain: $bridged:path, ) => { $crate::assert_chain_types!(runtime: $r, this_chain: $this); - $crate::assert_bridge_grandpa_pallet_types!( - runtime: $r, - with_bridged_chain_grandpa_instance: $gi, - bridged_chain: $bridged - ); $crate::assert_bridge_messages_pallet_types!( runtime: $r, with_bridged_chain_messages_instance: $mi, - bridge: $bridge + this_chain: $this, + bridged_chain: $bridged, ); } ); @@ -184,20 +159,8 @@ where ); } -/// Parameters for asserting messages pallet constants. -#[derive(Debug)] -pub struct AssertBridgeMessagesPalletConstants { - /// Maximal number of unrewarded relayer entries in a confirmation transaction at the bridged - /// chain. - pub max_unrewarded_relayers_in_bridged_confirmation_tx: MessageNonce, - /// Maximal number of unconfirmed messages in a confirmation transaction at the bridged chain. - pub max_unconfirmed_messages_in_bridged_confirmation_tx: MessageNonce, - /// Identifier of the bridged chain. - pub bridged_chain_id: ChainId, -} - /// Test that the constants, used in messages pallet configuration are valid. -pub fn assert_bridge_messages_pallet_constants<R, MI>(params: AssertBridgeMessagesPalletConstants) +pub fn assert_bridge_messages_pallet_constants<R, MI>() where R: pallet_bridge_messages::Config<MI>, MI: 'static, @@ -207,27 +170,22 @@ where "ActiveOutboundLanes ({:?}) must not be empty", R::ActiveOutboundLanes::get(), ); + assert!( - R::MaxUnrewardedRelayerEntriesAtInboundLane::get() <= params.max_unrewarded_relayers_in_bridged_confirmation_tx, - "MaxUnrewardedRelayerEntriesAtInboundLane ({}) must be <= than the hardcoded value for bridged chain: {}", - R::MaxUnrewardedRelayerEntriesAtInboundLane::get(), - params.max_unrewarded_relayers_in_bridged_confirmation_tx, - ); - assert!( - R::MaxUnconfirmedMessagesAtInboundLane::get() <= params.max_unconfirmed_messages_in_bridged_confirmation_tx, - "MaxUnrewardedRelayerEntriesAtInboundLane ({}) must be <= than the hardcoded value for bridged chain: {}", - R::MaxUnconfirmedMessagesAtInboundLane::get(), - params.max_unconfirmed_messages_in_bridged_confirmation_tx, + pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX + <= pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + "MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX ({}) of {:?} is larger than \ + its MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX ({}). This makes \ + no sense", + pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + pallet_bridge_messages::BridgedChainOf::<R, MI>::ID, + pallet_bridge_messages::BridgedChainOf::<R, MI>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, ); - assert_eq!(R::BridgedChainId::get(), params.bridged_chain_id); } /// Parameters for asserting bridge pallet names. #[derive(Debug)] pub struct AssertBridgePalletNames<'a> { - /// Name of the messages pallet, deployed at the bridged chain and used to bridge with this - /// chain. - pub with_this_chain_messages_pallet_name: &'a str, /// Name of the GRANDPA pallet, deployed at this chain and used to bridge with the bridged /// chain. pub with_bridged_chain_grandpa_pallet_name: &'a str, @@ -238,18 +196,22 @@ pub struct AssertBridgePalletNames<'a> { /// Tests that bridge pallet names used in `construct_runtime!()` macro call are matching constants /// from chain primitives crates. -pub fn assert_bridge_pallet_names<B, R, GI, MI>(params: AssertBridgePalletNames) +fn assert_bridge_pallet_names<R, GI, MI>(params: AssertBridgePalletNames) where - B: MessageBridge, R: pallet_bridge_grandpa::Config<GI> + pallet_bridge_messages::Config<MI>, GI: 'static, MI: 'static, { - assert_eq!(B::BRIDGED_MESSAGES_PALLET_NAME, params.with_this_chain_messages_pallet_name); + // check that the bridge GRANDPA pallet has required name assert_eq!( pallet_bridge_grandpa::PalletOwner::<R, GI>::storage_value_final_key().to_vec(), - bp_runtime::storage_value_key(params.with_bridged_chain_grandpa_pallet_name, "PalletOwner",).0, + bp_runtime::storage_value_key( + params.with_bridged_chain_grandpa_pallet_name, + "PalletOwner", + ).0, ); + + // check that the bridge messages pallet has required name assert_eq!( pallet_bridge_messages::PalletOwner::<R, MI>::storage_value_final_key().to_vec(), bp_runtime::storage_value_key( @@ -262,35 +224,58 @@ where /// Parameters for asserting complete standard messages bridge. #[derive(Debug)] -pub struct AssertCompleteBridgeConstants<'a> { +pub struct AssertCompleteBridgeConstants { /// Parameters to assert this chain constants. pub this_chain_constants: AssertChainConstants, - /// Parameters to assert messages pallet constants. - pub messages_pallet_constants: AssertBridgeMessagesPalletConstants, - /// Parameters to assert pallet names constants. - pub pallet_names: AssertBridgePalletNames<'a>, } -/// All bridge-related constants tests for the complete standard messages bridge (i.e. with bridge -/// GRANDPA and messages pallets deployed). -pub fn assert_complete_bridge_constants<R, GI, MI, B>(params: AssertCompleteBridgeConstants) -where +/// All bridge-related constants tests for the complete standard relay-chain messages bridge +/// (i.e. with bridge GRANDPA and messages pallets deployed). +pub fn assert_complete_with_relay_chain_bridge_constants<R, GI, MI>( + params: AssertCompleteBridgeConstants, +) where + R: frame_system::Config + + pallet_bridge_grandpa::Config<GI> + + pallet_bridge_messages::Config<MI>, + GI: 'static, + MI: 'static, +{ + assert_chain_constants::<R>(params.this_chain_constants); + assert_bridge_grandpa_pallet_constants::<R, GI>(); + assert_bridge_messages_pallet_constants::<R, MI>(); + assert_bridge_pallet_names::<R, GI, MI>(AssertBridgePalletNames { + with_bridged_chain_grandpa_pallet_name: + <R as pallet_bridge_grandpa::Config<GI>>::BridgedChain::WITH_CHAIN_GRANDPA_PALLET_NAME, + with_bridged_chain_messages_pallet_name: + <R as pallet_bridge_messages::Config<MI>>::BridgedChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + }); +} + +/// All bridge-related constants tests for the complete standard parachain messages bridge +/// (i.e. with bridge GRANDPA, parachains and messages pallets deployed). +pub fn assert_complete_with_parachain_bridge_constants<R, GI, MI, RelayChain>( + params: AssertCompleteBridgeConstants, +) where R: frame_system::Config + pallet_bridge_grandpa::Config<GI> + pallet_bridge_messages::Config<MI>, GI: 'static, MI: 'static, - B: MessageBridge, + RelayChain: ChainWithGrandpa, { assert_chain_constants::<R>(params.this_chain_constants); assert_bridge_grandpa_pallet_constants::<R, GI>(); - assert_bridge_messages_pallet_constants::<R, MI>(params.messages_pallet_constants); - assert_bridge_pallet_names::<B, R, GI, MI>(params.pallet_names); + assert_bridge_messages_pallet_constants::<R, MI>(); + assert_bridge_pallet_names::<R, GI, MI>(AssertBridgePalletNames { + with_bridged_chain_grandpa_pallet_name: RelayChain::WITH_CHAIN_GRANDPA_PALLET_NAME, + with_bridged_chain_messages_pallet_name: + <R as pallet_bridge_messages::Config<MI>>::BridgedChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + }); } /// Check that the message lane weights are correct. pub fn check_message_lane_weights< - C: Chain, + C: ChainWithMessages, T: frame_system::Config + pallet_bridge_messages::Config<MessagesPalletInstance>, MessagesPalletInstance: 'static, >( @@ -308,14 +293,20 @@ pub fn check_message_lane_weights< // check basic weight assumptions pallet_bridge_messages::ensure_weights_are_correct::<Weights<T, MessagesPalletInstance>>(); + // check that the maximal message dispatch weight is below hardcoded limit + pallet_bridge_messages::ensure_maximal_message_dispatch::<Weights<T, MessagesPalletInstance>>( + C::maximal_incoming_message_size(), + C::maximal_incoming_message_dispatch_weight(), + ); + // check that weights allow us to receive messages - let max_incoming_message_proof_size = bridged_chain_extra_storage_proof_size - .saturating_add(messages::target::maximal_incoming_message_size(C::max_extrinsic_size())); + let max_incoming_message_proof_size = + bridged_chain_extra_storage_proof_size.saturating_add(C::maximal_incoming_message_size()); pallet_bridge_messages::ensure_able_to_receive_message::<Weights<T, MessagesPalletInstance>>( C::max_extrinsic_size(), C::max_extrinsic_weight(), max_incoming_message_proof_size, - messages::target::maximal_incoming_message_dispatch_weight(C::max_extrinsic_weight()), + C::maximal_incoming_message_dispatch_weight(), ); // check that weights allow us to receive delivery confirmations diff --git a/bridges/bin/runtime-common/src/lib.rs b/bridges/bin/runtime-common/src/lib.rs index 5679acd6006ccb8540f940f0f90363f902d643f7..b65bb6041d5610ce2bdfb63f923f3f24b21dcd7f 100644 --- a/bridges/bin/runtime-common/src/lib.rs +++ b/bridges/bin/runtime-common/src/lib.rs @@ -20,11 +20,10 @@ #![cfg_attr(not(feature = "std"), no_std)] pub mod extensions; -pub mod messages; + pub mod messages_api; pub mod messages_benchmarking; pub mod messages_call_ext; -pub mod messages_generation; pub mod messages_xcm_extension; pub mod parachains_benchmarking; diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs deleted file mode 100644 index 03801d5279d0a8453542336d8089f5c887a3d005..0000000000000000000000000000000000000000 --- a/bridges/bin/runtime-common/src/messages.rs +++ /dev/null @@ -1,704 +0,0 @@ -// Copyright (C) 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 <http://www.gnu.org/licenses/>. - -//! Types that allow runtime to act as a source/target endpoint of message lanes. -//! -//! Messages are assumed to be encoded `Call`s of the target chain. Call-dispatch -//! pallet is used to dispatch incoming messages. Message identified by a tuple -//! of to elements - message lane id and message nonce. - -pub use bp_runtime::{RangeInclusiveExt, UnderlyingChainOf, UnderlyingChainProvider}; - -use bp_header_chain::HeaderChain; -use bp_messages::{ - source_chain::TargetHeaderChain, - target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, - InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, - VerificationError, -}; -use bp_runtime::{Chain, RawStorageProof, Size, StorageProofChecker}; -use codec::{Decode, Encode}; -use frame_support::{traits::Get, weights::Weight}; -use hash_db::Hasher; -use scale_info::TypeInfo; -use sp_runtime::RuntimeDebug; -use sp_std::{marker::PhantomData, vec::Vec}; - -/// Bidirectional message bridge. -pub trait MessageBridge { - /// Name of the paired messages pallet instance at the Bridged chain. - /// - /// Should be the name that is used in the `construct_runtime!()` macro. - const BRIDGED_MESSAGES_PALLET_NAME: &'static str; - - /// This chain in context of message bridge. - type ThisChain: ThisChainWithMessages; - /// Bridged chain in context of message bridge. - type BridgedChain: BridgedChainWithMessages; - /// Bridged header chain. - type BridgedHeaderChain: HeaderChain<UnderlyingChainOf<Self::BridgedChain>>; -} - -/// This chain that has `pallet-bridge-messages` module. -pub trait ThisChainWithMessages: UnderlyingChainProvider { - /// Call origin on the chain. - type RuntimeOrigin; -} - -/// Bridged chain that has `pallet-bridge-messages` module. -pub trait BridgedChainWithMessages: UnderlyingChainProvider {} - -/// This chain in context of message bridge. -pub type ThisChain<B> = <B as MessageBridge>::ThisChain; -/// Bridged chain in context of message bridge. -pub type BridgedChain<B> = <B as MessageBridge>::BridgedChain; -/// Hash used on the chain. -pub type HashOf<C> = bp_runtime::HashOf<<C as UnderlyingChainProvider>::Chain>; -/// Hasher used on the chain. -pub type HasherOf<C> = bp_runtime::HasherOf<UnderlyingChainOf<C>>; -/// Account id used on the chain. -pub type AccountIdOf<C> = bp_runtime::AccountIdOf<UnderlyingChainOf<C>>; -/// Type of balances that is used on the chain. -pub type BalanceOf<C> = bp_runtime::BalanceOf<UnderlyingChainOf<C>>; - -/// Sub-module that is declaring types required for processing This -> Bridged chain messages. -pub mod source { - use super::*; - - /// Message payload for This -> Bridged chain messages. - pub type FromThisChainMessagePayload = crate::messages_xcm_extension::XcmAsPlainPayload; - - /// Maximal size of outbound message payload. - pub struct FromThisChainMaximalOutboundPayloadSize<B>(PhantomData<B>); - - impl<B: MessageBridge> Get<u32> for FromThisChainMaximalOutboundPayloadSize<B> { - fn get() -> u32 { - maximal_message_size::<B>() - } - } - - /// Messages delivery proof from bridged chain: - /// - /// - hash of finalized header; - /// - storage proof of inbound lane state; - /// - lane id. - #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] - pub struct FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash> { - /// Hash of the bridge header the proof is for. - pub bridged_header_hash: BridgedHeaderHash, - /// Storage trie proof generated for [`Self::bridged_header_hash`]. - pub storage_proof: RawStorageProof, - /// Lane id of which messages were delivered and the proof is for. - pub lane: LaneId, - } - - impl<BridgedHeaderHash> Size for FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash> { - fn size(&self) -> u32 { - u32::try_from( - self.storage_proof - .iter() - .fold(0usize, |sum, node| sum.saturating_add(node.len())), - ) - .unwrap_or(u32::MAX) - } - } - - /// 'Parsed' message delivery proof - inbound lane id and its state. - pub type ParsedMessagesDeliveryProofFromBridgedChain<B> = - (LaneId, InboundLaneData<AccountIdOf<ThisChain<B>>>); - - /// Return maximal message size of This -> Bridged chain message. - pub fn maximal_message_size<B: MessageBridge>() -> u32 { - super::target::maximal_incoming_message_size( - UnderlyingChainOf::<BridgedChain<B>>::max_extrinsic_size(), - ) - } - - /// `TargetHeaderChain` implementation that is using default types and perform default checks. - pub struct TargetHeaderChainAdapter<B>(PhantomData<B>); - - impl<B: MessageBridge> TargetHeaderChain<FromThisChainMessagePayload, AccountIdOf<ThisChain<B>>> - for TargetHeaderChainAdapter<B> - { - type MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain<B>>>; - - fn verify_message(payload: &FromThisChainMessagePayload) -> Result<(), VerificationError> { - verify_chain_message::<B>(payload) - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData<AccountIdOf<ThisChain<B>>>), VerificationError> { - verify_messages_delivery_proof::<B>(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 - /// may be 'mined' by the target chain. - pub fn verify_chain_message<B: MessageBridge>( - payload: &FromThisChainMessagePayload, - ) -> Result<(), VerificationError> { - // IMPORTANT: any error that is returned here is fatal for the bridge, because - // this code is executed at the bridge hub and message sender actually lives - // at some sibling parachain. So we are failing **after** the message has been - // sent and we can't report it back to sender (unless error report mechanism is - // embedded into message and its dispatcher). - - // apart from maximal message size check (see below), we should also check the message - // dispatch weight here. But we assume that the bridged chain will just push the message - // to some queue (XCMP, UMP, DMP), so the weight is constant and fits the block. - - // The maximal size of extrinsic at Substrate-based chain depends on the - // `frame_system::Config::MaximumBlockLength` and - // `frame_system::Config::AvailableBlockRatio` constants. This check is here to be sure that - // the lane won't stuck because message is too large to fit into delivery transaction. - // - // **IMPORTANT NOTE**: the delivery transaction contains storage proof of the message, not - // the message itself. The proof is always larger than the message. But unless chain state - // is enormously large, it should be several dozens/hundreds of bytes. The delivery - // transaction also contains signatures and signed extensions. Because of this, we reserve - // 1/3 of the the maximal extrinsic size for this data. - if payload.len() > maximal_message_size::<B>() as usize { - return Err(VerificationError::MessageTooLarge) - } - - Ok(()) - } - - /// Verify proof of This -> Bridged chain messages delivery. - /// - /// This function is used when Bridged chain is directly using GRANDPA finality. For Bridged - /// parachains, please use the `verify_messages_delivery_proof_from_parachain`. - pub fn verify_messages_delivery_proof<B: MessageBridge>( - proof: FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain<B>>>, - ) -> Result<ParsedMessagesDeliveryProofFromBridgedChain<B>, VerificationError> { - let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = - proof; - let mut storage = - B::BridgedHeaderChain::storage_proof_checker(bridged_header_hash, storage_proof) - .map_err(VerificationError::HeaderChain)?; - // Messages delivery proof is just proof of single storage key read => any error - // is fatal. - let storage_inbound_lane_data_key = bp_messages::storage_keys::inbound_lane_data_key( - B::BRIDGED_MESSAGES_PALLET_NAME, - &lane, - ); - let inbound_lane_data = storage - .read_and_decode_mandatory_value(storage_inbound_lane_data_key.0.as_ref()) - .map_err(VerificationError::InboundLaneStorage)?; - - // check that the storage proof doesn't have any untouched trie nodes - storage.ensure_no_unused_nodes().map_err(VerificationError::StorageProof)?; - - Ok((lane, inbound_lane_data)) - } -} - -/// Sub-module that is declaring types required for processing Bridged -> This chain messages. -pub mod target { - use super::*; - - /// Decoded Bridged -> This message payload. - pub type FromBridgedChainMessagePayload = crate::messages_xcm_extension::XcmAsPlainPayload; - - /// Messages proof from bridged chain: - /// - /// - hash of finalized header; - /// - storage proof of messages and (optionally) outbound lane state; - /// - lane id; - /// - nonces (inclusive range) of messages which are included in this proof. - #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] - pub struct FromBridgedChainMessagesProof<BridgedHeaderHash> { - /// Hash of the finalized bridged header the proof is for. - pub bridged_header_hash: BridgedHeaderHash, - /// A storage trie proof of messages being delivered. - pub storage_proof: RawStorageProof, - /// Messages in this proof are sent over this lane. - pub lane: LaneId, - /// Nonce of the first message being delivered. - pub nonces_start: MessageNonce, - /// Nonce of the last message being delivered. - pub nonces_end: MessageNonce, - } - - impl<BridgedHeaderHash> Size for FromBridgedChainMessagesProof<BridgedHeaderHash> { - fn size(&self) -> u32 { - u32::try_from( - self.storage_proof - .iter() - .fold(0usize, |sum, node| sum.saturating_add(node.len())), - ) - .unwrap_or(u32::MAX) - } - } - - /// Return maximal dispatch weight of the message we're able to receive. - pub fn maximal_incoming_message_dispatch_weight(maximal_extrinsic_weight: Weight) -> Weight { - maximal_extrinsic_weight / 2 - } - - /// Return maximal message size given maximal extrinsic size. - pub fn maximal_incoming_message_size(maximal_extrinsic_size: u32) -> u32 { - maximal_extrinsic_size / 3 * 2 - } - - /// `SourceHeaderChain` implementation that is using default types and perform default checks. - pub struct SourceHeaderChainAdapter<B>(PhantomData<B>); - - impl<B: MessageBridge> SourceHeaderChain for SourceHeaderChainAdapter<B> { - type MessagesProof = FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>; - - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result<ProvedMessages<Message>, VerificationError> { - verify_messages_proof::<B>(proof, messages_count) - } - } - - /// Verify proof of Bridged -> This chain messages. - /// - /// This function is used when Bridged chain is directly using GRANDPA finality. For Bridged - /// parachains, please use the `verify_messages_proof_from_parachain`. - /// - /// The `messages_count` argument verification (sane limits) is supposed to be made - /// outside of this function. This function only verifies that the proof declares exactly - /// `messages_count` messages. - pub fn verify_messages_proof<B: MessageBridge>( - proof: FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>, - messages_count: u32, - ) -> Result<ProvedMessages<Message>, VerificationError> { - let FromBridgedChainMessagesProof { - bridged_header_hash, - storage_proof, - lane, - nonces_start, - nonces_end, - } = proof; - let storage = - B::BridgedHeaderChain::storage_proof_checker(bridged_header_hash, storage_proof) - .map_err(VerificationError::HeaderChain)?; - let mut parser = StorageProofCheckerAdapter::<_, B> { storage, _dummy: Default::default() }; - let nonces_range = nonces_start..=nonces_end; - - // receiving proofs where end < begin is ok (if proof includes outbound lane state) - let messages_in_the_proof = nonces_range.checked_len().unwrap_or(0); - if messages_in_the_proof != MessageNonce::from(messages_count) { - return Err(VerificationError::MessagesCountMismatch) - } - - // Read messages first. All messages that are claimed to be in the proof must - // be in the proof. So any error in `read_value`, or even missing value is fatal. - // - // Mind that we allow proofs with no messages if outbound lane state is proved. - let mut messages = Vec::with_capacity(messages_in_the_proof as _); - for nonce in nonces_range { - let message_key = MessageKey { lane_id: lane, nonce }; - let message_payload = parser.read_and_decode_message_payload(&message_key)?; - messages.push(Message { key: message_key, payload: message_payload }); - } - - // Now let's check if proof contains outbound lane state proof. It is optional, so - // we simply ignore `read_value` errors and missing value. - let proved_lane_messages = ProvedLaneMessages { - lane_state: parser.read_and_decode_outbound_lane_data(&lane)?, - messages, - }; - - // Now we may actually check if the proof is empty or not. - if proved_lane_messages.lane_state.is_none() && proved_lane_messages.messages.is_empty() { - return Err(VerificationError::EmptyMessageProof) - } - - // check that the storage proof doesn't have any untouched trie nodes - parser - .storage - .ensure_no_unused_nodes() - .map_err(VerificationError::StorageProof)?; - - // We only support single lane messages in this generated_schema - let mut proved_messages = ProvedMessages::new(); - proved_messages.insert(lane, proved_lane_messages); - - Ok(proved_messages) - } - - struct StorageProofCheckerAdapter<H: Hasher, B> { - storage: StorageProofChecker<H>, - _dummy: sp_std::marker::PhantomData<B>, - } - - impl<H: Hasher, B: MessageBridge> StorageProofCheckerAdapter<H, B> { - fn read_and_decode_outbound_lane_data( - &mut self, - lane_id: &LaneId, - ) -> Result<Option<OutboundLaneData>, VerificationError> { - let storage_outbound_lane_data_key = bp_messages::storage_keys::outbound_lane_data_key( - B::BRIDGED_MESSAGES_PALLET_NAME, - lane_id, - ); - - self.storage - .read_and_decode_opt_value(storage_outbound_lane_data_key.0.as_ref()) - .map_err(VerificationError::OutboundLaneStorage) - } - - fn read_and_decode_message_payload( - &mut self, - message_key: &MessageKey, - ) -> Result<MessagePayload, VerificationError> { - let storage_message_key = bp_messages::storage_keys::message_key( - B::BRIDGED_MESSAGES_PALLET_NAME, - &message_key.lane_id, - message_key.nonce, - ); - self.storage - .read_and_decode_mandatory_value(storage_message_key.0.as_ref()) - .map_err(VerificationError::MessageStorage) - } - } -} - -/// The `BridgeMessagesCall` used by a chain. -pub type BridgeMessagesCallOf<C> = bp_messages::BridgeMessagesCall< - bp_runtime::AccountIdOf<C>, - target::FromBridgedChainMessagesProof<bp_runtime::HashOf<C>>, - source::FromBridgedChainMessagesDeliveryProof<bp_runtime::HashOf<C>>, ->; - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - messages_generation::{ - encode_all_messages, encode_lane_data, prepare_messages_storage_proof, - }, - mock::*, - }; - use bp_header_chain::{HeaderChainError, StoredHeaderDataBuilder}; - use bp_runtime::{HeaderId, StorageProofError}; - use codec::Encode; - use sp_core::H256; - use sp_runtime::traits::Header as _; - use sp_trie::accessed_nodes_tracker::Error as AccessedNodesTrackerError; - - #[test] - fn verify_chain_message_rejects_message_with_too_large_declared_weight() { - assert!(source::verify_chain_message::<OnThisChainBridge>(&vec![ - 42; - BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT - - 1 - ]) - .is_err()); - } - - #[test] - fn verify_chain_message_rejects_message_too_large_message() { - assert!(source::verify_chain_message::<OnThisChainBridge>(&vec![ - 0; - source::maximal_message_size::<OnThisChainBridge>() - as usize + 1 - ],) - .is_err()); - } - - #[test] - fn verify_chain_message_accepts_maximal_message() { - assert_eq!( - source::verify_chain_message::<OnThisChainBridge>(&vec![ - 0; - source::maximal_message_size::<OnThisChainBridge>() - as _ - ],), - Ok(()), - ); - } - - fn using_messages_proof<R>( - nonces_end: MessageNonce, - outbound_lane_data: Option<OutboundLaneData>, - encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option<Vec<u8>>, - encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec<u8>, - test: impl Fn(target::FromBridgedChainMessagesProof<H256>) -> R, - ) -> R { - let (state_root, storage_proof) = prepare_messages_storage_proof::<OnThisChainBridge>( - TEST_LANE_ID, - 1..=nonces_end, - outbound_lane_data, - bp_runtime::StorageProofSize::Minimal(0), - vec![42], - encode_message, - encode_outbound_lane_data, - ); - - 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(); - - pallet_bridge_grandpa::BestFinalized::<TestRuntime>::put(HeaderId( - 0, - bridged_header_hash, - )); - pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert( - bridged_header_hash, - bridged_header.build(), - ); - test(target::FromBridgedChainMessagesProof { - bridged_header_hash, - storage_proof, - lane: TEST_LANE_ID, - nonces_start: 1, - nonces_end, - }) - }) - } - - #[test] - fn messages_proof_is_rejected_if_declared_less_than_actual_number_of_messages() { - assert_eq!( - using_messages_proof(10, None, encode_all_messages, encode_lane_data, |proof| { - target::verify_messages_proof::<OnThisChainBridge>(proof, 5) - }), - Err(VerificationError::MessagesCountMismatch), - ); - } - - #[test] - fn messages_proof_is_rejected_if_declared_more_than_actual_number_of_messages() { - assert_eq!( - using_messages_proof(10, None, encode_all_messages, encode_lane_data, |proof| { - target::verify_messages_proof::<OnThisChainBridge>(proof, 15) - }), - Err(VerificationError::MessagesCountMismatch), - ); - } - - #[test] - 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| { - let bridged_header_hash = - pallet_bridge_grandpa::BestFinalized::<TestRuntime>::get().unwrap().1; - pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::remove(bridged_header_hash); - target::verify_messages_proof::<OnThisChainBridge>(proof, 10) - }), - Err(VerificationError::HeaderChain(HeaderChainError::UnknownHeader)), - ); - } - - #[test] - fn message_proof_is_rejected_if_header_state_root_mismatches() { - assert_eq!( - using_messages_proof(10, None, encode_all_messages, encode_lane_data, |proof| { - let bridged_header_hash = - pallet_bridge_grandpa::BestFinalized::<TestRuntime>::get().unwrap().1; - pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert( - bridged_header_hash, - BridgedChainHeader::new( - 0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ) - .build(), - ); - target::verify_messages_proof::<OnThisChainBridge>(proof, 10) - }), - Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( - StorageProofError::StorageRootMismatch - ))), - ); - } - - #[test] - fn message_proof_is_rejected_if_it_has_duplicate_trie_nodes() { - assert_eq!( - using_messages_proof(10, None, encode_all_messages, encode_lane_data, |mut proof| { - let node = proof.storage_proof.pop().unwrap(); - proof.storage_proof.push(node.clone()); - proof.storage_proof.push(node); - target::verify_messages_proof::<OnThisChainBridge>(proof, 10) - },), - Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( - StorageProofError::StorageProof(sp_trie::StorageProofError::DuplicateNodes.into()) - ))), - ); - } - - #[test] - fn message_proof_is_rejected_if_it_has_unused_trie_nodes() { - assert_eq!( - using_messages_proof(10, None, encode_all_messages, encode_lane_data, |mut proof| { - proof.storage_proof.push(vec![42]); - target::verify_messages_proof::<OnThisChainBridge>(proof, 10) - },), - Err(VerificationError::StorageProof(StorageProofError::AccessedNodesTracker( - AccessedNodesTrackerError::UnusedNodes.into() - ))), - ); - } - - #[test] - fn message_proof_is_rejected_if_required_message_is_missing() { - matches!( - using_messages_proof( - 10, - None, - |n, m| if n != 5 { Some(m.encode()) } else { None }, - encode_lane_data, - |proof| target::verify_messages_proof::<OnThisChainBridge>(proof, 10) - ), - Err(VerificationError::MessageStorage(StorageProofError::StorageValueEmpty)), - ); - } - - #[test] - fn message_proof_is_rejected_if_message_decode_fails() { - matches!( - using_messages_proof( - 10, - None, - |n, m| { - let mut m = m.encode(); - if n == 5 { - m = vec![42] - } - Some(m) - }, - encode_lane_data, - |proof| target::verify_messages_proof::<OnThisChainBridge>(proof, 10), - ), - Err(VerificationError::MessageStorage(StorageProofError::StorageValueDecodeFailed(_))), - ); - } - - #[test] - fn message_proof_is_rejected_if_outbound_lane_state_decode_fails() { - matches!( - using_messages_proof( - 10, - Some(OutboundLaneData { - oldest_unpruned_nonce: 1, - latest_received_nonce: 1, - latest_generated_nonce: 1, - }), - encode_all_messages, - |d| { - let mut d = d.encode(); - d.truncate(1); - d - }, - |proof| target::verify_messages_proof::<OnThisChainBridge>(proof, 10), - ), - Err(VerificationError::OutboundLaneStorage( - StorageProofError::StorageValueDecodeFailed(_) - )), - ); - } - - #[test] - fn message_proof_is_rejected_if_it_is_empty() { - assert_eq!( - using_messages_proof(0, None, encode_all_messages, encode_lane_data, |proof| { - target::verify_messages_proof::<OnThisChainBridge>(proof, 0) - },), - Err(VerificationError::EmptyMessageProof), - ); - } - - #[test] - fn non_empty_message_proof_without_messages_is_accepted() { - assert_eq!( - using_messages_proof( - 0, - Some(OutboundLaneData { - oldest_unpruned_nonce: 1, - latest_received_nonce: 1, - latest_generated_nonce: 1, - }), - encode_all_messages, - encode_lane_data, - |proof| target::verify_messages_proof::<OnThisChainBridge>(proof, 0), - ), - Ok(vec![( - TEST_LANE_ID, - ProvedLaneMessages { - lane_state: Some(OutboundLaneData { - oldest_unpruned_nonce: 1, - latest_received_nonce: 1, - latest_generated_nonce: 1, - }), - messages: Vec::new(), - }, - )] - .into_iter() - .collect()), - ); - } - - #[test] - fn non_empty_message_proof_is_accepted() { - assert_eq!( - using_messages_proof( - 1, - Some(OutboundLaneData { - oldest_unpruned_nonce: 1, - latest_received_nonce: 1, - latest_generated_nonce: 1, - }), - encode_all_messages, - encode_lane_data, - |proof| target::verify_messages_proof::<OnThisChainBridge>(proof, 1), - ), - Ok(vec![( - TEST_LANE_ID, - ProvedLaneMessages { - lane_state: Some(OutboundLaneData { - oldest_unpruned_nonce: 1, - latest_received_nonce: 1, - latest_generated_nonce: 1, - }), - messages: vec![Message { - key: MessageKey { lane_id: TEST_LANE_ID, nonce: 1 }, - payload: vec![42], - }], - }, - )] - .into_iter() - .collect()), - ); - } - - #[test] - fn verify_messages_proof_does_not_panic_if_messages_count_mismatches() { - assert_eq!( - using_messages_proof(1, None, encode_all_messages, encode_lane_data, |mut proof| { - proof.nonces_end = u64::MAX; - target::verify_messages_proof::<OnThisChainBridge>(proof, u32::MAX) - },), - Err(VerificationError::MessagesCountMismatch), - ); - } -} diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index 74494f7908045fac601b4c3f64a456ad12dacd6f..1880e65547fe6d5e0af71e6ec7c6e0e214f20866 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -19,23 +19,22 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - AccountIdOf, BridgedChain, HashOf, MessageBridge, ThisChain, - }, +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, MessagePayload, +}; +use bp_polkadot_core::parachains::ParaHash; +use bp_runtime::{AccountIdOf, Chain, HashOf, Parachain}; +use codec::Encode; +use frame_support::weights::Weight; +use pallet_bridge_messages::{ + benchmarking::{MessageDeliveryProofParams, MessageProofParams}, messages_generation::{ encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, prepare_messages_storage_proof, }, + BridgedChainOf, ThisChainOf, }; - -use bp_messages::MessagePayload; -use bp_polkadot_core::parachains::ParaHash; -use bp_runtime::{Chain, Parachain, StorageProofSize, UnderlyingChainOf}; -use codec::Encode; -use frame_support::weights::Weight; -use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams}; use sp_runtime::traits::{Header, Zero}; use sp_std::prelude::*; use xcm::latest::prelude::*; @@ -45,11 +44,7 @@ fn prepare_inbound_message( params: &MessageProofParams, successful_dispatch_message_generator: impl Fn(usize) -> MessagePayload, ) -> MessagePayload { - // we only care about **this** message size when message proof needs to be `Minimal` - let expected_size = match params.size { - StorageProofSize::Minimal(size) => size as usize, - _ => 0, - }; + let expected_size = params.proof_params.db_size.unwrap_or(0) as usize; // if we don't need a correct message, then we may just return some random blob if !params.is_successful_dispatch_expected { @@ -75,25 +70,32 @@ fn prepare_inbound_message( /// This method is intended to be used when benchmarking pallet, linked to the chain that /// uses GRANDPA finality. For parachains, please use the `prepare_message_proof_from_parachain` /// function. -pub fn prepare_message_proof_from_grandpa_chain<R, FI, B>( +pub fn prepare_message_proof_from_grandpa_chain<R, FI, MI>( params: MessageProofParams, message_generator: impl Fn(usize) -> MessagePayload, -) -> (FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>, Weight) +) -> (FromBridgedChainMessagesProof<HashOf<BridgedChainOf<R, MI>>>, Weight) where - R: pallet_bridge_grandpa::Config<FI, BridgedChain = UnderlyingChainOf<BridgedChain<B>>>, + R: pallet_bridge_grandpa::Config<FI, BridgedChain = BridgedChainOf<R, MI>> + + pallet_bridge_messages::Config< + MI, + BridgedHeaderChain = pallet_bridge_grandpa::Pallet<R, FI>, + >, FI: 'static, - B: MessageBridge, + MI: 'static, { // prepare storage proof - let (state_root, storage_proof) = prepare_messages_storage_proof::<B>( - params.lane, - params.message_nonces.clone(), - params.outbound_lane_data.clone(), - params.size, - prepare_inbound_message(¶ms, message_generator), - encode_all_messages, - encode_lane_data, - ); + let (state_root, storage_proof) = + prepare_messages_storage_proof::<BridgedChainOf<R, MI>, ThisChainOf<R, MI>>( + params.lane, + params.message_nonces.clone(), + params.outbound_lane_data.clone(), + params.proof_params, + |_| prepare_inbound_message(¶ms, &message_generator), + encode_all_messages, + encode_lane_data, + false, + false, + ); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::<R, FI>(state_root); @@ -118,30 +120,33 @@ where /// This method is intended to be used when benchmarking pallet, linked to the chain that /// uses parachain finality. For GRANDPA chains, please use the /// `prepare_message_proof_from_grandpa_chain` function. -pub fn prepare_message_proof_from_parachain<R, PI, B>( +pub fn prepare_message_proof_from_parachain<R, PI, MI>( params: MessageProofParams, message_generator: impl Fn(usize) -> MessagePayload, -) -> (FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>, Weight) +) -> (FromBridgedChainMessagesProof<HashOf<BridgedChainOf<R, MI>>>, Weight) where - R: pallet_bridge_parachains::Config<PI>, + R: pallet_bridge_parachains::Config<PI> + pallet_bridge_messages::Config<MI>, PI: 'static, - B: MessageBridge, - UnderlyingChainOf<BridgedChain<B>>: Chain<Hash = ParaHash> + Parachain, + MI: 'static, + BridgedChainOf<R, MI>: Chain<Hash = ParaHash> + Parachain, { // prepare storage proof - let (state_root, storage_proof) = prepare_messages_storage_proof::<B>( - params.lane, - params.message_nonces.clone(), - params.outbound_lane_data.clone(), - params.size, - prepare_inbound_message(¶ms, message_generator), - encode_all_messages, - encode_lane_data, - ); + let (state_root, storage_proof) = + prepare_messages_storage_proof::<BridgedChainOf<R, MI>, ThisChainOf<R, MI>>( + params.lane, + params.message_nonces.clone(), + params.outbound_lane_data.clone(), + params.proof_params, + |_| prepare_inbound_message(¶ms, &message_generator), + encode_all_messages, + encode_lane_data, + false, + false, + ); // update runtime storage let (_, bridged_header_hash) = - insert_header_to_parachains_pallet::<R, PI, UnderlyingChainOf<BridgedChain<B>>>(state_root); + insert_header_to_parachains_pallet::<R, PI, BridgedChainOf<R, MI>>(state_root); ( FromBridgedChainMessagesProof { @@ -160,21 +165,24 @@ where /// This method is intended to be used when benchmarking pallet, linked to the chain that /// uses GRANDPA finality. For parachains, please use the /// `prepare_message_delivery_proof_from_parachain` function. -pub fn prepare_message_delivery_proof_from_grandpa_chain<R, FI, B>( - params: MessageDeliveryProofParams<AccountIdOf<ThisChain<B>>>, -) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain<B>>> +pub fn prepare_message_delivery_proof_from_grandpa_chain<R, FI, MI>( + params: MessageDeliveryProofParams<AccountIdOf<ThisChainOf<R, MI>>>, +) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<R, MI>>> where - R: pallet_bridge_grandpa::Config<FI, BridgedChain = UnderlyingChainOf<BridgedChain<B>>>, + R: pallet_bridge_grandpa::Config<FI, BridgedChain = BridgedChainOf<R, MI>> + + pallet_bridge_messages::Config< + MI, + BridgedHeaderChain = pallet_bridge_grandpa::Pallet<R, FI>, + >, FI: 'static, - B: MessageBridge, + MI: 'static, { // prepare storage proof let lane = params.lane; - let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<B>( - params.lane, - params.inbound_lane_data, - params.size, - ); + let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< + BridgedChainOf<R, MI>, + ThisChainOf<R, MI>, + >(params.lane, params.inbound_lane_data, params.proof_params); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::<R, FI>(state_root); @@ -191,26 +199,25 @@ where /// This method is intended to be used when benchmarking pallet, linked to the chain that /// uses parachain finality. For GRANDPA chains, please use the /// `prepare_message_delivery_proof_from_grandpa_chain` function. -pub fn prepare_message_delivery_proof_from_parachain<R, PI, B>( - params: MessageDeliveryProofParams<AccountIdOf<ThisChain<B>>>, -) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain<B>>> +pub fn prepare_message_delivery_proof_from_parachain<R, PI, MI>( + params: MessageDeliveryProofParams<AccountIdOf<ThisChainOf<R, MI>>>, +) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<R, MI>>> where - R: pallet_bridge_parachains::Config<PI>, + R: pallet_bridge_parachains::Config<PI> + pallet_bridge_messages::Config<MI>, PI: 'static, - B: MessageBridge, - UnderlyingChainOf<BridgedChain<B>>: Chain<Hash = ParaHash> + Parachain, + MI: 'static, + BridgedChainOf<R, MI>: Chain<Hash = ParaHash> + Parachain, { // prepare storage proof let lane = params.lane; - let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<B>( - params.lane, - params.inbound_lane_data, - params.size, - ); + let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< + BridgedChainOf<R, MI>, + ThisChainOf<R, MI>, + >(params.lane, params.inbound_lane_data, params.proof_params); // update runtime storage let (_, bridged_header_hash) = - insert_header_to_parachains_pallet::<R, PI, UnderlyingChainOf<BridgedChain<B>>>(state_root); + insert_header_to_parachains_pallet::<R, PI, BridgedChainOf<R, MI>>(state_root); FromBridgedChainMessagesDeliveryProof { bridged_header_hash: bridged_header_hash.into(), diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index fb07f7b6dd69110918af23b227708e226bede625..a9ee1969ae0ca462f36098f03b4454e1399af129 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -14,19 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>. -//! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete -//! (and some other invalid) transactions. +//! Helpers for easier manipulation of call processing with signed extensions. -use crate::messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, +use bp_messages::{ + target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, MessageNonce, }; -use bp_messages::{target_chain::MessageDispatch, InboundLaneData, LaneId, MessageNonce}; -use bp_runtime::OwnedBridgeModule; -use frame_support::{ - dispatch::CallableCallFor, - traits::{Get, IsSubType}, -}; -use pallet_bridge_messages::{Config, Pallet}; +use bp_runtime::{AccountIdOf, OwnedBridgeModule}; +use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; +use pallet_bridge_messages::{BridgedChainOf, Config, Pallet}; use sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug}; use sp_std::ops::RangeInclusive; @@ -213,18 +208,8 @@ pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>: } impl< - BridgedHeaderHash, - SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof<BridgedHeaderHash>, - >, - TargetHeaderChain: bp_messages::source_chain::TargetHeaderChain< - <T as Config<I>>::OutboundPayload, - <T as frame_system::Config>::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash>, - >, Call: IsSubType<CallableCallFor<Pallet<T, I>, T>>, - T: frame_system::Config<RuntimeCall = Call> - + Config<I, SourceHeaderChain = SourceHeaderChain, TargetHeaderChain = TargetHeaderChain>, + T: frame_system::Config<RuntimeCall = Call> + Config<I>, I: 'static, > MessagesCallSubType<T, I> for T::RuntimeCall { @@ -340,16 +325,17 @@ impl< /// Returns occupation state of unrewarded relayers vector. fn unrewarded_relayers_occupation<T: Config<I>, I: 'static>( - inbound_lane_data: &InboundLaneData<T::InboundRelayer>, + inbound_lane_data: &InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>, ) -> UnrewardedRelayerOccupation { UnrewardedRelayerOccupation { - free_relayer_slots: T::MaxUnrewardedRelayerEntriesAtInboundLane::get() + free_relayer_slots: T::BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX .saturating_sub(inbound_lane_data.relayers.len() as MessageNonce), free_message_slots: { let unconfirmed_messages = inbound_lane_data .last_delivered_nonce() .saturating_sub(inbound_lane_data.last_confirmed_nonce); - T::MaxUnconfirmedMessagesAtInboundLane::get().saturating_sub(unconfirmed_messages) + T::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX + .saturating_sub(unconfirmed_messages) }, } } @@ -358,22 +344,20 @@ fn unrewarded_relayers_occupation<T: Config<I>, I: 'static>( mod tests { use super::*; use crate::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - }, messages_call_ext::MessagesCallSubType, - mock::{ - DummyMessageDispatch, MaxUnconfirmedMessagesAtInboundLane, - MaxUnrewardedRelayerEntriesAtInboundLane, TestRuntime, ThisChainRuntimeCall, - }, + mock::{BridgedUnderlyingChain, DummyMessageDispatch, TestRuntime, ThisChainRuntimeCall}, + }; + use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, DeliveredMessages, UnrewardedRelayer, + UnrewardedRelayersState, }; - use bp_messages::{DeliveredMessages, UnrewardedRelayer, UnrewardedRelayersState}; use sp_std::ops::RangeInclusive; fn fill_unrewarded_relayers() { let mut inbound_lane_state = pallet_bridge_messages::InboundLanes::<TestRuntime>::get(LaneId([0, 0, 0, 0])); - for n in 0..MaxUnrewardedRelayerEntriesAtInboundLane::get() { + for n in 0..BridgedUnderlyingChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX { inbound_lane_state.relayers.push_back(UnrewardedRelayer { relayer: Default::default(), messages: DeliveredMessages { begin: n + 1, end: n + 1 }, @@ -392,7 +376,7 @@ mod tests { relayer: Default::default(), messages: DeliveredMessages { begin: 1, - end: MaxUnconfirmedMessagesAtInboundLane::get(), + end: BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, }, }); pallet_bridge_messages::InboundLanes::<TestRuntime>::insert( @@ -418,13 +402,13 @@ mod tests { messages_count: nonces_end.checked_sub(nonces_start).map(|x| x + 1).unwrap_or(0) as u32, dispatch_weight: frame_support::weights::Weight::zero(), - proof: FromBridgedChainMessagesProof { + proof: Box::new(FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage_proof: vec![], + storage_proof: Default::default(), lane: LaneId([0, 0, 0, 0]), nonces_start, nonces_end, - }, + }), }, ) .check_obsolete_call() @@ -508,8 +492,8 @@ mod tests { sp_io::TestExternalities::new(Default::default()).execute_with(|| { fill_unrewarded_messages(); assert!(validate_message_delivery( - MaxUnconfirmedMessagesAtInboundLane::get(), - MaxUnconfirmedMessagesAtInboundLane::get() - 1 + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX - 1 )); }); } @@ -540,7 +524,7 @@ mod tests { pallet_bridge_messages::Call::<TestRuntime>::receive_messages_delivery_proof { proof: FromBridgedChainMessagesDeliveryProof { bridged_header_hash: Default::default(), - storage_proof: Vec::new(), + storage_proof: Default::default(), lane: LaneId([0, 0, 0, 0]), }, relayers_state: UnrewardedRelayersState { @@ -608,7 +592,7 @@ mod tests { free_message_slots: if is_empty { 0 } else { - MaxUnconfirmedMessagesAtInboundLane::get() + BridgedUnderlyingChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX }, }, }, diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index f49474667896049cfd6aff4bf4a4b0d9d6e73c95..2f248a7162a6cbdcc09d2980a922b1a065127e40 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -18,26 +18,16 @@ #![cfg(test)] -use crate::messages::{ - source::{ - FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload, - TargetHeaderChainAdapter, - }, - target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, - BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, -}; +use crate::messages_xcm_extension::XcmAsPlainPayload; -use bp_header_chain::{ChainWithGrandpa, HeaderChain}; +use bp_header_chain::ChainWithGrandpa; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, - LaneId, MessageNonce, + ChainWithMessages, LaneId, MessageNonce, }; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_relayers::PayRewardFromAccount; -use bp_runtime::{ - messages::MessageDispatchResult, Chain, ChainId, Parachain, UnderlyingChainProvider, -}; -use codec::{Decode, Encode}; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Parachain}; use frame_support::{ derive_impl, parameter_types, weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight}, @@ -46,7 +36,7 @@ use pallet_transaction_payment::Multiplier; use sp_runtime::{ testing::H256, traits::{BlakeTwo256, ConstU32, ConstU64, ConstU8}, - FixedPointNumber, Perquintill, + FixedPointNumber, Perquintill, StateVersion, }; /// Account identifier at `ThisChain`. @@ -61,8 +51,6 @@ pub type ThisChainHash = H256; 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<ThisChainBlockNumber, ThisChainHasher>; /// Block of `ThisChain`. @@ -100,8 +88,6 @@ pub type TestStakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< pub const TEST_LANE_ID: LaneId = LaneId([0, 0, 0, 0]); /// Bridged chain id used in tests. pub const TEST_BRIDGED_CHAIN_ID: ChainId = *b"brdg"; -/// 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; @@ -126,7 +112,6 @@ crate::generate_bridge_reject_obsolete_headers_and_messages! { parameter_types! { pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID]; - pub const BridgedChainId: ChainId = TEST_BRIDGED_CHAIN_ID; pub const BridgedParasPalletName: &'static str = "Paras"; pub const ExistentialDeposit: ThisChainBalance = 500; pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 1, write: 2 }; @@ -136,8 +121,6 @@ parameter_types! { 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(); - pub const MaxUnrewardedRelayerEntriesAtInboundLane: MessageNonce = 16; - pub const MaxUnconfirmedMessagesAtInboundLane: MessageNonce = 1_000; pub const ReserveId: [u8; 8] = *b"brdgrlrs"; } @@ -203,17 +186,12 @@ impl pallet_bridge_messages::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight<TestRuntime>; type ActiveOutboundLanes = ActiveOutboundLanes; - type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; - type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; - type MaximalOutboundPayloadSize = FromThisChainMaximalOutboundPayloadSize<OnThisChainBridge>; - type OutboundPayload = FromThisChainMessagePayload; + type OutboundPayload = XcmAsPlainPayload; - type InboundPayload = FromBridgedChainMessagePayload; - type InboundRelayer = BridgedChainAccountId; + type InboundPayload = Vec<u8>; type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter<OnThisChainBridge>; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< TestRuntime, (), @@ -221,9 +199,11 @@ impl pallet_bridge_messages::Config for TestRuntime { >; type OnMessagesDelivered = (); - type SourceHeaderChain = SourceHeaderChainAdapter<OnThisChainBridge>; type MessageDispatch = DummyMessageDispatch; - type BridgedChainId = BridgedChainId; + + type ThisChain = ThisUnderlyingChain; + type BridgedChain = BridgedUnderlyingChain; + type BridgedHeaderChain = BridgeGrandpa; } impl pallet_bridge_relayers::Config for TestRuntime { @@ -262,55 +242,6 @@ impl MessageDispatch for DummyMessageDispatch { } } -/// 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 BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; - - type ThisChain = ThisChain; - type BridgedChain = BridgedChain; - type BridgedHeaderChain = pallet_bridge_grandpa::GrandpaChainHeaders<TestRuntime, ()>; -} - -/// 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 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<ThisUnderlyingChain> for ThisHeaderChain { - fn finalized_header_state_root(_hash: HashOf<ThisChain>) -> Option<HashOf<ThisChain>> { - unreachable!() - } -} - -/// Call origin at `BridgedChain`. -#[derive(Clone, Debug)] -pub struct BridgedChainOrigin; - -impl From<BridgedChainOrigin> - for Result<frame_system::RawOrigin<BridgedChainAccountId>, BridgedChainOrigin> -{ - fn from( - _origin: BridgedChainOrigin, - ) -> Result<frame_system::RawOrigin<BridgedChainAccountId>, BridgedChainOrigin> { - unreachable!() - } -} - /// Underlying chain of `ThisChain`. pub struct ThisUnderlyingChain; @@ -326,6 +257,8 @@ impl Chain for ThisUnderlyingChain { type Nonce = u32; type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE } @@ -335,29 +268,20 @@ impl Chain for ThisUnderlyingChain { } } -/// The chain where we are in tests. -pub struct ThisChain; - -impl UnderlyingChainProvider for ThisChain { - type Chain = ThisUnderlyingChain; -} +impl ChainWithMessages for ThisUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; -impl ThisChainWithMessages for ThisChain { - type RuntimeOrigin = ThisChainCallOrigin; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; } -impl BridgedChainWithMessages for ThisChain {} - /// 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 { - const ID: ChainId = *b"buch"; + const ID: ChainId = TEST_BRIDGED_CHAIN_ID; type BlockNumber = BridgedChainBlockNumber; type Hash = BridgedChainHash; @@ -368,6 +292,8 @@ impl Chain for BridgedUnderlyingChain { type Nonce = u32; type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE } @@ -384,6 +310,12 @@ impl ChainWithGrandpa for BridgedUnderlyingChain { const AVERAGE_HEADER_SIZE: u32 = 64; } +impl ChainWithMessages for BridgedUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; +} + impl Chain for BridgedUnderlyingParachain { const ID: ChainId = *b"bupc"; @@ -396,6 +328,8 @@ impl Chain for BridgedUnderlyingParachain { type Nonce = u32; type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE } @@ -409,19 +343,6 @@ impl Parachain for BridgedUnderlyingParachain { const MAX_HEADER_SIZE: u32 = 1_024; } -/// The other, bridged chain, used in tests. -pub struct BridgedChain; - -impl UnderlyingChainProvider for BridgedChain { - type Chain = BridgedUnderlyingChain; -} - -impl ThisChainWithMessages for BridgedChain { - type RuntimeOrigin = BridgedChainOrigin; -} - -impl BridgedChainWithMessages for BridgedChain {} - /// Run test within test externalities. pub fn run_test(test: impl FnOnce()) { sp_io::TestExternalities::new(Default::default()).execute_with(test) diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index b3050b9ac0f3ccec617399d3eb91647dcab7eb3d..bcbd779b44dea5fbef7781335cfa1d359ab8c1f1 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -18,14 +18,11 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{ - messages_benchmarking::insert_header_to_grandpa_pallet, - messages_generation::grow_trie_leaf_value, -}; +use crate::messages_benchmarking::insert_header_to_grandpa_pallet; use bp_parachains::parachain_head_storage_key_at_source; use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId}; -use bp_runtime::{record_all_trie_keys, StorageProofSize}; +use bp_runtime::{grow_storage_value, record_all_trie_keys, Chain, UnverifiedStorageProofParams}; use codec::Encode; use frame_support::traits::Get; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; @@ -39,14 +36,14 @@ use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; pub fn prepare_parachain_heads_proof<R, PI>( parachains: &[ParaId], parachain_head_size: u32, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) where R: pallet_bridge_parachains::Config<PI> + pallet_bridge_grandpa::Config<R::BridgesGrandpaPalletInstance>, PI: 'static, <R as pallet_bridge_grandpa::Config<R::BridgesGrandpaPalletInstance>>::BridgedChain: - bp_runtime::Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash>, + Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash>, { let parachain_head = ParaHead(vec![0u8; parachain_head_size as usize]); @@ -64,7 +61,7 @@ where let storage_key = parachain_head_storage_key_at_source(R::ParasPalletName::get(), *parachain); let leaf_data = if i == 0 { - grow_trie_leaf_value(parachain_head.encode(), size) + grow_storage_value(parachain_head.encode(), &proof_params) } else { parachain_head.encode() }; diff --git a/bridges/chains/chain-bridge-hub-kusama/src/lib.rs b/bridges/chains/chain-bridge-hub-kusama/src/lib.rs index ef3ef4ab7b7a9bc111218e3c53091ac232f34721..c990e8a12f367cafbd35b0693b323a6ec5fb5e96 100644 --- a/bridges/chains/chain-bridge-hub-kusama/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-kusama/src/lib.rs @@ -29,7 +29,7 @@ use frame_support::{ dispatch::DispatchClass, sp_runtime::{MultiAddress, MultiSigner}, }; -use sp_runtime::RuntimeDebug; +use sp_runtime::{RuntimeDebug, StateVersion}; /// BridgeHubKusama parachain. #[derive(RuntimeDebug)] @@ -48,6 +48,8 @@ impl Chain for BridgeHubKusama { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } diff --git a/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs b/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs index 9db71af928e5df01170cf4ab8bf5f20cd72f7610..7379b8863b1de5c1a1482db90077e958f0a33366 100644 --- a/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs @@ -26,7 +26,7 @@ use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; -use sp_runtime::RuntimeDebug; +use sp_runtime::{RuntimeDebug, StateVersion}; /// BridgeHubPolkadot parachain. #[derive(RuntimeDebug)] @@ -45,6 +45,8 @@ impl Chain for BridgeHubPolkadot { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index d7097f01c5316a58851f400a86b98eda3d7e8bcc..73af997b9950ef640040e44cbba0b93b6a7a56a3 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -25,8 +25,10 @@ use bp_messages::*; use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; -use frame_support::dispatch::DispatchClass; -use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug}; +use frame_support::{ + dispatch::DispatchClass, + sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug, StateVersion}, +}; /// BridgeHubRococo parachain. #[derive(RuntimeDebug)] @@ -45,6 +47,8 @@ impl Chain for BridgeHubRococo { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } @@ -103,10 +107,10 @@ frame_support::parameter_types! { pub const BridgeHubRococoBaseXcmFeeInRocs: u128 = 59_034_266; /// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message. - /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`) + /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 314_037_860; /// Transaction fee that is paid at the Rococo BridgeHub for delivering single outbound message confirmation. - /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`) + /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`) pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 57_414_813; } diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index 800f290d7bfa41cec4139e80a7dc9ea8962a6da5..17ff2c858a1d3eeae329cb972d95adc32952ede4 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -25,7 +25,7 @@ use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; -use sp_runtime::RuntimeDebug; +use sp_runtime::{RuntimeDebug, StateVersion}; /// BridgeHubWestend parachain. #[derive(RuntimeDebug)] @@ -44,6 +44,8 @@ impl Chain for BridgeHubWestend { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } diff --git a/bridges/chains/chain-kusama/src/lib.rs b/bridges/chains/chain-kusama/src/lib.rs index fd7172c5869d468ff534e54f9ef6278cf86a88ed..dcd0b23abbbefa2dfba741d6934b5d5510c93017 100644 --- a/bridges/chains/chain-kusama/src/lib.rs +++ b/bridges/chains/chain-kusama/src/lib.rs @@ -23,7 +23,7 @@ pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; -use frame_support::weights::Weight; +use frame_support::{sp_runtime::StateVersion, weights::Weight}; /// Kusama Chain pub struct Kusama; @@ -41,6 +41,8 @@ impl Chain for Kusama { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V0; + fn max_extrinsic_size() -> u32 { max_extrinsic_size() } diff --git a/bridges/chains/chain-polkadot-bulletin/src/lib.rs b/bridges/chains/chain-polkadot-bulletin/src/lib.rs index f3d300567f2b4f92cec272e0929a3c53d718c823..88980a9575016bd5c5e1428329454e8131a2075d 100644 --- a/bridges/chains/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/chains/chain-polkadot-bulletin/src/lib.rs @@ -37,7 +37,9 @@ use frame_support::{ }; use frame_system::limits; use scale_info::TypeInfo; -use sp_runtime::{traits::DispatchInfoOf, transaction_validity::TransactionValidityError, Perbill}; +use sp_runtime::{ + traits::DispatchInfoOf, transaction_validity::TransactionValidityError, Perbill, StateVersion, +}; // This chain reuses most of Polkadot primitives. pub use bp_polkadot_core::{ @@ -192,6 +194,8 @@ impl Chain for PolkadotBulletin { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } diff --git a/bridges/chains/chain-polkadot/src/lib.rs b/bridges/chains/chain-polkadot/src/lib.rs index a8cac0467d574e9355a8fe9ba2e7c2378019349d..f4b262d40735d7470a4d7e289f24bc1d4556d039 100644 --- a/bridges/chains/chain-polkadot/src/lib.rs +++ b/bridges/chains/chain-polkadot/src/lib.rs @@ -25,7 +25,7 @@ use bp_header_chain::ChainWithGrandpa; use bp_runtime::{ decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain, ChainId, }; -use frame_support::weights::Weight; +use frame_support::{sp_runtime::StateVersion, weights::Weight}; /// Polkadot Chain pub struct Polkadot; @@ -43,6 +43,8 @@ impl Chain for Polkadot { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V0; + fn max_extrinsic_size() -> u32 { max_extrinsic_size() } diff --git a/bridges/chains/chain-rococo/src/lib.rs b/bridges/chains/chain-rococo/src/lib.rs index b290fe71c829d08130556a2b061c0d63f0787d4c..bfcafdf41ea2e629c9a58f2545016b2e776375b8 100644 --- a/bridges/chains/chain-rococo/src/lib.rs +++ b/bridges/chains/chain-rococo/src/lib.rs @@ -23,7 +23,7 @@ pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; -use frame_support::weights::Weight; +use frame_support::{sp_runtime::StateVersion, weights::Weight}; /// Rococo Chain pub struct Rococo; @@ -41,6 +41,8 @@ impl Chain for Rococo { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { max_extrinsic_size() } diff --git a/bridges/chains/chain-westend/src/lib.rs b/bridges/chains/chain-westend/src/lib.rs index ef451f7de0a9640bc1a278e1c712bbb099193ceb..2a247e03e59d666d3c5dd54d74e3a4f852a60bd3 100644 --- a/bridges/chains/chain-westend/src/lib.rs +++ b/bridges/chains/chain-westend/src/lib.rs @@ -23,7 +23,7 @@ pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; -use frame_support::weights::Weight; +use frame_support::{sp_runtime::StateVersion, weights::Weight}; /// Westend Chain pub struct Westend; @@ -41,6 +41,8 @@ impl Chain for Westend { type Nonce = Nonce; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { max_extrinsic_size() } diff --git a/bridges/modules/beefy/src/mock.rs b/bridges/modules/beefy/src/mock.rs index 53efd57c29a0dfc870e43be4fec7bcdf817a3282..3b751ddf066c9562cd8fc0f054b1b103306479dd 100644 --- a/bridges/modules/beefy/src/mock.rs +++ b/bridges/modules/beefy/src/mock.rs @@ -29,6 +29,7 @@ use sp_core::{sr25519::Signature, Pair}; use sp_runtime::{ testing::{Header, H256}, traits::{BlakeTwo256, Hash}, + StateVersion, }; pub use sp_consensus_beefy::ecdsa_crypto::{AuthorityId as BeefyId, Pair as BeefyPair}; @@ -93,6 +94,8 @@ impl Chain for TestBridgedChain { type Nonce = u64; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { unreachable!() } diff --git a/bridges/modules/grandpa/Cargo.toml b/bridges/modules/grandpa/Cargo.toml index 307c7ddaaffd963e89f7b2faa7a487ce5db0dcca..6d1419ae5b030733ad9fb38a6a459ab7ce34f99f 100644 --- a/bridges/modules/grandpa/Cargo.toml +++ b/bridges/modules/grandpa/Cargo.toml @@ -14,7 +14,6 @@ workspace = true [dependencies] codec = { workspace = true } -finality-grandpa = { workspace = true } log = { workspace = true } scale-info = { features = ["derive"], workspace = true } @@ -30,13 +29,13 @@ frame-system = { workspace = true } sp-consensus-grandpa = { features = ["serde"], workspace = true } sp-runtime = { features = ["serde"], workspace = true } sp-std = { workspace = true } -sp-trie = { workspace = true } # Optional Benchmarking Dependencies bp-test-utils = { optional = true, workspace = true } frame-benchmarking = { optional = true, workspace = true } [dev-dependencies] +bp-runtime = { features = ["test-helpers"], workspace = true } sp-core = { workspace = true, default-features = true } sp-io = { workspace = true, default-features = true } @@ -47,7 +46,6 @@ std = [ "bp-runtime/std", "bp-test-utils/std", "codec/std", - "finality-grandpa/std", "frame-benchmarking/std", "frame-support/std", "frame-system/std", @@ -56,7 +54,6 @@ std = [ "sp-consensus-grandpa/std", "sp-runtime/std", "sp-std/std", - "sp-trie/std", ] runtime-benchmarks = [ "bp-test-utils", diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 3b77f676870e1a28b8367f1b14d24c9ca83ece4a..c62951b74656b052d4858dec2af1393e41553029 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -1443,11 +1443,14 @@ mod tests { } #[test] - fn parse_finalized_storage_proof_rejects_proof_on_unknown_header() { + fn verify_storage_proof_rejects_unknown_header() { run_test(|| { assert_noop!( - Pallet::<TestRuntime>::storage_proof_checker(Default::default(), vec![],) - .map(|_| ()), + Pallet::<TestRuntime>::verify_storage_proof( + Default::default(), + Default::default(), + ) + .map(|_| ()), bp_header_chain::HeaderChainError::UnknownHeader, ); }); @@ -1465,9 +1468,7 @@ mod tests { <BestFinalized<TestRuntime>>::put(HeaderId(2, hash)); <ImportedHeaders<TestRuntime>>::insert(hash, header.build()); - assert_ok!( - Pallet::<TestRuntime>::storage_proof_checker(hash, storage_proof).map(|_| ()) - ); + assert_ok!(Pallet::<TestRuntime>::verify_storage_proof(hash, storage_proof).map(|_| ())); }); } diff --git a/bridges/modules/grandpa/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index 27df9d9c78f540d0d73f74c6a86ba19af30d4b6b..71af6182e057cca3d06b98ee6fe94283b93ab77d 100644 --- a/bridges/modules/grandpa/src/mock.rs +++ b/bridges/modules/grandpa/src/mock.rs @@ -20,7 +20,8 @@ use bp_header_chain::ChainWithGrandpa; use bp_runtime::{Chain, ChainId}; use frame_support::{ - construct_runtime, derive_impl, parameter_types, traits::Hooks, weights::Weight, + construct_runtime, derive_impl, parameter_types, sp_runtime::StateVersion, traits::Hooks, + weights::Weight, }; use sp_core::sr25519::Signature; @@ -78,6 +79,8 @@ impl Chain for TestBridgedChain { type Nonce = u64; type Signature = Signature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { unreachable!() } diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index 573d0ba47668cfd5513def1a2465be10002c676f..33f524030d264e4ed292f8f67273e838e15fc3a9 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -13,52 +13,67 @@ workspace = true [dependencies] codec = { workspace = true } log = { workspace = true } -num-traits = { workspace = true } scale-info = { features = ["derive"], workspace = true } # Bridge dependencies - +bp-header-chain = { workspace = true } bp-messages = { workspace = true } bp-runtime = { workspace = true } # Substrate Dependencies - frame-benchmarking = { optional = true, workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } +sp-trie = { optional = true, workspace = true } [dev-dependencies] -bp-test-utils = { workspace = true, default-features = true } -pallet-balances = { workspace = true, default-features = true } -sp-io = { workspace = true, default-features = true } +bp-runtime = { features = ["test-helpers"], workspace = true } +bp-test-utils = { workspace = true } +pallet-balances = { workspace = true } +pallet-bridge-grandpa = { workspace = true } +sp-io = { workspace = true } +sp-core = { workspace = true } [features] default = ["std"] std = [ + "bp-header-chain/std", "bp-messages/std", "bp-runtime/std", + "bp-test-utils/std", "codec/std", "frame-benchmarking/std", "frame-support/std", "frame-system/std", "log/std", - "num-traits/std", + "pallet-balances/std", + "pallet-bridge-grandpa/std", "scale-info/std", + "sp-core/std", + "sp-io/std", "sp-runtime/std", "sp-std/std", + "sp-trie/std", ] runtime-benchmarks = [ + "bp-runtime/test-helpers", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-bridge-grandpa/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-balances/try-runtime", + "pallet-bridge-grandpa/try-runtime", "sp-runtime/try-runtime", ] +test-helpers = [ + "bp-runtime/test-helpers", + "sp-trie", +] diff --git a/bridges/modules/messages/README.md b/bridges/modules/messages/README.md index c06b96b857dea1cdf7fdaed81e70d66aff116064..80fd92eb0e5a7d975ba45619838007a12f5f5553 100644 --- a/bridges/modules/messages/README.md +++ b/bridges/modules/messages/README.md @@ -104,17 +104,22 @@ the message. When a message is delivered to the target chain, the `MessagesDeliv `receive_messages_delivery_proof()` transaction. The `MessagesDelivered` contains the message lane identifier and inclusive range of delivered message nonces. -The pallet provides no means to get the result of message dispatch at the target chain. If that is required, it must be -done outside of the pallet. For example, XCM messages, when dispatched, have special instructions to send some data back -to the sender. Other dispatchers may use similar mechanism for that. -### How to plug-in Messages Module to Send Messages to the Bridged Chain? - -The `pallet_bridge_messages::Config` trait has 3 main associated types that are used to work with outbound messages. The -`pallet_bridge_messages::Config::TargetHeaderChain` defines how we see the bridged chain as the target for our outbound -messages. It must be able to check that the bridged chain may accept our message - like that the message has size below -maximal possible transaction size of the chain and so on. And when the relayer sends us a confirmation transaction, this -implementation must be able to parse and verify the proof of messages delivery. Normally, you would reuse the same -(configurable) type on all chains that are sending messages to the same bridged chain. +The pallet provides no means to get the result of message dispatch at the target chain. If that is +required, it must be done outside of the pallet. For example, XCM messages, when dispatched, have +special instructions to send some data back to the sender. Other dispatchers may use similar +mechanism for that. + +### How to plug-in Messages Module to Send and Receive Messages from the Bridged Chain? + +The `pallet_bridge_messages::Config` trait has 2 main associated types that are used to work with +inbound messages. The `pallet_bridge_messages::BridgedChain` defines basic primitives of the bridged +chain. The `pallet_bridge_messages::BridgedHeaderChain` defines the way we access the bridged chain +headers in our runtime. You may use `pallet_bridge_grandpa` if you're bridging with chain that uses +GRANDPA finality or `pallet_bridge_parachains::ParachainHeaders` if you're bridging with parachain. + +The `pallet_bridge_messages::Config::MessageDispatch` defines a way on how to dispatch delivered +messages. Apart from actually dispatching the message, the implementation must return the correct +dispatch weight of the message before dispatch is called. The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation transaction is received, we call the `pay_reward()` method, passing the range of delivered messages. @@ -129,18 +134,6 @@ You should be looking at the `bp_messages::source_chain::ForbidOutboundMessages` [`bp_messages::source_chain`](../../primitives/messages/src/source_chain.rs). It implements all required traits and will simply reject all transactions, related to outbound messages. -### How to plug-in Messages Module to Receive Messages from the Bridged Chain? - -The `pallet_bridge_messages::Config` trait has 2 main associated types that are used to work with inbound messages. The -`pallet_bridge_messages::Config::SourceHeaderChain` defines how we see the bridged chain as the source of our inbound -messages. When relayer sends us a delivery transaction, this implementation must be able to parse and verify the proof -of messages wrapped in this transaction. Normally, you would reuse the same (configurable) type on all chains that are -sending messages to the same bridged chain. - -The `pallet_bridge_messages::Config::MessageDispatch` defines a way on how to dispatch delivered messages. Apart from -actually dispatching the message, the implementation must return the correct dispatch weight of the message before -dispatch is called. - ### I have a Messages Module in my Runtime, but I Want to Reject all Inbound Messages. What shall I do? You should be looking at the `bp_messages::target_chain::ForbidInboundMessages` structure from the @@ -150,36 +143,42 @@ and will simply reject all transactions, related to inbound messages. ### What about other Constants in the Messages Module Configuration Trait? Two settings that are used to check messages in the `send_message()` function. The -`pallet_bridge_messages::Config::ActiveOutboundLanes` is an array of all message lanes, that may be used to send -messages. All messages sent using other lanes are rejected. All messages that have size above -`pallet_bridge_messages::Config::MaximalOutboundPayloadSize` will also be rejected. - -To be able to reward the relayer for delivering messages, we store a map of message nonces range => identifier of the -relayer that has delivered this range at the target chain runtime storage. If a relayer delivers multiple consequent -ranges, they're merged into single entry. So there may be more than one entry for the same relayer. Eventually, this -whole map must be delivered back to the source chain to confirm delivery and pay rewards. So to make sure we are able to -craft this confirmation transaction, we need to: (1) keep the size of this map below a certain limit and (2) make sure -that the weight of processing this map is below a certain limit. Both size and processing weight mostly depend on the -number of entries. The number of entries is limited with the -`pallet_bridge_messages::ConfigMaxUnrewardedRelayerEntriesAtInboundLane` parameter. Processing weight also depends on -the total number of messages that are being confirmed, because every confirmed message needs to be read. So there's -another `pallet_bridge_messages::Config::MaxUnconfirmedMessagesAtInboundLane` parameter for that. - -When choosing values for these parameters, you must also keep in mind that if proof in your scheme is based on finality -of headers (and it is the most obvious option for Substrate-based chains with finality notion), then choosing too small -values for these parameters may cause significant delays in message delivery. That's because there are too many actors -involved in this scheme: 1) authorities that are finalizing headers of the target chain need to finalize header with -non-empty map; 2) the headers relayer then needs to submit this header and its finality proof to the source chain; 3) -the messages relayer must then send confirmation transaction (storage proof of this map) to the source chain; 4) when -the confirmation transaction will be mined at some header, source chain authorities must finalize this header; 5) the -headers relay then needs to submit this header and its finality proof to the target chain; 6) only now the messages -relayer may submit new messages from the source to target chain and prune the entry from the map. - -Delivery transaction requires the relayer to provide both number of entries and total number of messages in the map. -This means that the module never charges an extra cost for delivering a map - the relayer would need to pay exactly for -the number of entries+messages it has delivered. So the best guess for values of these parameters would be the pair that -would occupy `N` percent of the maximal transaction size and weight of the source chain. The `N` should be large enough -to process large maps, at the same time keeping reserve for future source chain upgrades. +`pallet_bridge_messages::Config::ActiveOutboundLanes` is an array of all message lanes, that +may be used to send messages. All messages sent using other lanes are rejected. All messages that have +size above `pallet_bridge_messages::Config::MaximalOutboundPayloadSize` will also be rejected. + +To be able to reward the relayer for delivering messages, we store a map of message nonces range => +identifier of the relayer that has delivered this range at the target chain runtime storage. If a +relayer delivers multiple consequent ranges, they're merged into single entry. So there may be more +than one entry for the same relayer. Eventually, this whole map must be delivered back to the source +chain to confirm delivery and pay rewards. So to make sure we are able to craft this confirmation +transaction, we need to: (1) keep the size of this map below a certain limit and (2) make sure that +the weight of processing this map is below a certain limit. Both size and processing weight mostly +depend on the number of entries. The number of entries is limited with the +`pallet_bridge_messages::Config::BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX` parameter. +Processing weight also depends on the total number of messages that are being confirmed, because every +confirmed message needs to be read. So there's another +`pallet_bridge_messages::Config::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX` parameter +for that. + +When choosing values for these parameters, you must also keep in mind that if proof in your scheme +is based on finality of headers (and it is the most obvious option for Substrate-based chains with +finality notion), then choosing too small values for these parameters may cause significant delays +in message delivery. That's because there are too many actors involved in this scheme: 1) authorities +that are finalizing headers of the target chain need to finalize header with non-empty map; 2) the +headers relayer then needs to submit this header and its finality proof to the source chain; 3) the +messages relayer must then send confirmation transaction (storage proof of this map) to the source +chain; 4) when the confirmation transaction will be mined at some header, source chain authorities +must finalize this header; 5) the headers relay then needs to submit this header and its finality +proof to the target chain; 6) only now the messages relayer may submit new messages from the source +to target chain and prune the entry from the map. + +Delivery transaction requires the relayer to provide both number of entries and total number of +messages in the map. This means that the module never charges an extra cost for delivering a map - +the relayer would need to pay exactly for the number of entries+messages it has delivered. So the +best guess for values of these parameters would be the pair that would occupy `N` percent of the +maximal transaction size and weight of the source chain. The `N` should be large enough to process +large maps, at the same time keeping reserve for future source chain upgrades. ## Non-Essential Functionality diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 4f13c4409672b3e76d36fd7d3dd2fab5c7e2ec1b..d38aaf32dc94bd157de0d3e910b729a7970c1684 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -16,19 +16,22 @@ //! Messages pallet benchmarking. +#![cfg(feature = "runtime-benchmarks")] + use crate::{ inbound_lane::InboundLaneStorage, outbound_lane, weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH, - Call, OutboundLanes, RuntimeInboundLaneStorage, + BridgedChainOf, Call, OutboundLanes, RuntimeInboundLaneStorage, }; use bp_messages::{ - source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, DeliveredMessages, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; -use bp_runtime::StorageProofSize; +use bp_runtime::{AccountIdOf, HashOf, UnverifiedStorageProofParams}; use codec::Decode; -use frame_benchmarking::{account, benchmarks_instance_pallet}; +use frame_benchmarking::{account, v2::*}; use frame_support::weights::Weight; use frame_system::RawOrigin; use sp_runtime::{traits::TrailingZeroInput, BoundedVec}; @@ -54,7 +57,7 @@ pub struct MessageProofParams { /// return `true` from the `is_message_successfully_dispatched`. pub is_successful_dispatch_expected: bool, /// Proof size requirements. - pub size: StorageProofSize, + pub proof_params: UnverifiedStorageProofParams, } /// Benchmark-specific message delivery proof parameters. @@ -65,7 +68,7 @@ pub struct MessageDeliveryProofParams<ThisChainAccountId> { /// The proof needs to include this inbound lane data. pub inbound_lane_data: InboundLaneData<ThisChainAccountId>, /// Proof size requirements. - pub size: StorageProofSize, + pub proof_params: UnverifiedStorageProofParams, } /// Trait that must be implemented by runtime. @@ -80,8 +83,8 @@ pub trait Config<I: 'static>: crate::Config<I> { /// Return id of relayer account at the bridged chain. /// /// By default, zero account is returned. - fn bridged_relayer_id() -> Self::InboundRelayer { - Self::InboundRelayer::decode(&mut TrailingZeroInput::zeroes()).unwrap() + fn bridged_relayer_id() -> AccountIdOf<BridgedChainOf<Self, I>> { + Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap() } /// Create given account and give it enough balance for test purposes. Used to create @@ -94,11 +97,11 @@ pub trait Config<I: 'static>: crate::Config<I> { /// Prepare messages proof to receive by the module. fn prepare_message_proof( params: MessageProofParams, - ) -> (<Self::SourceHeaderChain as SourceHeaderChain>::MessagesProof, Weight); + ) -> (FromBridgedChainMessagesProof<HashOf<BridgedChainOf<Self, I>>>, Weight); /// Prepare messages delivery proof to receive by the module. fn prepare_message_delivery_proof( params: MessageDeliveryProofParams<Self::AccountId>, - ) -> <Self::TargetHeaderChain as TargetHeaderChain<Self::OutboundPayload, Self::AccountId>>::MessagesDeliveryProof; + ) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<Self, I>>>; /// Returns true if message has been successfully dispatched or not. fn is_message_successfully_dispatched(_nonce: MessageNonce) -> bool { @@ -109,174 +112,227 @@ pub trait Config<I: 'static>: crate::Config<I> { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool; } -benchmarks_instance_pallet! { +fn send_regular_message<T: Config<I>, I: 'static>() { + let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id()); + outbound_lane.send_message(BoundedVec::try_from(vec![]).expect("We craft valid messages")); +} + +fn receive_messages<T: Config<I>, I: 'static>(nonce: MessageNonce) { + let mut inbound_lane_storage = + RuntimeInboundLaneStorage::<T, I>::from_lane_id(T::bench_lane_id()); + inbound_lane_storage.set_data(InboundLaneData { + relayers: vec![UnrewardedRelayer { + relayer: T::bridged_relayer_id(), + messages: DeliveredMessages::new(nonce), + }] + .into_iter() + .collect(), + last_confirmed_nonce: 0, + }); +} + +struct ReceiveMessagesProofSetup<T: Config<I>, I: 'static> { + relayer_id_on_src: AccountIdOf<BridgedChainOf<T, I>>, + relayer_id_on_tgt: T::AccountId, + msgs_count: u32, + _phantom_data: sp_std::marker::PhantomData<I>, +} + +impl<T: Config<I>, I: 'static> ReceiveMessagesProofSetup<T, I> { + const LATEST_RECEIVED_NONCE: MessageNonce = 20; + + fn new(msgs_count: u32) -> Self { + let setup = Self { + relayer_id_on_src: T::bridged_relayer_id(), + relayer_id_on_tgt: account("relayer", 0, SEED), + msgs_count, + _phantom_data: Default::default(), + }; + T::endow_account(&setup.relayer_id_on_tgt); + // mark messages 1..=latest_recvd_nonce as delivered + receive_messages::<T, I>(Self::LATEST_RECEIVED_NONCE); + + setup + } + + fn relayer_id_on_src(&self) -> AccountIdOf<BridgedChainOf<T, I>> { + self.relayer_id_on_src.clone() + } + + fn relayer_id_on_tgt(&self) -> T::AccountId { + self.relayer_id_on_tgt.clone() + } + + fn last_nonce(&self) -> MessageNonce { + Self::LATEST_RECEIVED_NONCE + self.msgs_count as u64 + } + + fn nonces(&self) -> RangeInclusive<MessageNonce> { + (Self::LATEST_RECEIVED_NONCE + 1)..=self.last_nonce() + } + + fn check_last_nonce(&self) { + assert_eq!( + crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(), + self.last_nonce(), + ); + } +} + +#[instance_benchmarks] +mod benchmarks { + use super::*; + // // Benchmarks that are used directly by the runtime calls weight formulae. // - // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions: + fn max_msgs<T: Config<I>, I: 'static>() -> u32 { + T::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX as u32 - + ReceiveMessagesProofSetup::<T, I>::LATEST_RECEIVED_NONCE as u32 + } + + // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following + // conditions: // * proof does not include outbound lane state proof; // * inbound lane already has state, so it needs to be read and decoded; // * message is dispatched (reminder: dispatch weight should be minimal); // * message requires all heavy checks done by dispatcher. - // - // This is base benchmark for all other message delivery benchmarks. - receive_single_message_proof { - let relayer_id_on_source = T::bridged_relayer_id(); - let relayer_id_on_target = account("relayer", 0, SEED); - T::endow_account(&relayer_id_on_target); - - // mark messages 1..=20 as delivered - receive_messages::<T, I>(20); - + #[benchmark] + fn receive_single_message_proof() { + // setup code + let setup = ReceiveMessagesProofSetup::<T, I>::new(1); let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { lane: T::bench_lane_id(), - message_nonces: 21..=21, + message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: false, - size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), + proof_params: UnverifiedStorageProofParams::from_db_size( + EXPECTED_DEFAULT_MESSAGE_LENGTH, + ), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(), - 21, + + #[extrinsic_call] + receive_messages_proof( + RawOrigin::Signed(setup.relayer_id_on_tgt()), + setup.relayer_id_on_src(), + Box::new(proof), + setup.msgs_count, + dispatch_weight, ); + + // verification code + setup.check_last_nonce(); } - // Benchmark `receive_messages_proof` extrinsic with two minimal-weight messages and following conditions: + // Benchmark `receive_messages_proof` extrinsic with `n` minimal-weight messages and following + // conditions: // * proof does not include outbound lane state proof; // * inbound lane already has state, so it needs to be read and decoded; // * message is dispatched (reminder: dispatch weight should be minimal); // * message requires all heavy checks done by dispatcher. - // - // The weight of single message delivery could be approximated as - // `weight(receive_two_messages_proof) - weight(receive_single_message_proof)`. - // This won't be super-accurate if message has non-zero dispatch weight, but estimation should - // be close enough to real weight. - receive_two_messages_proof { - let relayer_id_on_source = T::bridged_relayer_id(); - let relayer_id_on_target = account("relayer", 0, SEED); - T::endow_account(&relayer_id_on_target); - - // mark messages 1..=20 as delivered - receive_messages::<T, I>(20); - + #[benchmark] + fn receive_n_messages_proof(n: Linear<1, { max_msgs::<T, I>() }>) { + // setup code + let setup = ReceiveMessagesProofSetup::<T, I>::new(n); let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { lane: T::bench_lane_id(), - message_nonces: 21..=22, + message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: false, - size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), + proof_params: UnverifiedStorageProofParams::from_db_size( + EXPECTED_DEFAULT_MESSAGE_LENGTH, + ), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 2, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(), - 22, + + #[extrinsic_call] + receive_messages_proof( + RawOrigin::Signed(setup.relayer_id_on_tgt()), + setup.relayer_id_on_src(), + Box::new(proof), + setup.msgs_count, + dispatch_weight, ); + + // verification code + setup.check_last_nonce(); } - // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions: + // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following + // conditions: // * proof includes outbound lane state proof; // * inbound lane already has state, so it needs to be read and decoded; // * message is successfully dispatched (reminder: dispatch weight should be minimal); // * message requires all heavy checks done by dispatcher. // // The weight of outbound lane state delivery would be - // `weight(receive_single_message_proof_with_outbound_lane_state) - weight(receive_single_message_proof)`. - // This won't be super-accurate if message has non-zero dispatch weight, but estimation should - // be close enough to real weight. - receive_single_message_proof_with_outbound_lane_state { - let relayer_id_on_source = T::bridged_relayer_id(); - let relayer_id_on_target = account("relayer", 0, SEED); - T::endow_account(&relayer_id_on_target); - - // mark messages 1..=20 as delivered - receive_messages::<T, I>(20); - + // `weight(receive_single_message_proof_with_outbound_lane_state) - + // weight(receive_single_message_proof)`. This won't be super-accurate if message has non-zero + // dispatch weight, but estimation should be close enough to real weight. + #[benchmark] + fn receive_single_message_proof_with_outbound_lane_state() { + // setup code + let setup = ReceiveMessagesProofSetup::<T, I>::new(1); let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { lane: T::bench_lane_id(), - message_nonces: 21..=21, + message_nonces: setup.nonces(), outbound_lane_data: Some(OutboundLaneData { - oldest_unpruned_nonce: 21, - latest_received_nonce: 20, - latest_generated_nonce: 21, + oldest_unpruned_nonce: setup.last_nonce(), + latest_received_nonce: ReceiveMessagesProofSetup::<T, I>::LATEST_RECEIVED_NONCE, + latest_generated_nonce: setup.last_nonce(), }), is_successful_dispatch_expected: false, - size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH), + proof_params: UnverifiedStorageProofParams::from_db_size( + EXPECTED_DEFAULT_MESSAGE_LENGTH, + ), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - let lane_state = crate::InboundLanes::<T, I>::get(&T::bench_lane_id()); - assert_eq!(lane_state.last_delivered_nonce(), 21); - assert_eq!(lane_state.last_confirmed_nonce, 20); - } - - // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions: - // * the proof has large leaf with total size of approximately 1KB; - // * proof does not include outbound lane state proof; - // * inbound lane already has state, so it needs to be read and decoded; - // * message is dispatched (reminder: dispatch weight should be minimal); - // * message requires all heavy checks done by dispatcher. - // - // With single KB of messages proof, the weight of the call is increased (roughly) by - // `(receive_single_message_proof_16KB - receive_single_message_proof_1_kb) / 15`. - receive_single_message_proof_1_kb { - let relayer_id_on_source = T::bridged_relayer_id(); - let relayer_id_on_target = account("relayer", 0, SEED); - T::endow_account(&relayer_id_on_target); - - // mark messages 1..=20 as delivered - receive_messages::<T, I>(20); - let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { - lane: T::bench_lane_id(), - message_nonces: 21..=21, - outbound_lane_data: None, - is_successful_dispatch_expected: false, - size: StorageProofSize::HasLargeLeaf(1024), - }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(), - 21, + #[extrinsic_call] + receive_messages_proof( + RawOrigin::Signed(setup.relayer_id_on_tgt()), + setup.relayer_id_on_src(), + Box::new(proof), + setup.msgs_count, + dispatch_weight, ); + + // verification code + setup.check_last_nonce(); } - // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions: - // * the proof has large leaf with total size of approximately 16KB; + // Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following + // conditions: + // * the proof has large leaf with total size ranging between 1KB and 16KB; // * proof does not include outbound lane state proof; // * inbound lane already has state, so it needs to be read and decoded; // * message is dispatched (reminder: dispatch weight should be minimal); // * message requires all heavy checks done by dispatcher. - // - // Size of proof grows because it contains extra trie nodes in it. - // - // With single KB of messages proof, the weight of the call is increased (roughly) by - // `(receive_single_message_proof_16KB - receive_single_message_proof) / 15`. - receive_single_message_proof_16_kb { - let relayer_id_on_source = T::bridged_relayer_id(); - let relayer_id_on_target = account("relayer", 0, SEED); - T::endow_account(&relayer_id_on_target); - - // mark messages 1..=20 as delivered - receive_messages::<T, I>(20); - + #[benchmark] + fn receive_single_n_bytes_message_proof( + /// Proof size in KB + n: Linear<1, { 16 * 1024 }>, + ) { + // setup code + let setup = ReceiveMessagesProofSetup::<T, I>::new(1); let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { lane: T::bench_lane_id(), - message_nonces: 21..=21, + message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: false, - size: StorageProofSize::HasLargeLeaf(16 * 1024), + proof_params: UnverifiedStorageProofParams::from_db_size(n), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(), - 21, + + #[extrinsic_call] + receive_messages_proof( + RawOrigin::Signed(setup.relayer_id_on_tgt()), + setup.relayer_id_on_src(), + Box::new(proof), + setup.msgs_count, + dispatch_weight, ); + + // verification code + setup.check_last_nonce(); } // Benchmark `receive_messages_delivery_proof` extrinsic with following conditions: @@ -284,7 +340,8 @@ benchmarks_instance_pallet! { // * relayer account does not exist (in practice it needs to exist in production environment). // // This is base benchmark for all other confirmations delivery benchmarks. - receive_delivery_proof_for_single_message { + #[benchmark] + fn receive_delivery_proof_for_single_message() { let relayer_id: T::AccountId = account("relayer", 0, SEED); // send message that we're going to confirm @@ -302,13 +359,21 @@ benchmarks_instance_pallet! { relayers: vec![UnrewardedRelayer { relayer: relayer_id.clone(), messages: DeliveredMessages::new(1), - }].into_iter().collect(), + }] + .into_iter() + .collect(), last_confirmed_nonce: 0, }, - size: StorageProofSize::Minimal(0), + proof_params: UnverifiedStorageProofParams::default(), }); - }: receive_messages_delivery_proof(RawOrigin::Signed(relayer_id.clone()), proof, relayers_state) - verify { + + #[extrinsic_call] + receive_messages_delivery_proof( + RawOrigin::Signed(relayer_id.clone()), + proof, + relayers_state, + ); + assert_eq!(OutboundLanes::<T, I>::get(T::bench_lane_id()).latest_received_nonce, 1); assert!(T::is_relayer_rewarded(&relayer_id)); } @@ -320,7 +385,8 @@ benchmarks_instance_pallet! { // Additional weight for paying single-message reward to the same relayer could be computed // as `weight(receive_delivery_proof_for_two_messages_by_single_relayer) // - weight(receive_delivery_proof_for_single_message)`. - receive_delivery_proof_for_two_messages_by_single_relayer { + #[benchmark] + fn receive_delivery_proof_for_two_messages_by_single_relayer() { let relayer_id: T::AccountId = account("relayer", 0, SEED); // send message that we're going to confirm @@ -341,13 +407,21 @@ benchmarks_instance_pallet! { relayers: vec![UnrewardedRelayer { relayer: relayer_id.clone(), messages: delivered_messages, - }].into_iter().collect(), + }] + .into_iter() + .collect(), last_confirmed_nonce: 0, }, - size: StorageProofSize::Minimal(0), + proof_params: UnverifiedStorageProofParams::default(), }); - }: receive_messages_delivery_proof(RawOrigin::Signed(relayer_id.clone()), proof, relayers_state) - verify { + + #[extrinsic_call] + receive_messages_delivery_proof( + RawOrigin::Signed(relayer_id.clone()), + proof, + relayers_state, + ); + assert_eq!(OutboundLanes::<T, I>::get(T::bench_lane_id()).latest_received_nonce, 2); assert!(T::is_relayer_rewarded(&relayer_id)); } @@ -359,7 +433,8 @@ benchmarks_instance_pallet! { // Additional weight for paying reward to the next relayer could be computed // as `weight(receive_delivery_proof_for_two_messages_by_two_relayers) // - weight(receive_delivery_proof_for_two_messages_by_single_relayer)`. - receive_delivery_proof_for_two_messages_by_two_relayers { + #[benchmark] + fn receive_delivery_proof_for_two_messages_by_two_relayers() { let relayer1_id: T::AccountId = account("relayer1", 1, SEED); let relayer2_id: T::AccountId = account("relayer2", 2, SEED); @@ -385,13 +460,21 @@ benchmarks_instance_pallet! { relayer: relayer2_id.clone(), messages: DeliveredMessages::new(2), }, - ].into_iter().collect(), + ] + .into_iter() + .collect(), last_confirmed_nonce: 0, }, - size: StorageProofSize::Minimal(0), + proof_params: UnverifiedStorageProofParams::default(), }); - }: receive_messages_delivery_proof(RawOrigin::Signed(relayer1_id.clone()), proof, relayers_state) - verify { + + #[extrinsic_call] + receive_messages_delivery_proof( + RawOrigin::Signed(relayer1_id.clone()), + proof, + relayers_state, + ); + assert_eq!(OutboundLanes::<T, I>::get(T::bench_lane_id()).latest_received_nonce, 2); assert!(T::is_relayer_rewarded(&relayer1_id)); assert!(T::is_relayer_rewarded(&relayer2_id)); @@ -411,51 +494,38 @@ benchmarks_instance_pallet! { // * inbound lane already has state, so it needs to be read and decoded; // * message is **SUCCESSFULLY** dispatched; // * message requires all heavy checks done by dispatcher. - receive_single_message_proof_with_dispatch { - // maybe dispatch weight relies on the message size too? - let i in EXPECTED_DEFAULT_MESSAGE_LENGTH .. EXPECTED_DEFAULT_MESSAGE_LENGTH * 16; - - let relayer_id_on_source = T::bridged_relayer_id(); - let relayer_id_on_target = account("relayer", 0, SEED); - T::endow_account(&relayer_id_on_target); - - // mark messages 1..=20 as delivered - receive_messages::<T, I>(20); - + #[benchmark] + fn receive_single_n_bytes_message_proof_with_dispatch( + /// Proof size in KB + n: Linear<1, { 16 * 1024 }>, + ) { + // setup code + let setup = ReceiveMessagesProofSetup::<T, I>::new(1); let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { lane: T::bench_lane_id(), - message_nonces: 21..=21, + message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: true, - size: StorageProofSize::Minimal(i), + proof_params: UnverifiedStorageProofParams::from_db_size(n), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(), - 21, - ); - assert!(T::is_message_successfully_dispatched(21)); - } - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) -} + #[extrinsic_call] + receive_messages_proof( + RawOrigin::Signed(setup.relayer_id_on_tgt()), + setup.relayer_id_on_src(), + Box::new(proof), + setup.msgs_count, + dispatch_weight, + ); -fn send_regular_message<T: Config<I>, I: 'static>() { - let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id()); - outbound_lane.send_message(BoundedVec::try_from(vec![]).expect("We craft valid messages")); -} + // verification code + setup.check_last_nonce(); + assert!(T::is_message_successfully_dispatched(setup.last_nonce())); + } -fn receive_messages<T: Config<I>, I: 'static>(nonce: MessageNonce) { - let mut inbound_lane_storage = - RuntimeInboundLaneStorage::<T, I>::from_lane_id(T::bench_lane_id()); - inbound_lane_storage.set_data(InboundLaneData { - relayers: vec![UnrewardedRelayer { - relayer: T::bridged_relayer_id(), - messages: DeliveredMessages::new(nonce), - }] - .into_iter() - .collect(), - last_confirmed_nonce: 0, - }); + impl_benchmark_test_suite!( + Pallet, + crate::tests::mock::new_test_ext(), + crate::tests::mock::TestRuntime + ); } diff --git a/bridges/modules/messages/src/inbound_lane.rs b/bridges/modules/messages/src/inbound_lane.rs index da1698e6e0370f9f84ca8dd53bc1ebc99f696017..7ef4599a93c4823a9be7fa918b35c309cea6611a 100644 --- a/bridges/modules/messages/src/inbound_lane.rs +++ b/bridges/modules/messages/src/inbound_lane.rs @@ -16,15 +16,15 @@ //! Everything about incoming messages receival. -use crate::Config; +use crate::{BridgedChainOf, Config}; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, - DeliveredMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, OutboundLaneData, - ReceptionResult, UnrewardedRelayer, + ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, + OutboundLaneData, ReceptionResult, UnrewardedRelayer, }; +use bp_runtime::AccountIdOf; use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; -use frame_support::traits::Get; use scale_info::{Type, TypeInfo}; use sp_runtime::RuntimeDebug; use sp_std::prelude::PartialEq; @@ -55,10 +55,12 @@ pub trait InboundLaneStorage { /// /// The encoding of this type matches encoding of the corresponding `MessageData`. #[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)] -pub struct StoredInboundLaneData<T: Config<I>, I: 'static>(pub InboundLaneData<T::InboundRelayer>); +pub struct StoredInboundLaneData<T: Config<I>, I: 'static>( + pub InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>, +); impl<T: Config<I>, I: 'static> sp_std::ops::Deref for StoredInboundLaneData<T, I> { - type Target = InboundLaneData<T::InboundRelayer>; + type Target = InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>; fn deref(&self) -> &Self::Target { &self.0 @@ -78,7 +80,7 @@ impl<T: Config<I>, I: 'static> Default for StoredInboundLaneData<T, I> { } impl<T: Config<I>, I: 'static> From<StoredInboundLaneData<T, I>> - for InboundLaneData<T::InboundRelayer> + for InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>> { fn from(data: StoredInboundLaneData<T, I>) -> Self { data.0 @@ -86,7 +88,7 @@ impl<T: Config<I>, I: 'static> From<StoredInboundLaneData<T, I>> } impl<T: Config<I>, I: 'static> EncodeLike<StoredInboundLaneData<T, I>> - for InboundLaneData<T::InboundRelayer> + for InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>> { } @@ -94,14 +96,14 @@ impl<T: Config<I>, I: 'static> TypeInfo for StoredInboundLaneData<T, I> { type Identity = Self; fn type_info() -> Type { - InboundLaneData::<T::InboundRelayer>::type_info() + InboundLaneData::<AccountIdOf<BridgedChainOf<T, I>>>::type_info() } } impl<T: Config<I>, I: 'static> MaxEncodedLen for StoredInboundLaneData<T, I> { fn max_encoded_len() -> usize { - InboundLaneData::<T::InboundRelayer>::encoded_size_hint( - T::MaxUnrewardedRelayerEntriesAtInboundLane::get() as usize, + InboundLaneData::<AccountIdOf<BridgedChainOf<T, I>>>::encoded_size_hint( + BridgedChainOf::<T, I>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as usize, ) .unwrap_or(usize::MAX) } @@ -216,10 +218,10 @@ mod tests { use super::*; use crate::{ inbound_lane, - mock::{ + tests::mock::{ dispatch_result, inbound_message_data, inbound_unrewarded_relayers_state, run_test, - unrewarded_relayer, TestMessageDispatch, TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, - TEST_RELAYER_A, TEST_RELAYER_B, TEST_RELAYER_C, + unrewarded_relayer, BridgedChain, TestMessageDispatch, TestRuntime, REGULAR_PAYLOAD, + TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B, TEST_RELAYER_C, }, RuntimeInboundLaneStorage, }; @@ -372,8 +374,7 @@ mod tests { fn fails_to_receive_messages_above_unrewarded_relayer_entries_limit_per_lane() { run_test(|| { let mut lane = inbound_lane::<TestRuntime, _>(TEST_LANE_ID); - let max_nonce = - <TestRuntime as Config>::MaxUnrewardedRelayerEntriesAtInboundLane::get(); + let max_nonce = BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; for current_nonce in 1..max_nonce + 1 { assert_eq!( lane.receive_message::<TestMessageDispatch>( @@ -409,7 +410,7 @@ mod tests { fn fails_to_receive_messages_above_unconfirmed_messages_limit_per_lane() { run_test(|| { let mut lane = inbound_lane::<TestRuntime, _>(TEST_LANE_ID); - let max_nonce = <TestRuntime as Config>::MaxUnconfirmedMessagesAtInboundLane::get(); + let max_nonce = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; for current_nonce in 1..=max_nonce { assert_eq!( lane.receive_message::<TestMessageDispatch>( diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index e31a4542056cb30466f236d0dc9957c053a03f66..bf105b14040185f61e627a35f4f53b3a66b48c19 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -41,8 +41,8 @@ pub use outbound_lane::StoredMessagePayload; pub use weights::WeightInfo; pub use weights_ext::{ ensure_able_to_receive_confirmation, ensure_able_to_receive_message, - ensure_weights_are_correct, WeightInfoExt, EXPECTED_DEFAULT_MESSAGE_LENGTH, - EXTRA_STORAGE_PROOF_SIZE, + ensure_maximal_message_dispatch, ensure_weights_are_correct, WeightInfoExt, + EXPECTED_DEFAULT_MESSAGE_LENGTH, EXTRA_STORAGE_PROOF_SIZE, }; use crate::{ @@ -50,20 +50,23 @@ use crate::{ outbound_lane::{OutboundLane, OutboundLaneStorage, ReceptionConfirmationError}, }; +use bp_header_chain::HeaderChain; use bp_messages::{ source_chain::{ - DeliveryConfirmationPayments, OnMessagesDelivered, SendMessageArtifacts, TargetHeaderChain, + DeliveryConfirmationPayments, FromBridgedChainMessagesDeliveryProof, OnMessagesDelivered, + SendMessageArtifacts, }, target_chain::{ - DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, - SourceHeaderChain, + DeliveryPayments, DispatchMessage, FromBridgedChainMessagesProof, MessageDispatch, + ProvedLaneMessages, ProvedMessages, }, - DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, MessageKey, MessageNonce, - MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, - UnrewardedRelayersState, VerificationError, + ChainWithMessages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, + MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, + OutboundMessageDetails, UnrewardedRelayersState, VerificationError, }; use bp_runtime::{ - BasicOperatingMode, ChainId, OwnedBridgeModule, PreComputedSize, RangeInclusiveExt, Size, + AccountIdOf, BasicOperatingMode, HashOf, OwnedBridgeModule, PreComputedSize, RangeInclusiveExt, + Size, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound}; @@ -72,6 +75,8 @@ use sp_std::{marker::PhantomData, prelude::*}; mod inbound_lane; mod outbound_lane; +mod proofs; +mod tests; mod weights_ext; pub mod weights; @@ -79,10 +84,9 @@ pub mod weights; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; -#[cfg(test)] -mod mock; - pub use pallet::*; +#[cfg(feature = "test-helpers")] +pub use tests::*; /// The target that will be used when publishing logs related to this pallet. pub const LOG_TARGET: &str = "runtime::bridge-messages"; @@ -105,76 +109,39 @@ pub mod pallet { /// Benchmarks results from runtime we're plugged into. type WeightInfo: WeightInfoExt; - /// Gets the chain id value from the instance. - #[pallet::constant] - type BridgedChainId: Get<ChainId>; + /// This chain type. + type ThisChain: ChainWithMessages; + /// Bridged chain type. + type BridgedChain: ChainWithMessages; + /// Bridged chain headers provider. + type BridgedHeaderChain: HeaderChain<Self::BridgedChain>; /// Get all active outbound lanes that the message pallet is serving. type ActiveOutboundLanes: Get<&'static [LaneId]>; - /// Maximal number of unrewarded relayer entries at inbound lane. Unrewarded means that the - /// relayer has delivered messages, but either confirmations haven't been delivered back to - /// the source chain, or we haven't received reward confirmations yet. - /// - /// This constant limits maximal number of entries in the `InboundLaneData::relayers`. Keep - /// in mind that the same relayer account may take several (non-consecutive) entries in this - /// set. - type MaxUnrewardedRelayerEntriesAtInboundLane: Get<MessageNonce>; - /// Maximal number of unconfirmed messages at inbound lane. Unconfirmed means that the - /// message has been delivered, but either confirmations haven't been delivered back to the - /// source chain, or we haven't received reward confirmations for these messages yet. - /// - /// This constant limits difference between last message from last entry of the - /// `InboundLaneData::relayers` and first message at the first entry. - /// - /// There is no point of making this parameter lesser than - /// MaxUnrewardedRelayerEntriesAtInboundLane, because then maximal number of relayer entries - /// will be limited by maximal number of messages. - /// - /// This value also represents maximal number of messages in single delivery transaction. - /// Transaction that is declaring more messages than this value, will be rejected. Even if - /// these messages are from different lanes. - type MaxUnconfirmedMessagesAtInboundLane: Get<MessageNonce>; - - /// Maximal encoded size of the outbound payload. - #[pallet::constant] - type MaximalOutboundPayloadSize: Get<u32>; + /// Payload type of outbound messages. This payload is dispatched on the bridged chain. type OutboundPayload: Parameter + Size; - /// Payload type of inbound messages. This payload is dispatched on this chain. type InboundPayload: Decode; - /// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the - /// bridged chain. - type InboundRelayer: Parameter + MaxEncodedLen; - /// Delivery payments. - type DeliveryPayments: DeliveryPayments<Self::AccountId>; - - // Types that are used by outbound_lane (on source chain). - /// Target header chain. - type TargetHeaderChain: TargetHeaderChain<Self::OutboundPayload, Self::AccountId>; - /// Delivery confirmation payments. + /// Handler for relayer payments that happen during message delivery transaction. + type DeliveryPayments: DeliveryPayments<Self::AccountId>; + /// Handler for relayer payments that happen during message delivery confirmation + /// transaction. type DeliveryConfirmationPayments: DeliveryConfirmationPayments<Self::AccountId>; /// Delivery confirmation callback. type OnMessagesDelivered: OnMessagesDelivered; - // Types that are used by inbound_lane (on target chain). - - /// Source header chain, as it is represented on target chain. - type SourceHeaderChain: SourceHeaderChain; - /// Message dispatch. + /// Message dispatch handler. type MessageDispatch: MessageDispatch<DispatchPayload = Self::InboundPayload>; } - /// Shortcut to messages proof type for Config. - pub type MessagesProofOf<T, I> = - <<T as Config<I>>::SourceHeaderChain as SourceHeaderChain>::MessagesProof; - /// Shortcut to messages delivery proof type for Config. - pub type MessagesDeliveryProofOf<T, I> = - <<T as Config<I>>::TargetHeaderChain as TargetHeaderChain< - <T as Config<I>>::OutboundPayload, - <T as frame_system::Config>::AccountId, - >>::MessagesDeliveryProof; + /// Shortcut to this chain type for Config. + pub type ThisChainOf<T, I> = <T as Config<I>>::ThisChain; + /// Shortcut to bridged chain type for Config. + pub type BridgedChainOf<T, I> = <T as Config<I>>::BridgedChain; + /// Shortcut to bridged header chain type for Config. + pub type BridgedHeaderChainOf<T, I> = <T as Config<I>>::BridgedHeaderChain; #[pallet::pallet] pub struct Pallet<T, I = ()>(PhantomData<(T, I)>); @@ -265,11 +232,11 @@ pub mod pallet { /// The call may succeed, but some messages may not be delivered e.g. if they are not fit /// into the unrewarded relayers vector. #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::receive_messages_proof_weight(proof, *messages_count, *dispatch_weight))] + #[pallet::weight(T::WeightInfo::receive_messages_proof_weight(&**proof, *messages_count, *dispatch_weight))] pub fn receive_messages_proof( origin: OriginFor<T>, - relayer_id_at_bridged_chain: T::InboundRelayer, - proof: MessagesProofOf<T, I>, + relayer_id_at_bridged_chain: AccountIdOf<BridgedChainOf<T, I>>, + proof: Box<FromBridgedChainMessagesProof<HashOf<BridgedChainOf<T, I>>>>, messages_count: u32, dispatch_weight: Weight, ) -> DispatchResultWithPostInfo { @@ -278,7 +245,8 @@ pub mod pallet { // reject transactions that are declaring too many messages ensure!( - MessageNonce::from(messages_count) <= T::MaxUnconfirmedMessagesAtInboundLane::get(), + MessageNonce::from(messages_count) <= + BridgedChainOf::<T, I>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, Error::<T, I>::TooManyMessagesInTheProof ); @@ -296,22 +264,19 @@ pub mod pallet { // The DeclaredWeight is exactly what's computed here. Unfortunately it is impossible // to get pre-computed value (and it has been already computed by the executive). let declared_weight = T::WeightInfo::receive_messages_proof_weight( - &proof, + &*proof, messages_count, dispatch_weight, ); let mut actual_weight = declared_weight; // verify messages proof && convert proof into messages - let messages = verify_and_decode_messages_proof::< - T::SourceHeaderChain, - T::InboundPayload, - >(proof, messages_count) - .map_err(|err| { - log::trace!(target: LOG_TARGET, "Rejecting invalid messages proof: {:?}", err,); + let messages = verify_and_decode_messages_proof::<T, I>(*proof, messages_count) + .map_err(|err| { + log::trace!(target: LOG_TARGET, "Rejecting invalid messages proof: {:?}", err,); - Error::<T, I>::InvalidMessagesProof - })?; + Error::<T, I>::InvalidMessagesProof + })?; // dispatch messages and (optionally) update lane(s) state(s) let mut total_messages = 0; @@ -424,14 +389,14 @@ pub mod pallet { ))] pub fn receive_messages_delivery_proof( origin: OriginFor<T>, - proof: MessagesDeliveryProofOf<T, I>, + proof: FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<T, I>>>, mut relayers_state: UnrewardedRelayersState, ) -> DispatchResultWithPostInfo { Self::ensure_not_halted().map_err(Error::<T, I>::BridgeModule)?; let proof_size = proof.size(); let confirmation_relayer = ensure_signed(origin)?; - let (lane_id, lane_data) = T::TargetHeaderChain::verify_messages_delivery_proof(proof) + let (lane_id, lane_data) = proofs::verify_messages_delivery_proof::<T, I>(proof) .map_err(|err| { log::trace!( target: LOG_TARGET, @@ -542,8 +507,6 @@ pub mod pallet { InactiveOutboundLane, /// The inbound message dispatcher is inactive. MessageDispatchInactive, - /// Message has been treated as invalid by chain verifier. - MessageRejectedByChainVerifier(VerificationError), /// Message has been treated as invalid by the pallet logic. MessageRejectedByPallet(VerificationError), /// Submitter has failed to pay fee for delivering and dispatching messages. @@ -674,7 +637,9 @@ pub mod pallet { } /// Return inbound lane data. - pub fn inbound_lane_data(lane: LaneId) -> InboundLaneData<T::InboundRelayer> { + pub fn inbound_lane_data( + lane: LaneId, + ) -> InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>> { InboundLanes::<T, I>::get(lane).0 } } @@ -714,18 +679,6 @@ where // let's check if outbound lane is active ensure!(T::ActiveOutboundLanes::get().contains(&lane), Error::<T, I>::InactiveOutboundLane); - // let's first check if message can be delivered to target chain - T::TargetHeaderChain::verify_message(message).map_err(|err| { - log::trace!( - target: LOG_TARGET, - "Message to lane {:?} is rejected by target chain: {:?}", - lane, - err, - ); - - Error::<T, I>::MessageRejectedByChainVerifier(err) - })?; - Ok(SendMessageArgs { lane_id: lane, payload: StoredMessagePayload::<T, I>::try_from(message.encode()).map_err(|_| { @@ -785,7 +738,7 @@ fn outbound_lane<T: Config<I>, I: 'static>( /// Runtime inbound lane storage. struct RuntimeInboundLaneStorage<T: Config<I>, I: 'static = ()> { lane_id: LaneId, - cached_data: Option<InboundLaneData<T::InboundRelayer>>, + cached_data: Option<InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>>, _phantom: PhantomData<I>, } @@ -802,39 +755,39 @@ impl<T: Config<I>, I: 'static> RuntimeInboundLaneStorage<T, I> { /// maximal configured. /// /// Maximal inbound lane state set size is configured by the - /// `MaxUnrewardedRelayerEntriesAtInboundLane` constant from the pallet configuration. The PoV + /// `MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX` constant from the pallet configuration. The PoV /// of the call includes the maximal size of inbound lane state. If the actual size is smaller, /// we may subtract extra bytes from this component. pub fn extra_proof_size_bytes(&mut self) -> u64 { let max_encoded_len = StoredInboundLaneData::<T, I>::max_encoded_len(); let relayers_count = self.get_or_init_data().relayers.len(); let actual_encoded_len = - InboundLaneData::<T::InboundRelayer>::encoded_size_hint(relayers_count) + InboundLaneData::<AccountIdOf<BridgedChainOf<T, I>>>::encoded_size_hint(relayers_count) .unwrap_or(usize::MAX); max_encoded_len.saturating_sub(actual_encoded_len) as _ } } impl<T: Config<I>, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage<T, I> { - type Relayer = T::InboundRelayer; + type Relayer = AccountIdOf<BridgedChainOf<T, I>>; fn id(&self) -> LaneId { self.lane_id } fn max_unrewarded_relayer_entries(&self) -> MessageNonce { - T::MaxUnrewardedRelayerEntriesAtInboundLane::get() + BridgedChainOf::<T, I>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX } fn max_unconfirmed_messages(&self) -> MessageNonce { - T::MaxUnconfirmedMessagesAtInboundLane::get() + BridgedChainOf::<T, I>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX } - fn get_or_init_data(&mut self) -> InboundLaneData<T::InboundRelayer> { + fn get_or_init_data(&mut self) -> InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>> { match self.cached_data { Some(ref data) => data.clone(), None => { - let data: InboundLaneData<T::InboundRelayer> = + let data: InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>> = InboundLanes::<T, I>::get(self.lane_id).into(); self.cached_data = Some(data.clone()); data @@ -842,7 +795,7 @@ impl<T: Config<I>, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage< } } - fn set_data(&mut self, data: InboundLaneData<T::InboundRelayer>) { + fn set_data(&mut self, data: InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>) { self.cached_data = Some(data.clone()); InboundLanes::<T, I>::insert(self.lane_id, StoredInboundLaneData::<T, I>(data)) } @@ -887,14 +840,14 @@ impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag } /// Verify messages proof and return proved messages with decoded payload. -fn verify_and_decode_messages_proof<Chain: SourceHeaderChain, DispatchPayload: Decode>( - proof: Chain::MessagesProof, +fn verify_and_decode_messages_proof<T: Config<I>, I: 'static>( + proof: FromBridgedChainMessagesProof<HashOf<BridgedChainOf<T, I>>>, messages_count: u32, -) -> Result<ProvedMessages<DispatchMessage<DispatchPayload>>, VerificationError> { - // `receive_messages_proof` weight formula and `MaxUnconfirmedMessagesAtInboundLane` check - // guarantees that the `message_count` is sane and Vec<Message> may be allocated. +) -> Result<ProvedMessages<DispatchMessage<T::InboundPayload>>, VerificationError> { + // `receive_messages_proof` weight formula and `MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX` + // check guarantees that the `message_count` is sane and Vec<Message> may be allocated. // (tx with too many messages will either be rejected from the pool, or will fail earlier) - Chain::verify_messages_proof(proof, messages_count).map(|messages_by_lane| { + proofs::verify_messages_proof::<T, I>(proof, messages_count).map(|messages_by_lane| { messages_by_lane .into_iter() .map(|(lane, lane_data)| { @@ -909,1209 +862,3 @@ fn verify_and_decode_messages_proof<Chain: SourceHeaderChain, DispatchPayload: D .collect() }) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - mock::{ - inbound_unrewarded_relayers_state, message, message_payload, run_test, - unrewarded_relayer, AccountId, DbWeight, RuntimeEvent as TestEvent, RuntimeOrigin, - TestDeliveryConfirmationPayments, TestDeliveryPayments, TestMessageDispatch, - TestMessagesDeliveryProof, TestMessagesProof, TestOnMessagesDelivered, TestRelayer, - TestRuntime, TestWeightInfo, MAX_OUTBOUND_PAYLOAD_SIZE, - PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2, - TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B, - }, - outbound_lane::ReceptionConfirmationError, - }; - use bp_messages::{ - source_chain::MessagesBridge, BridgeMessagesCall, UnrewardedRelayer, - UnrewardedRelayersState, - }; - use bp_test_utils::generate_owned_bridge_module_tests; - use frame_support::{ - assert_noop, assert_ok, - dispatch::Pays, - storage::generator::{StorageMap, StorageValue}, - traits::Hooks, - weights::Weight, - }; - use frame_system::{EventRecord, Pallet as System, Phase}; - use sp_runtime::DispatchError; - - fn get_ready_for_events() { - System::<TestRuntime>::set_block_number(1); - System::<TestRuntime>::reset_events(); - } - - fn send_regular_message(lane_id: LaneId) { - get_ready_for_events(); - - let outbound_lane = outbound_lane::<TestRuntime, ()>(lane_id); - let message_nonce = outbound_lane.data().latest_generated_nonce + 1; - let prev_enqueued_messages = outbound_lane.data().queued_messages().saturating_len(); - let valid_message = Pallet::<TestRuntime, ()>::validate_message(lane_id, ®ULAR_PAYLOAD) - .expect("validate_message has failed"); - let artifacts = Pallet::<TestRuntime, ()>::send_message(valid_message); - assert_eq!(artifacts.enqueued_messages, prev_enqueued_messages + 1); - - // check event with assigned nonce - assert_eq!( - System::<TestRuntime>::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: TestEvent::Messages(Event::MessageAccepted { - lane_id, - nonce: message_nonce - }), - topics: vec![], - }], - ); - } - - fn receive_messages_delivery_proof() { - System::<TestRuntime>::set_block_number(1); - System::<TestRuntime>::reset_events(); - - assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 1, - relayers: vec![UnrewardedRelayer { - relayer: 0, - messages: DeliveredMessages::new(1), - }] - .into_iter() - .collect(), - }, - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 1, - }, - )); - - assert_eq!( - System::<TestRuntime>::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: TestEvent::Messages(Event::MessagesDelivered { - lane_id: TEST_LANE_ID, - messages: DeliveredMessages::new(1), - }), - topics: vec![], - }], - ); - } - - #[test] - fn pallet_rejects_transactions_if_halted() { - run_test(|| { - // send message first to be able to check that delivery_proof fails later - send_regular_message(TEST_LANE_ID); - - PalletOperatingMode::<TestRuntime, ()>::put(MessagesOperatingMode::Basic( - BasicOperatingMode::Halted, - )); - - assert_noop!( - Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), - Error::<TestRuntime, ()>::NotOperatingNormally, - ); - - assert_noop!( - Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(2, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - ), - Error::<TestRuntime, ()>::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), - ); - - assert_noop!( - Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 1, - relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)] - .into_iter() - .collect(), - }, - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 1, - }, - ), - Error::<TestRuntime, ()>::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), - ); - }); - } - - #[test] - fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { - run_test(|| { - // send message first to be able to check that delivery_proof fails later - send_regular_message(TEST_LANE_ID); - - PalletOperatingMode::<TestRuntime, ()>::put( - MessagesOperatingMode::RejectingOutboundMessages, - ); - - assert_noop!( - Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), - Error::<TestRuntime, ()>::NotOperatingNormally, - ); - - assert_ok!(Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - ),); - - assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 1, - relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)] - .into_iter() - .collect(), - }, - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 1, - }, - )); - }); - } - - #[test] - fn send_message_works() { - run_test(|| { - send_regular_message(TEST_LANE_ID); - }); - } - - #[test] - fn send_message_rejects_too_large_message() { - run_test(|| { - let mut message_payload = message_payload(1, 0); - // the payload isn't simply extra, so it'll definitely overflow - // `MAX_OUTBOUND_PAYLOAD_SIZE` if we add `MAX_OUTBOUND_PAYLOAD_SIZE` bytes to extra - message_payload - .extra - .extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]); - assert_noop!( - Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &message_payload.clone(),), - Error::<TestRuntime, ()>::MessageRejectedByPallet( - VerificationError::MessageTooLarge - ), - ); - - // let's check that we're able to send `MAX_OUTBOUND_PAYLOAD_SIZE` messages - while message_payload.encoded_size() as u32 > MAX_OUTBOUND_PAYLOAD_SIZE { - message_payload.extra.pop(); - } - assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE); - - let valid_message = - Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &message_payload) - .expect("validate_message has failed"); - Pallet::<TestRuntime, ()>::send_message(valid_message); - }) - } - - #[test] - fn chain_verifier_rejects_invalid_message_in_send_message() { - run_test(|| { - // messages with this payload are rejected by target chain verifier - assert_noop!( - Pallet::<TestRuntime, ()>::validate_message( - TEST_LANE_ID, - &PAYLOAD_REJECTED_BY_TARGET_CHAIN, - ), - Error::<TestRuntime, ()>::MessageRejectedByChainVerifier(VerificationError::Other( - mock::TEST_ERROR - )), - ); - }); - } - - #[test] - fn receive_messages_proof_works() { - run_test(|| { - assert_ok!(Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - )); - - assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).0.last_delivered_nonce(), 1); - - assert!(TestDeliveryPayments::is_reward_paid(1)); - }); - } - - #[test] - fn receive_messages_proof_updates_confirmed_message_nonce() { - run_test(|| { - // say we have received 10 messages && last confirmed message is 8 - InboundLanes::<TestRuntime, ()>::insert( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 8, - relayers: vec![ - unrewarded_relayer(9, 9, TEST_RELAYER_A), - unrewarded_relayer(10, 10, TEST_RELAYER_B), - ] - .into_iter() - .collect(), - }, - ); - assert_eq!( - inbound_unrewarded_relayers_state(TEST_LANE_ID), - UnrewardedRelayersState { - unrewarded_relayer_entries: 2, - messages_in_oldest_entry: 1, - total_messages: 2, - last_delivered_nonce: 10, - }, - ); - - // message proof includes outbound lane state with latest confirmed message updated to 9 - let mut message_proof: TestMessagesProof = - Ok(vec![message(11, REGULAR_PAYLOAD)]).into(); - message_proof.result.as_mut().unwrap()[0].1.lane_state = - Some(OutboundLaneData { latest_received_nonce: 9, ..Default::default() }); - - assert_ok!(Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - message_proof, - 1, - REGULAR_PAYLOAD.declared_weight, - )); - - assert_eq!( - InboundLanes::<TestRuntime>::get(TEST_LANE_ID).0, - InboundLaneData { - last_confirmed_nonce: 9, - relayers: vec![ - unrewarded_relayer(10, 10, TEST_RELAYER_B), - unrewarded_relayer(11, 11, TEST_RELAYER_A) - ] - .into_iter() - .collect(), - }, - ); - assert_eq!( - inbound_unrewarded_relayers_state(TEST_LANE_ID), - UnrewardedRelayersState { - unrewarded_relayer_entries: 2, - messages_in_oldest_entry: 1, - total_messages: 2, - last_delivered_nonce: 11, - }, - ); - }); - } - - #[test] - fn receive_messages_fails_if_dispatcher_is_inactive() { - run_test(|| { - TestMessageDispatch::deactivate(); - assert_noop!( - Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - ), - Error::<TestRuntime, ()>::MessageDispatchInactive, - ); - }); - } - - #[test] - fn receive_messages_proof_does_not_accept_message_if_dispatch_weight_is_not_enough() { - run_test(|| { - let mut declared_weight = REGULAR_PAYLOAD.declared_weight; - *declared_weight.ref_time_mut() -= 1; - assert_noop!( - Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - declared_weight, - ), - Error::<TestRuntime, ()>::InsufficientDispatchWeight - ); - assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 0); - }); - } - - #[test] - fn receive_messages_proof_rejects_invalid_proof() { - run_test(|| { - assert_noop!( - Pallet::<TestRuntime, ()>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Err(()).into(), - 1, - Weight::zero(), - ), - Error::<TestRuntime, ()>::InvalidMessagesProof, - ); - }); - } - - #[test] - fn receive_messages_proof_rejects_proof_with_too_many_messages() { - run_test(|| { - assert_noop!( - Pallet::<TestRuntime, ()>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - u32::MAX, - Weight::zero(), - ), - Error::<TestRuntime, ()>::TooManyMessagesInTheProof, - ); - }); - } - - #[test] - fn receive_messages_delivery_proof_works() { - run_test(|| { - send_regular_message(TEST_LANE_ID); - receive_messages_delivery_proof(); - - assert_eq!( - OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).latest_received_nonce, - 1, - ); - }); - } - - #[test] - fn receive_messages_delivery_proof_rewards_relayers() { - run_test(|| { - send_regular_message(TEST_LANE_ID); - send_regular_message(TEST_LANE_ID); - - // this reports delivery of message 1 => reward is paid to TEST_RELAYER_A - let single_message_delivery_proof = TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)].into_iter().collect(), - ..Default::default() - }, - ))); - let single_message_delivery_proof_size = single_message_delivery_proof.size(); - let result = Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - single_message_delivery_proof, - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 1, - }, - ); - assert_ok!(result); - assert_eq!( - result.unwrap().actual_weight.unwrap(), - TestWeightInfo::receive_messages_delivery_proof_weight( - &PreComputedSize(single_message_delivery_proof_size as _), - &UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - total_messages: 1, - ..Default::default() - }, - ) - ); - assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1)); - assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1)); - assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 1))); - - // this reports delivery of both message 1 and message 2 => reward is paid only to - // TEST_RELAYER_B - let two_messages_delivery_proof = TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - relayers: vec![ - unrewarded_relayer(1, 1, TEST_RELAYER_A), - unrewarded_relayer(2, 2, TEST_RELAYER_B), - ] - .into_iter() - .collect(), - ..Default::default() - }, - ))); - let two_messages_delivery_proof_size = two_messages_delivery_proof.size(); - let result = Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - two_messages_delivery_proof, - UnrewardedRelayersState { - unrewarded_relayer_entries: 2, - messages_in_oldest_entry: 1, - total_messages: 2, - last_delivered_nonce: 2, - }, - ); - assert_ok!(result); - // even though the pre-dispatch weight was for two messages, the actual weight is - // for single message only - assert_eq!( - result.unwrap().actual_weight.unwrap(), - TestWeightInfo::receive_messages_delivery_proof_weight( - &PreComputedSize(two_messages_delivery_proof_size as _), - &UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - total_messages: 1, - ..Default::default() - }, - ) - ); - assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1)); - assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1)); - assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 0))); - }); - } - - #[test] - fn receive_messages_delivery_proof_rejects_invalid_proof() { - run_test(|| { - assert_noop!( - Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Err(())), - Default::default(), - ), - Error::<TestRuntime, ()>::InvalidMessagesDeliveryProof, - ); - }); - } - - #[test] - fn receive_messages_delivery_proof_rejects_proof_if_declared_relayers_state_is_invalid() { - run_test(|| { - // when number of relayers entries is invalid - assert_noop!( - Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - relayers: vec![ - unrewarded_relayer(1, 1, TEST_RELAYER_A), - unrewarded_relayer(2, 2, TEST_RELAYER_B) - ] - .into_iter() - .collect(), - ..Default::default() - } - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - total_messages: 2, - last_delivered_nonce: 2, - ..Default::default() - }, - ), - Error::<TestRuntime, ()>::InvalidUnrewardedRelayersState, - ); - - // when number of messages is invalid - assert_noop!( - Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - relayers: vec![ - unrewarded_relayer(1, 1, TEST_RELAYER_A), - unrewarded_relayer(2, 2, TEST_RELAYER_B) - ] - .into_iter() - .collect(), - ..Default::default() - } - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 2, - total_messages: 1, - last_delivered_nonce: 2, - ..Default::default() - }, - ), - Error::<TestRuntime, ()>::InvalidUnrewardedRelayersState, - ); - - // when last delivered nonce is invalid - assert_noop!( - Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - relayers: vec![ - unrewarded_relayer(1, 1, TEST_RELAYER_A), - unrewarded_relayer(2, 2, TEST_RELAYER_B) - ] - .into_iter() - .collect(), - ..Default::default() - } - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 2, - total_messages: 2, - last_delivered_nonce: 8, - ..Default::default() - }, - ), - Error::<TestRuntime, ()>::InvalidUnrewardedRelayersState, - ); - }); - } - - #[test] - fn receive_messages_accepts_single_message_with_invalid_payload() { - run_test(|| { - let mut invalid_message = message(1, REGULAR_PAYLOAD); - invalid_message.payload = Vec::new(); - - assert_ok!(Pallet::<TestRuntime, ()>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![invalid_message]).into(), - 1, - Weight::zero(), /* weight may be zero in this case (all messages are - * improperly encoded) */ - ),); - - assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 1,); - }); - } - - #[test] - fn receive_messages_accepts_batch_with_message_with_invalid_payload() { - run_test(|| { - let mut invalid_message = message(2, REGULAR_PAYLOAD); - invalid_message.payload = Vec::new(); - - assert_ok!(Pallet::<TestRuntime, ()>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok( - vec![message(1, REGULAR_PAYLOAD), invalid_message, message(3, REGULAR_PAYLOAD),] - ) - .into(), - 3, - REGULAR_PAYLOAD.declared_weight + REGULAR_PAYLOAD.declared_weight, - ),); - - assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 3,); - }); - } - - #[test] - fn actual_dispatch_weight_does_not_overflow() { - run_test(|| { - let message1 = message(1, message_payload(0, u64::MAX / 2)); - let message2 = message(2, message_payload(0, u64::MAX / 2)); - let message3 = message(3, message_payload(0, u64::MAX / 2)); - - assert_noop!( - Pallet::<TestRuntime, ()>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - // this may cause overflow if source chain storage is invalid - Ok(vec![message1, message2, message3]).into(), - 3, - Weight::MAX, - ), - Error::<TestRuntime, ()>::InsufficientDispatchWeight - ); - assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 0); - }); - } - - #[test] - fn ref_time_refund_from_receive_messages_proof_works() { - run_test(|| { - fn submit_with_unspent_weight( - nonce: MessageNonce, - unspent_weight: u64, - ) -> (Weight, Weight) { - let mut payload = REGULAR_PAYLOAD; - *payload.dispatch_result.unspent_weight.ref_time_mut() = unspent_weight; - let proof = Ok(vec![message(nonce, payload)]).into(); - let messages_count = 1; - let pre_dispatch_weight = - <TestRuntime as Config>::WeightInfo::receive_messages_proof_weight( - &proof, - messages_count, - REGULAR_PAYLOAD.declared_weight, - ); - let result = Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - proof, - messages_count, - REGULAR_PAYLOAD.declared_weight, - ) - .expect("delivery has failed"); - let post_dispatch_weight = - result.actual_weight.expect("receive_messages_proof always returns Some"); - - // message delivery transactions are never free - assert_eq!(result.pays_fee, Pays::Yes); - - (pre_dispatch_weight, post_dispatch_weight) - } - - // when dispatch is returning `unspent_weight < declared_weight` - let (pre, post) = submit_with_unspent_weight(1, 1); - assert_eq!(post.ref_time(), pre.ref_time() - 1); - - // when dispatch is returning `unspent_weight = declared_weight` - let (pre, post) = - submit_with_unspent_weight(2, REGULAR_PAYLOAD.declared_weight.ref_time()); - assert_eq!( - post.ref_time(), - pre.ref_time() - REGULAR_PAYLOAD.declared_weight.ref_time() - ); - - // when dispatch is returning `unspent_weight > declared_weight` - let (pre, post) = - submit_with_unspent_weight(3, REGULAR_PAYLOAD.declared_weight.ref_time() + 1); - assert_eq!( - post.ref_time(), - pre.ref_time() - REGULAR_PAYLOAD.declared_weight.ref_time() - ); - - // when there's no unspent weight - let (pre, post) = submit_with_unspent_weight(4, 0); - assert_eq!(post.ref_time(), pre.ref_time()); - - // when dispatch is returning `unspent_weight < declared_weight` - let (pre, post) = submit_with_unspent_weight(5, 1); - assert_eq!(post.ref_time(), pre.ref_time() - 1); - }); - } - - #[test] - fn proof_size_refund_from_receive_messages_proof_works() { - run_test(|| { - let max_entries = crate::mock::MaxUnrewardedRelayerEntriesAtInboundLane::get() as usize; - - // if there's maximal number of unrewarded relayer entries at the inbound lane, then - // `proof_size` is unchanged in post-dispatch weight - let proof: TestMessagesProof = Ok(vec![message(101, REGULAR_PAYLOAD)]).into(); - let messages_count = 1; - let pre_dispatch_weight = - <TestRuntime as Config>::WeightInfo::receive_messages_proof_weight( - &proof, - messages_count, - REGULAR_PAYLOAD.declared_weight, - ); - InboundLanes::<TestRuntime>::insert( - TEST_LANE_ID, - StoredInboundLaneData(InboundLaneData { - relayers: vec![ - UnrewardedRelayer { - relayer: 42, - messages: DeliveredMessages { begin: 0, end: 100 } - }; - max_entries - ] - .into_iter() - .collect(), - last_confirmed_nonce: 0, - }), - ); - let post_dispatch_weight = Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - proof.clone(), - messages_count, - REGULAR_PAYLOAD.declared_weight, - ) - .unwrap() - .actual_weight - .unwrap(); - assert_eq!(post_dispatch_weight.proof_size(), pre_dispatch_weight.proof_size()); - - // if count of unrewarded relayer entries is less than maximal, then some `proof_size` - // must be refunded - InboundLanes::<TestRuntime>::insert( - TEST_LANE_ID, - StoredInboundLaneData(InboundLaneData { - relayers: vec![ - UnrewardedRelayer { - relayer: 42, - messages: DeliveredMessages { begin: 0, end: 100 } - }; - max_entries - 1 - ] - .into_iter() - .collect(), - last_confirmed_nonce: 0, - }), - ); - let post_dispatch_weight = Pallet::<TestRuntime>::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - proof, - messages_count, - REGULAR_PAYLOAD.declared_weight, - ) - .unwrap() - .actual_weight - .unwrap(); - assert!( - post_dispatch_weight.proof_size() < pre_dispatch_weight.proof_size(), - "Expected post-dispatch PoV {} to be less than pre-dispatch PoV {}", - post_dispatch_weight.proof_size(), - pre_dispatch_weight.proof_size(), - ); - }); - } - - #[test] - fn messages_delivered_callbacks_are_called() { - run_test(|| { - send_regular_message(TEST_LANE_ID); - send_regular_message(TEST_LANE_ID); - send_regular_message(TEST_LANE_ID); - - // messages 1+2 are confirmed in 1 tx, message 3 in a separate tx - // dispatch of message 2 has failed - let mut delivered_messages_1_and_2 = DeliveredMessages::new(1); - delivered_messages_1_and_2.note_dispatched_message(); - let messages_1_and_2_proof = Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 0, - relayers: vec![UnrewardedRelayer { - relayer: 0, - messages: delivered_messages_1_and_2.clone(), - }] - .into_iter() - .collect(), - }, - )); - let delivered_message_3 = DeliveredMessages::new(3); - let messages_3_proof = Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 0, - relayers: vec![UnrewardedRelayer { relayer: 0, messages: delivered_message_3 }] - .into_iter() - .collect(), - }, - )); - - // first tx with messages 1+2 - assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(messages_1_and_2_proof), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 2, - total_messages: 2, - last_delivered_nonce: 2, - }, - )); - // second tx with message 3 - assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(messages_3_proof), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 3, - }, - )); - }); - } - - #[test] - fn receive_messages_delivery_proof_rejects_proof_if_trying_to_confirm_more_messages_than_expected( - ) { - run_test(|| { - // send message first to be able to check that delivery_proof fails later - send_regular_message(TEST_LANE_ID); - - // 1) InboundLaneData declares that the `last_confirmed_nonce` is 1; - // 2) InboundLaneData has no entries => `InboundLaneData::last_delivered_nonce()` - // returns `last_confirmed_nonce`; - // 3) it means that we're going to confirm delivery of messages 1..=1; - // 4) so the number of declared messages (see `UnrewardedRelayersState`) is `0` and - // number of actually confirmed messages is `1`. - assert_noop!( - Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { last_confirmed_nonce: 1, relayers: Default::default() }, - ))), - UnrewardedRelayersState { last_delivered_nonce: 1, ..Default::default() }, - ), - Error::<TestRuntime, ()>::ReceptionConfirmation( - ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected - ), - ); - }); - } - - #[test] - fn storage_keys_computed_properly() { - assert_eq!( - PalletOperatingMode::<TestRuntime>::storage_value_final_key().to_vec(), - bp_messages::storage_keys::operating_mode_key("Messages").0, - ); - - assert_eq!( - OutboundMessages::<TestRuntime>::storage_map_final_key(MessageKey { - lane_id: TEST_LANE_ID, - nonce: 42 - }), - bp_messages::storage_keys::message_key("Messages", &TEST_LANE_ID, 42).0, - ); - - assert_eq!( - OutboundLanes::<TestRuntime>::storage_map_final_key(TEST_LANE_ID), - bp_messages::storage_keys::outbound_lane_data_key("Messages", &TEST_LANE_ID).0, - ); - - assert_eq!( - InboundLanes::<TestRuntime>::storage_map_final_key(TEST_LANE_ID), - bp_messages::storage_keys::inbound_lane_data_key("Messages", &TEST_LANE_ID).0, - ); - } - - #[test] - fn inbound_message_details_works() { - run_test(|| { - assert_eq!( - Pallet::<TestRuntime>::inbound_message_data( - TEST_LANE_ID, - REGULAR_PAYLOAD.encode(), - OutboundMessageDetails { nonce: 0, dispatch_weight: Weight::zero(), size: 0 }, - ), - InboundMessageDetails { dispatch_weight: REGULAR_PAYLOAD.declared_weight }, - ); - }); - } - - #[test] - fn on_idle_callback_respects_remaining_weight() { - run_test(|| { - send_regular_message(TEST_LANE_ID); - send_regular_message(TEST_LANE_ID); - send_regular_message(TEST_LANE_ID); - send_regular_message(TEST_LANE_ID); - - assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 4, - relayers: vec![unrewarded_relayer(1, 4, TEST_RELAYER_A)] - .into_iter() - .collect(), - }, - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 4, - total_messages: 4, - last_delivered_nonce: 4, - }, - )); - - // all 4 messages may be pruned now - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_received_nonce, - 4 - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 1 - ); - System::<TestRuntime>::set_block_number(2); - - // if passed wight is too low to do anything - let dbw = DbWeight::get(); - assert_eq!( - Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(1, 1)), - Weight::zero(), - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 1 - ); - - // if passed wight is enough to prune single message - assert_eq!( - Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(1, 2)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 2 - ); - - // if passed wight is enough to prune two more messages - assert_eq!( - Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(1, 3)), - dbw.reads_writes(1, 3), - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 4 - ); - - // if passed wight is enough to prune many messages - assert_eq!( - Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 5 - ); - }); - } - - #[test] - fn on_idle_callback_is_rotating_lanes_to_prune() { - run_test(|| { - // send + receive confirmation for lane 1 - send_regular_message(TEST_LANE_ID); - receive_messages_delivery_proof(); - // send + receive confirmation for lane 2 - send_regular_message(TEST_LANE_ID_2); - assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID_2, - InboundLaneData { - last_confirmed_nonce: 1, - relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)] - .into_iter() - .collect(), - }, - ))), - UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - messages_in_oldest_entry: 1, - total_messages: 1, - last_delivered_nonce: 1, - }, - )); - - // nothing is pruned yet - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_received_nonce, - 1 - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 1 - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().latest_received_nonce, - 1 - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 1 - ); - - // in block#2.on_idle lane messages of lane 1 are pruned - let dbw = DbWeight::get(); - System::<TestRuntime>::set_block_number(2); - assert_eq!( - Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 2 - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 1 - ); - - // in block#3.on_idle lane messages of lane 2 are pruned - System::<TestRuntime>::set_block_number(3); - - assert_eq!( - Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, - 2 - ); - assert_eq!( - outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 2 - ); - }); - } - - #[test] - fn outbound_message_from_unconfigured_lane_is_rejected() { - run_test(|| { - assert_noop!( - Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), - Error::<TestRuntime, ()>::InactiveOutboundLane, - ); - }); - } - - #[test] - fn test_bridge_messages_call_is_correctly_defined() { - let account_id = 1; - let message_proof: TestMessagesProof = Ok(vec![message(1, REGULAR_PAYLOAD)]).into(); - let message_delivery_proof = TestMessagesDeliveryProof(Ok(( - TEST_LANE_ID, - InboundLaneData { - last_confirmed_nonce: 1, - relayers: vec![UnrewardedRelayer { - relayer: 0, - messages: DeliveredMessages::new(1), - }] - .into_iter() - .collect(), - }, - ))); - let unrewarded_relayer_state = UnrewardedRelayersState { - unrewarded_relayer_entries: 1, - total_messages: 1, - last_delivered_nonce: 1, - ..Default::default() - }; - - let direct_receive_messages_proof_call = Call::<TestRuntime>::receive_messages_proof { - relayer_id_at_bridged_chain: account_id, - proof: message_proof.clone(), - messages_count: 1, - dispatch_weight: REGULAR_PAYLOAD.declared_weight, - }; - let indirect_receive_messages_proof_call = BridgeMessagesCall::< - AccountId, - TestMessagesProof, - TestMessagesDeliveryProof, - >::receive_messages_proof { - relayer_id_at_bridged_chain: account_id, - proof: message_proof, - messages_count: 1, - dispatch_weight: REGULAR_PAYLOAD.declared_weight, - }; - assert_eq!( - direct_receive_messages_proof_call.encode(), - indirect_receive_messages_proof_call.encode() - ); - - let direct_receive_messages_delivery_proof_call = - Call::<TestRuntime>::receive_messages_delivery_proof { - proof: message_delivery_proof.clone(), - relayers_state: unrewarded_relayer_state.clone(), - }; - let indirect_receive_messages_delivery_proof_call = BridgeMessagesCall::< - AccountId, - TestMessagesProof, - TestMessagesDeliveryProof, - >::receive_messages_delivery_proof { - proof: message_delivery_proof, - relayers_state: unrewarded_relayer_state, - }; - assert_eq!( - direct_receive_messages_delivery_proof_call.encode(), - indirect_receive_messages_delivery_proof_call.encode() - ); - } - - generate_owned_bridge_module_tests!( - MessagesOperatingMode::Basic(BasicOperatingMode::Normal), - MessagesOperatingMode::Basic(BasicOperatingMode::Halted) - ); - - #[test] - fn inbound_storage_extra_proof_size_bytes_works() { - fn relayer_entry() -> UnrewardedRelayer<TestRelayer> { - UnrewardedRelayer { relayer: 42u64, messages: DeliveredMessages { begin: 0, end: 100 } } - } - - fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage<TestRuntime, ()> { - RuntimeInboundLaneStorage { - lane_id: Default::default(), - cached_data: Some(InboundLaneData { - relayers: vec![relayer_entry(); relayer_entries].into_iter().collect(), - last_confirmed_nonce: 0, - }), - _phantom: Default::default(), - } - } - - let max_entries = crate::mock::MaxUnrewardedRelayerEntriesAtInboundLane::get() as usize; - - // when we have exactly `MaxUnrewardedRelayerEntriesAtInboundLane` unrewarded relayers - assert_eq!(storage(max_entries).extra_proof_size_bytes(), 0); - - // when we have less than `MaxUnrewardedRelayerEntriesAtInboundLane` unrewarded relayers - assert_eq!( - storage(max_entries - 1).extra_proof_size_bytes(), - relayer_entry().encode().len() as u64 - ); - assert_eq!( - storage(max_entries - 2).extra_proof_size_bytes(), - 2 * relayer_entry().encode().len() as u64 - ); - - // when we have more than `MaxUnrewardedRelayerEntriesAtInboundLane` unrewarded relayers - // (shall not happen in practice) - assert_eq!(storage(max_entries + 1).extra_proof_size_bytes(), 0); - } - - #[test] - fn maybe_outbound_lanes_count_returns_correct_value() { - assert_eq!( - MaybeOutboundLanesCount::<TestRuntime, ()>::get(), - Some(mock::ActiveOutboundLanes::get().len() as u32) - ); - } -} diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index acef5546d2a64fa8a3fb38c6b41ae30819cdeaa2..fcdddf199dc65b37dd014745b6a1630709ad8f8b 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -18,16 +18,18 @@ use crate::{Config, LOG_TARGET}; -use bp_messages::{DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer}; +use bp_messages::{ + ChainWithMessages, DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, +}; use codec::{Decode, Encode}; use frame_support::{ + traits::Get, weights::{RuntimeDbWeight, Weight}, BoundedVec, PalletError, }; -use num_traits::Zero; use scale_info::TypeInfo; -use sp_runtime::RuntimeDebug; -use sp_std::collections::vec_deque::VecDeque; +use sp_runtime::{traits::Zero, RuntimeDebug}; +use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData}; /// Outbound lane storage. pub trait OutboundLaneStorage { @@ -48,8 +50,17 @@ pub trait OutboundLaneStorage { fn remove_message(&mut self, nonce: &MessageNonce); } +/// Limit for the `StoredMessagePayload` vector. +pub struct StoredMessagePayloadLimit<T, I>(PhantomData<(T, I)>); + +impl<T: Config<I>, I: 'static> Get<u32> for StoredMessagePayloadLimit<T, I> { + fn get() -> u32 { + T::BridgedChain::maximal_incoming_message_size() + } +} + /// Outbound message data wrapper that implements `MaxEncodedLen`. -pub type StoredMessagePayload<T, I> = BoundedVec<u8, <T as Config<I>>::MaximalOutboundPayloadSize>; +pub type StoredMessagePayload<T, I> = BoundedVec<u8, StoredMessagePayloadLimit<T, I>>; /// Result of messages receival confirmation. #[derive(Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] @@ -204,11 +215,11 @@ fn ensure_unrewarded_relayers_are_correct<RelayerId>( mod tests { use super::*; use crate::{ - mock::{ + outbound_lane, + tests::mock::{ outbound_message_data, run_test, unrewarded_relayer, TestRelayer, TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, }, - outbound_lane, }; use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; @@ -263,12 +274,43 @@ mod tests { assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); assert_eq!( lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)), Ok(Some(delivered_messages(1..=3))), ); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 3); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + }); + } + + #[test] + fn confirm_partial_delivery_works() { + run_test(|| { + let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3); + assert_eq!(lane.storage.data().latest_generated_nonce, 3); + assert_eq!(lane.storage.data().latest_received_nonce, 0); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + + assert_eq!( + lane.confirm_delivery(3, 2, &unrewarded_relayers(1..=2)), + Ok(Some(delivered_messages(1..=2))), + ); + assert_eq!(lane.storage.data().latest_generated_nonce, 3); + assert_eq!(lane.storage.data().latest_received_nonce, 2); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + + assert_eq!( + lane.confirm_delivery(3, 3, &unrewarded_relayers(3..=3)), + Ok(Some(delivered_messages(3..=3))), + ); + assert_eq!(lane.storage.data().latest_generated_nonce, 3); + assert_eq!(lane.storage.data().latest_received_nonce, 3); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -281,6 +323,7 @@ mod tests { lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); assert_eq!( lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)), Ok(Some(delivered_messages(1..=3))), @@ -288,10 +331,12 @@ mod tests { assert_eq!(lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)), Ok(None),); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 3); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); assert_eq!(lane.confirm_delivery(1, 2, &unrewarded_relayers(1..=1)), Ok(None),); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 3); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -310,8 +355,8 @@ mod tests { 3, &unrewarded_relayers(1..=1) .into_iter() - .chain(unrewarded_relayers(2..=30).into_iter()) - .chain(unrewarded_relayers(3..=3).into_iter()) + .chain(unrewarded_relayers(2..=30)) + .chain(unrewarded_relayers(3..=3)) .collect(), ), Err(ReceptionConfirmationError::FailedToConfirmFutureMessages), @@ -326,8 +371,8 @@ mod tests { 3, &unrewarded_relayers(1..=1) .into_iter() - .chain(unrewarded_relayers(2..=1).into_iter()) - .chain(unrewarded_relayers(2..=3).into_iter()) + .chain(unrewarded_relayers(2..=1)) + .chain(unrewarded_relayers(2..=3)) .collect(), ), Err(ReceptionConfirmationError::EmptyUnrewardedRelayerEntry), @@ -341,8 +386,8 @@ mod tests { 3, &unrewarded_relayers(1..=1) .into_iter() - .chain(unrewarded_relayers(3..=3).into_iter()) - .chain(unrewarded_relayers(2..=2).into_iter()) + .chain(unrewarded_relayers(3..=3)) + .chain(unrewarded_relayers(2..=2)) .collect(), ), Err(ReceptionConfirmationError::NonConsecutiveUnrewardedRelayerEntries), diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs new file mode 100644 index 0000000000000000000000000000000000000000..18367029d72cd356939f19f769a36b634ad1991e --- /dev/null +++ b/bridges/modules/messages/src/proofs.rs @@ -0,0 +1,562 @@ +// 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 <http://www.gnu.org/licenses/>. + +//! Tools for messages and delivery proof verification. + +use crate::{BridgedChainOf, BridgedHeaderChainOf, Config}; + +use bp_header_chain::{HeaderChain, HeaderChainError}; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::{FromBridgedChainMessagesProof, ProvedLaneMessages, ProvedMessages}, + ChainWithMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, + OutboundLaneData, VerificationError, +}; +use bp_runtime::{ + HashOf, HasherOf, RangeInclusiveExt, RawStorageProof, StorageProofChecker, StorageProofError, +}; +use codec::Decode; +use sp_std::vec::Vec; + +/// 'Parsed' message delivery proof - inbound lane id and its state. +pub(crate) type ParsedMessagesDeliveryProofFromBridgedChain<T> = + (LaneId, InboundLaneData<<T as frame_system::Config>::AccountId>); + +/// Verify proof of Bridged -> This chain messages. +/// +/// This function is used when Bridged chain is directly using GRANDPA finality. For Bridged +/// parachains, please use the `verify_messages_proof_from_parachain`. +/// +/// The `messages_count` argument verification (sane limits) is supposed to be made +/// outside of this function. This function only verifies that the proof declares exactly +/// `messages_count` messages. +pub fn verify_messages_proof<T: Config<I>, I: 'static>( + proof: FromBridgedChainMessagesProof<HashOf<BridgedChainOf<T, I>>>, + messages_count: u32, +) -> Result<ProvedMessages<Message>, VerificationError> { + let FromBridgedChainMessagesProof { + bridged_header_hash, + storage_proof, + lane, + nonces_start, + nonces_end, + } = proof; + let mut parser: MessagesStorageProofAdapter<T, I> = + MessagesStorageProofAdapter::try_new_with_verified_storage_proof( + bridged_header_hash, + storage_proof, + ) + .map_err(VerificationError::HeaderChain)?; + let nonces_range = nonces_start..=nonces_end; + + // receiving proofs where end < begin is ok (if proof includes outbound lane state) + let messages_in_the_proof = nonces_range.checked_len().unwrap_or(0); + if messages_in_the_proof != MessageNonce::from(messages_count) { + return Err(VerificationError::MessagesCountMismatch) + } + + // Read messages first. All messages that are claimed to be in the proof must + // be in the proof. So any error in `read_value`, or even missing value is fatal. + // + // Mind that we allow proofs with no messages if outbound lane state is proved. + let mut messages = Vec::with_capacity(messages_in_the_proof as _); + for nonce in nonces_range { + let message_key = MessageKey { lane_id: lane, nonce }; + let message_payload = parser + .read_and_decode_message_payload(&message_key) + .map_err(VerificationError::MessageStorage)?; + messages.push(Message { key: message_key, payload: message_payload }); + } + + // Now let's check if proof contains outbound lane state proof. It is optional, so + // we simply ignore `read_value` errors and missing value. + let proved_lane_messages = ProvedLaneMessages { + lane_state: parser + .read_and_decode_outbound_lane_data(&lane) + .map_err(VerificationError::OutboundLaneStorage)?, + messages, + }; + + // Now we may actually check if the proof is empty or not. + if proved_lane_messages.lane_state.is_none() && proved_lane_messages.messages.is_empty() { + return Err(VerificationError::EmptyMessageProof) + } + + // Check that the storage proof doesn't have any untouched keys. + parser.ensure_no_unused_keys().map_err(VerificationError::StorageProof)?; + + // We only support single lane messages in this generated_schema + let mut proved_messages = ProvedMessages::new(); + proved_messages.insert(lane, proved_lane_messages); + + Ok(proved_messages) +} + +/// Verify proof of This -> Bridged chain messages delivery. +pub fn verify_messages_delivery_proof<T: Config<I>, I: 'static>( + proof: FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<T, I>>>, +) -> Result<ParsedMessagesDeliveryProofFromBridgedChain<T>, VerificationError> { + let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = proof; + let mut parser: MessagesStorageProofAdapter<T, I> = + MessagesStorageProofAdapter::try_new_with_verified_storage_proof( + bridged_header_hash, + storage_proof, + ) + .map_err(VerificationError::HeaderChain)?; + // Messages delivery proof is just proof of single storage key read => any error + // is fatal. + let storage_inbound_lane_data_key = bp_messages::storage_keys::inbound_lane_data_key( + T::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + &lane, + ); + let inbound_lane_data = parser + .read_and_decode_mandatory_value(&storage_inbound_lane_data_key) + .map_err(VerificationError::InboundLaneStorage)?; + + // check that the storage proof doesn't have any untouched trie nodes + parser.ensure_no_unused_keys().map_err(VerificationError::StorageProof)?; + + Ok((lane, inbound_lane_data)) +} + +/// Abstraction over storage proof manipulation, hiding implementation details of actual storage +/// proofs. +trait StorageProofAdapter<T: Config<I>, I: 'static> { + fn read_and_decode_mandatory_value<D: Decode>( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result<D, StorageProofError>; + fn read_and_decode_optional_value<D: Decode>( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result<Option<D>, StorageProofError>; + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError>; + + fn read_and_decode_outbound_lane_data( + &mut self, + lane_id: &LaneId, + ) -> Result<Option<OutboundLaneData>, StorageProofError> { + let storage_outbound_lane_data_key = bp_messages::storage_keys::outbound_lane_data_key( + T::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + lane_id, + ); + self.read_and_decode_optional_value(&storage_outbound_lane_data_key) + } + + fn read_and_decode_message_payload( + &mut self, + message_key: &MessageKey, + ) -> Result<MessagePayload, StorageProofError> { + let storage_message_key = bp_messages::storage_keys::message_key( + T::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + &message_key.lane_id, + message_key.nonce, + ); + self.read_and_decode_mandatory_value(&storage_message_key) + } +} + +/// Actual storage proof adapter for messages proofs. +type MessagesStorageProofAdapter<T, I> = StorageProofCheckerAdapter<T, I>; + +/// A `StorageProofAdapter` implementation for raw storage proofs. +struct StorageProofCheckerAdapter<T: Config<I>, I: 'static> { + storage: StorageProofChecker<HasherOf<BridgedChainOf<T, I>>>, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl<T: Config<I>, I: 'static> StorageProofCheckerAdapter<T, I> { + fn try_new_with_verified_storage_proof( + bridged_header_hash: HashOf<BridgedChainOf<T, I>>, + storage_proof: RawStorageProof, + ) -> Result<Self, HeaderChainError> { + BridgedHeaderChainOf::<T, I>::verify_storage_proof(bridged_header_hash, storage_proof).map( + |storage| StorageProofCheckerAdapter::<T, I> { storage, _dummy: Default::default() }, + ) + } +} + +impl<T: Config<I>, I: 'static> StorageProofAdapter<T, I> for StorageProofCheckerAdapter<T, I> { + fn read_and_decode_optional_value<D: Decode>( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result<Option<D>, StorageProofError> { + self.storage.read_and_decode_opt_value(key.as_ref()) + } + + fn read_and_decode_mandatory_value<D: Decode>( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result<D, StorageProofError> { + self.storage.read_and_decode_mandatory_value(key.as_ref()) + } + + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { + self.storage.ensure_no_unused_nodes() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{ + messages_generation::{ + encode_all_messages, encode_lane_data, generate_dummy_message, + prepare_messages_storage_proof, + }, + mock::*, + }; + + use bp_header_chain::StoredHeaderDataBuilder; + use bp_runtime::{HeaderId, StorageProofError}; + use codec::Encode; + use sp_runtime::traits::Header; + + fn using_messages_proof<R>( + nonces_end: MessageNonce, + outbound_lane_data: Option<OutboundLaneData>, + encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option<Vec<u8>>, + encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec<u8>, + add_duplicate_key: bool, + add_unused_key: bool, + test: impl Fn(FromBridgedChainMessagesProof<BridgedHeaderHash>) -> R, + ) -> R { + let (state_root, storage_proof) = prepare_messages_storage_proof::<BridgedChain, ThisChain>( + TEST_LANE_ID, + 1..=nonces_end, + outbound_lane_data, + bp_runtime::UnverifiedStorageProofParams::default(), + generate_dummy_message, + encode_message, + encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, + ); + + 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(); + + pallet_bridge_grandpa::BestFinalized::<TestRuntime>::put(HeaderId( + 0, + bridged_header_hash, + )); + pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert( + bridged_header_hash, + bridged_header.build(), + ); + test(FromBridgedChainMessagesProof { + bridged_header_hash, + storage_proof, + lane: TEST_LANE_ID, + nonces_start: 1, + nonces_end, + }) + }) + } + + #[test] + fn messages_proof_is_rejected_if_declared_less_than_actual_number_of_messages() { + assert_eq!( + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { verify_messages_proof::<TestRuntime, ()>(proof, 5) } + ), + Err(VerificationError::MessagesCountMismatch), + ); + } + + #[test] + fn messages_proof_is_rejected_if_declared_more_than_actual_number_of_messages() { + assert_eq!( + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { verify_messages_proof::<TestRuntime, ()>(proof, 15) } + ), + Err(VerificationError::MessagesCountMismatch), + ); + } + + #[test] + 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, + false, + false, + |proof| { + let bridged_header_hash = + pallet_bridge_grandpa::BestFinalized::<TestRuntime>::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::remove( + bridged_header_hash, + ); + verify_messages_proof::<TestRuntime, ()>(proof, 10) + } + ), + Err(VerificationError::HeaderChain(HeaderChainError::UnknownHeader)), + ); + } + + #[test] + fn message_proof_is_rejected_if_header_state_root_mismatches() { + assert_eq!( + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { + let bridged_header_hash = + pallet_bridge_grandpa::BestFinalized::<TestRuntime>::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert( + bridged_header_hash, + BridgedChainHeader::new( + 0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ) + .build(), + ); + verify_messages_proof::<TestRuntime, ()>(proof, 10) + } + ), + Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( + StorageProofError::StorageRootMismatch + ))), + ); + } + + #[test] + fn message_proof_is_rejected_if_it_has_duplicate_trie_nodes() { + assert_eq!( + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + true, + false, + |proof| { verify_messages_proof::<TestRuntime, ()>(proof, 10) }, + ), + Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( + StorageProofError::DuplicateNodes + ))), + ); + } + + #[test] + fn message_proof_is_rejected_if_it_has_unused_trie_nodes() { + assert_eq!( + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + true, + |proof| { verify_messages_proof::<TestRuntime, ()>(proof, 10) }, + ), + Err(VerificationError::StorageProof(StorageProofError::UnusedKey)), + ); + } + + #[test] + fn message_proof_is_rejected_if_required_message_is_missing() { + matches!( + using_messages_proof( + 10, + None, + |n, m| if n != 5 { Some(m.encode()) } else { None }, + encode_lane_data, + false, + false, + |proof| verify_messages_proof::<TestRuntime, ()>(proof, 10) + ), + Err(VerificationError::MessageStorage(StorageProofError::EmptyVal)), + ); + } + + #[test] + fn message_proof_is_rejected_if_message_decode_fails() { + matches!( + using_messages_proof( + 10, + None, + |n, m| { + let mut m = m.encode(); + if n == 5 { + m = vec![42] + } + Some(m) + }, + encode_lane_data, + false, + false, + |proof| verify_messages_proof::<TestRuntime, ()>(proof, 10), + ), + Err(VerificationError::MessageStorage(StorageProofError::DecodeError)), + ); + } + + #[test] + fn message_proof_is_rejected_if_outbound_lane_state_decode_fails() { + matches!( + using_messages_proof( + 10, + Some(OutboundLaneData { + oldest_unpruned_nonce: 1, + latest_received_nonce: 1, + latest_generated_nonce: 1, + }), + encode_all_messages, + |d| { + let mut d = d.encode(); + d.truncate(1); + d + }, + false, + false, + |proof| verify_messages_proof::<TestRuntime, ()>(proof, 10), + ), + Err(VerificationError::OutboundLaneStorage(StorageProofError::DecodeError)), + ); + } + + #[test] + fn message_proof_is_rejected_if_it_is_empty() { + assert_eq!( + using_messages_proof( + 0, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { verify_messages_proof::<TestRuntime, ()>(proof, 0) }, + ), + Err(VerificationError::EmptyMessageProof), + ); + } + + #[test] + fn non_empty_message_proof_without_messages_is_accepted() { + assert_eq!( + using_messages_proof( + 0, + Some(OutboundLaneData { + oldest_unpruned_nonce: 1, + latest_received_nonce: 1, + latest_generated_nonce: 1, + }), + encode_all_messages, + encode_lane_data, + false, + false, + |proof| verify_messages_proof::<TestRuntime, ()>(proof, 0), + ), + Ok(vec![( + TEST_LANE_ID, + ProvedLaneMessages { + lane_state: Some(OutboundLaneData { + oldest_unpruned_nonce: 1, + latest_received_nonce: 1, + latest_generated_nonce: 1, + }), + messages: Vec::new(), + }, + )] + .into_iter() + .collect()), + ); + } + + #[test] + fn non_empty_message_proof_is_accepted() { + assert_eq!( + using_messages_proof( + 1, + Some(OutboundLaneData { + oldest_unpruned_nonce: 1, + latest_received_nonce: 1, + latest_generated_nonce: 1, + }), + encode_all_messages, + encode_lane_data, + false, + false, + |proof| verify_messages_proof::<TestRuntime, ()>(proof, 1), + ), + Ok(vec![( + TEST_LANE_ID, + ProvedLaneMessages { + lane_state: Some(OutboundLaneData { + oldest_unpruned_nonce: 1, + latest_received_nonce: 1, + latest_generated_nonce: 1, + }), + messages: vec![Message { + key: MessageKey { lane_id: TEST_LANE_ID, nonce: 1 }, + payload: vec![42], + }], + }, + )] + .into_iter() + .collect()), + ); + } + + #[test] + fn verify_messages_proof_does_not_panic_if_messages_count_mismatches() { + assert_eq!( + using_messages_proof( + 1, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |mut proof| { + proof.nonces_end = u64::MAX; + verify_messages_proof::<TestRuntime, ()>(proof, u32::MAX) + }, + ), + Err(VerificationError::MessagesCountMismatch), + ); + } +} diff --git a/bridges/bin/runtime-common/src/messages_generation.rs b/bridges/modules/messages/src/tests/messages_generation.rs similarity index 62% rename from bridges/bin/runtime-common/src/messages_generation.rs rename to bridges/modules/messages/src/tests/messages_generation.rs index c37aaa5d4d5378a1b76507e017c73aec3c7aabbd..6c4867fa6de39fa97b35cbd1f270bdeff4c76dff 100644 --- a/bridges/bin/runtime-common/src/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -16,17 +16,23 @@ //! Helpers for generating message storage proofs, that are used by tests and by benchmarks. -use crate::messages::{AccountIdOf, BridgedChain, HashOf, HasherOf, MessageBridge, ThisChain}; - use bp_messages::{ - storage_keys, InboundLaneData, LaneId, MessageKey, MessageNonce, MessagePayload, - OutboundLaneData, + storage_keys, ChainWithMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, + MessagePayload, OutboundLaneData, +}; +use bp_runtime::{ + grow_storage_value, record_all_trie_keys, AccountIdOf, Chain, HashOf, HasherOf, + RawStorageProof, UnverifiedStorageProofParams, }; -use bp_runtime::{record_all_trie_keys, RawStorageProof, StorageProofSize}; use codec::Encode; use sp_std::{ops::RangeInclusive, prelude::*}; use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; +/// Dummy message generation function. +pub fn generate_dummy_message(_: MessageNonce) -> MessagePayload { + vec![42] +} + /// Simple and correct message data encode function. pub fn encode_all_messages(_: MessageNonce, m: &MessagePayload) -> Option<Vec<u8>> { Some(m.encode()) @@ -40,18 +46,20 @@ pub fn encode_lane_data(d: &OutboundLaneData) -> Vec<u8> { /// Prepare storage proof of given messages. /// /// Returns state trie root and nodes with prepared messages. -pub fn prepare_messages_storage_proof<B>( +#[allow(clippy::too_many_arguments)] +pub fn prepare_messages_storage_proof<BridgedChain: Chain, ThisChain: ChainWithMessages>( lane: LaneId, message_nonces: RangeInclusive<MessageNonce>, outbound_lane_data: Option<OutboundLaneData>, - size: StorageProofSize, - message_payload: MessagePayload, + proof_params: UnverifiedStorageProofParams, + generate_message: impl Fn(MessageNonce) -> MessagePayload, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option<Vec<u8>>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec<u8>, -) -> (HashOf<BridgedChain<B>>, RawStorageProof) + add_duplicate_key: bool, + add_unused_key: bool, +) -> (HashOf<BridgedChain>, RawStorageProof) where - B: MessageBridge, - HashOf<BridgedChain<B>>: Copy + Default, + HashOf<BridgedChain>: Copy + Default, { // prepare Bridged chain storage with messages and (optionally) outbound lane state let message_count = message_nonces.end().saturating_sub(*message_nonces.start()) + 1; @@ -60,22 +68,22 @@ where let mut mdb = MemoryDB::default(); { let mut trie = - TrieDBMutBuilderV1::<HasherOf<BridgedChain<B>>>::new(&mut mdb, &mut root).build(); + TrieDBMutBuilderV1::<HasherOf<BridgedChain>>::new(&mut mdb, &mut root).build(); // insert messages for (i, nonce) in message_nonces.into_iter().enumerate() { let message_key = MessageKey { lane_id: lane, nonce }; - let message_payload = match encode_message(nonce, &message_payload) { + let message_payload = match encode_message(nonce, &generate_message(nonce)) { Some(message_payload) => if i == 0 { - grow_trie_leaf_value(message_payload, size) + grow_storage_value(message_payload, &proof_params) } else { message_payload }, None => continue, }; let storage_key = storage_keys::message_key( - B::BRIDGED_MESSAGES_PALLET_NAME, + ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, &message_key.lane_id, message_key.nonce, ) @@ -89,8 +97,11 @@ where // insert outbound lane state if let Some(outbound_lane_data) = outbound_lane_data.as_ref().map(encode_outbound_lane_data) { - let storage_key = - storage_keys::outbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &lane).0; + let storage_key = storage_keys::outbound_lane_data_key( + ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + &lane, + ) + .0; trie.insert(&storage_key, &outbound_lane_data) .map_err(|_| "TrieMut::insert has failed") .expect("TrieMut::insert should not fail in benchmarks"); @@ -99,52 +110,54 @@ where } // generate storage proof to be delivered to This chain - let storage_proof = record_all_trie_keys::<LayoutV1<HasherOf<BridgedChain<B>>>, _>(&mdb, &root) - .map_err(|_| "record_all_trie_keys has failed") - .expect("record_all_trie_keys should not fail in benchmarks"); + let mut storage_proof = + record_all_trie_keys::<LayoutV1<HasherOf<BridgedChain>>, _>(&mdb, &root) + .map_err(|_| "record_all_trie_keys has failed") + .expect("record_all_trie_keys should not fail in benchmarks"); + + if add_duplicate_key { + assert!(!storage_proof.is_empty()); + let node = storage_proof.pop().unwrap(); + storage_proof.push(node.clone()); + storage_proof.push(node); + } + + if add_unused_key { + storage_proof.push(b"unused_value".to_vec()); + } + (root, storage_proof) } /// Prepare storage proof of given messages delivery. /// /// Returns state trie root and nodes with prepared messages. -pub fn prepare_message_delivery_storage_proof<B>( +pub fn prepare_message_delivery_storage_proof<BridgedChain: Chain, ThisChain: ChainWithMessages>( lane: LaneId, - inbound_lane_data: InboundLaneData<AccountIdOf<ThisChain<B>>>, - size: StorageProofSize, -) -> (HashOf<BridgedChain<B>>, RawStorageProof) + inbound_lane_data: InboundLaneData<AccountIdOf<ThisChain>>, + proof_params: UnverifiedStorageProofParams, +) -> (HashOf<BridgedChain>, RawStorageProof) where - B: MessageBridge, + HashOf<BridgedChain>: Copy + Default, { // prepare Bridged chain storage with inbound lane state - let storage_key = storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &lane).0; + let storage_key = + storage_keys::inbound_lane_data_key(ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, &lane).0; let mut root = Default::default(); let mut mdb = MemoryDB::default(); { let mut trie = - TrieDBMutBuilderV1::<HasherOf<BridgedChain<B>>>::new(&mut mdb, &mut root).build(); - let inbound_lane_data = grow_trie_leaf_value(inbound_lane_data.encode(), size); + TrieDBMutBuilderV1::<HasherOf<BridgedChain>>::new(&mut mdb, &mut root).build(); + let inbound_lane_data = grow_storage_value(inbound_lane_data.encode(), &proof_params); trie.insert(&storage_key, &inbound_lane_data) .map_err(|_| "TrieMut::insert has failed") .expect("TrieMut::insert should not fail in benchmarks"); } // generate storage proof to be delivered to This chain - let storage_proof = record_all_trie_keys::<LayoutV1<HasherOf<BridgedChain<B>>>, _>(&mdb, &root) + let storage_proof = record_all_trie_keys::<LayoutV1<HasherOf<BridgedChain>>, _>(&mdb, &root) .map_err(|_| "record_all_trie_keys has failed") .expect("record_all_trie_keys should not fail in benchmarks"); (root, storage_proof) } - -/// Add extra data to the trie leaf value so that it'll be of given size. -pub fn grow_trie_leaf_value(mut value: Vec<u8>, size: StorageProofSize) -> Vec<u8> { - match size { - StorageProofSize::Minimal(_) => (), - StorageProofSize::HasLargeLeaf(size) if size as usize > value.len() => { - value.extend(sp_std::iter::repeat(42u8).take(size as usize - value.len())); - }, - StorageProofSize::HasLargeLeaf(_) => (), - } - value -} diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/tests/mock.rs similarity index 62% rename from bridges/modules/messages/src/mock.rs rename to bridges/modules/messages/src/tests/mock.rs index 3a1e0063d5337769b75b35035116aaff6e2b2e08..ffdd536830b5f7dde6671c75ba1ac108d7d218e4 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -17,30 +17,43 @@ // From construct_runtime macro #![allow(clippy::from_over_into)] -use crate::{Config, StoredMessagePayload}; +use crate::{ + tests::messages_generation::{ + encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, + prepare_messages_storage_proof, + }, + Config, StoredMessagePayload, +}; +use bp_header_chain::{ChainWithGrandpa, StoredHeaderData}; use bp_messages::{ calc_relayers_rewards, - source_chain::{DeliveryConfirmationPayments, OnMessagesDelivered, TargetHeaderChain}, + source_chain::{ + DeliveryConfirmationPayments, FromBridgedChainMessagesDeliveryProof, OnMessagesDelivered, + }, target_chain::{ - DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch, - ProvedLaneMessages, ProvedMessages, SourceHeaderChain, + DeliveryPayments, DispatchMessage, DispatchMessageData, FromBridgedChainMessagesProof, + MessageDispatch, }, - DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, - UnrewardedRelayer, UnrewardedRelayersState, VerificationError, + ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, + MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, +}; +use bp_runtime::{ + messages::MessageDispatchResult, Chain, ChainId, Size, UnverifiedStorageProofParams, }; -use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode}; use frame_support::{ derive_impl, parameter_types, weights::{constants::RocksDbWeight, Weight}, }; use scale_info::TypeInfo; -use sp_runtime::BuildStorage; -use std::{ - collections::{BTreeMap, VecDeque}, - ops::RangeInclusive, +use sp_core::H256; +use sp_runtime::{ + testing::Header as SubstrateHeader, + traits::{BlakeTwo256, ConstU32}, + BuildStorage, StateVersion, }; +use std::{collections::VecDeque, ops::RangeInclusive}; pub type AccountId = u64; pub type Balance = u64; @@ -62,6 +75,77 @@ pub type TestMessageFee = u64; pub type TestRelayer = u64; pub type TestDispatchLevelResult = (); +pub struct ThisChain; + +impl Chain for ThisChain { + const ID: ChainId = *b"ttch"; + + type BlockNumber = u64; + type Hash = H256; + type Hasher = BlakeTwo256; + type Header = SubstrateHeader; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = u64; + type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + + fn max_extrinsic_size() -> u32 { + u32::MAX + } + + fn max_extrinsic_weight() -> Weight { + Weight::MAX + } +} + +impl ChainWithMessages for ThisChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = "WithThisChainBridgeMessages"; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 128; +} + +pub struct BridgedChain; + +pub type BridgedHeaderHash = H256; +pub type BridgedChainHeader = SubstrateHeader; + +impl Chain for BridgedChain { + const ID: ChainId = *b"tbch"; + + type BlockNumber = u64; + type Hash = BridgedHeaderHash; + type Hasher = BlakeTwo256; + type Header = BridgedChainHeader; + type AccountId = TestRelayer; + type Balance = Balance; + type Nonce = u64; + type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + + fn max_extrinsic_size() -> u32 { + 4096 + } + + fn max_extrinsic_weight() -> Weight { + Weight::MAX + } +} + +impl ChainWithGrandpa for BridgedChain { + const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = "WithBridgedChainBridgeGrandpa"; + const MAX_AUTHORITIES_COUNT: u32 = 16; + const REASONABLE_HEADERS_IN_JUSTIFICATION_ANCESTRY: u32 = 4; + const MAX_MANDATORY_HEADER_SIZE: u32 = 4096; + const AVERAGE_HEADER_SIZE: u32 = 4096; +} + +impl ChainWithMessages for BridgedChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = "WithBridgedChainBridgeMessages"; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 128; +} + type Block = frame_system::mocking::MockBlock<TestRuntime>; use crate as pallet_bridge_messages; @@ -71,6 +155,7 @@ frame_support::construct_runtime! { { System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>}, Balances: pallet_balances::{Pallet, Call, Event<T>}, + BridgedChainGrandpa: pallet_bridge_grandpa::{Pallet, Call, Event<T>}, Messages: pallet_bridge_messages::{Pallet, Call, Event<T>}, } } @@ -89,10 +174,17 @@ impl pallet_balances::Config for TestRuntime { type AccountStore = System; } +impl pallet_bridge_grandpa::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type BridgedChain = BridgedChain; + type MaxFreeHeadersPerBlock = ConstU32<4>; + type FreeHeadersInterval = ConstU32<1_024>; + type HeadersToKeep = ConstU32<8>; + type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<TestRuntime>; +} + parameter_types! { pub const MaxMessagesToPruneAtOnce: u64 = 10; - pub const MaxUnrewardedRelayerEntriesAtInboundLane: u64 = 16; - pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 128; pub const TestBridgedChainId: bp_runtime::ChainId = *b"test"; pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID, TEST_LANE_ID_2]; } @@ -103,24 +195,22 @@ pub type TestWeightInfo = (); impl Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = TestWeightInfo; + + type ThisChain = ThisChain; + type BridgedChain = BridgedChain; + type BridgedHeaderChain = BridgedChainGrandpa; + type ActiveOutboundLanes = ActiveOutboundLanes; - type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; - type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; - type MaximalOutboundPayloadSize = frame_support::traits::ConstU32<MAX_OUTBOUND_PAYLOAD_SIZE>; type OutboundPayload = TestPayload; type InboundPayload = TestPayload; - type InboundRelayer = TestRelayer; type DeliveryPayments = TestDeliveryPayments; - type TargetHeaderChain = TestTargetHeaderChain; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; type OnMessagesDelivered = TestOnMessagesDelivered; - type SourceHeaderChain = TestSourceHeaderChain; type MessageDispatch = TestMessageDispatch; - type BridgedChainId = TestBridgedChainId; } #[cfg(feature = "runtime-benchmarks")] @@ -131,29 +221,26 @@ impl crate::benchmarking::Config<()> for TestRuntime { fn prepare_message_proof( params: crate::benchmarking::MessageProofParams, - ) -> (TestMessagesProof, Weight) { - // in mock run we only care about benchmarks correctness, not the benchmark results - // => ignore size related arguments - let (messages, total_dispatch_weight) = - params.message_nonces.into_iter().map(|n| message(n, REGULAR_PAYLOAD)).fold( - (Vec::new(), Weight::zero()), - |(mut messages, total_dispatch_weight), message| { - let weight = REGULAR_PAYLOAD.declared_weight; - messages.push(message); - (messages, total_dispatch_weight.saturating_add(weight)) - }, - ); - let mut proof: TestMessagesProof = Ok(messages).into(); - proof.result.as_mut().unwrap().get_mut(0).unwrap().1.lane_state = params.outbound_lane_data; - (proof, total_dispatch_weight) + ) -> (FromBridgedChainMessagesProof<BridgedHeaderHash>, Weight) { + use bp_runtime::RangeInclusiveExt; + + let dispatch_weight = + REGULAR_PAYLOAD.declared_weight * params.message_nonces.checked_len().unwrap_or(0); + ( + *prepare_messages_proof( + params.message_nonces.into_iter().map(|n| message(n, REGULAR_PAYLOAD)).collect(), + params.outbound_lane_data, + ), + dispatch_weight, + ) } fn prepare_message_delivery_proof( params: crate::benchmarking::MessageDeliveryProofParams<AccountId>, - ) -> TestMessagesDeliveryProof { + ) -> FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash> { // in mock run we only care about benchmarks correctness, not the benchmark results // => ignore size related arguments - TestMessagesDeliveryProof(Ok((params.lane, params.inbound_lane_data))) + prepare_messages_delivery_proof(params.lane, params.inbound_lane_data) } fn is_relayer_rewarded(_relayer: &AccountId) -> bool { @@ -167,9 +254,6 @@ impl Size for TestPayload { } } -/// Maximal outbound payload size. -pub const MAX_OUTBOUND_PAYLOAD_SIZE: u32 = 4096; - /// Account that has balance to use in tests. pub const ENDOWED_ACCOUNT: AccountId = 0xDEAD; @@ -182,9 +266,6 @@ pub const TEST_RELAYER_B: AccountId = 101; /// Account id of additional test relayer - C. pub const TEST_RELAYER_C: AccountId = 102; -/// Error that is returned by all test implementations. -pub const TEST_ERROR: &str = "Test error"; - /// Lane that we're using in tests. pub const TEST_LANE_ID: LaneId = LaneId([0, 0, 0, 1]); @@ -197,71 +278,6 @@ pub const TEST_LANE_ID_3: LaneId = LaneId([0, 0, 0, 3]); /// Regular message payload. pub const REGULAR_PAYLOAD: TestPayload = message_payload(0, 50); -/// Payload that is rejected by `TestTargetHeaderChain`. -pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = message_payload(1, 50); - -/// Vec of proved messages, grouped by lane. -pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages<Message>)>; - -/// Test messages proof. -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo)] -pub struct TestMessagesProof { - pub result: Result<MessagesByLaneVec, ()>, -} - -impl Size for TestMessagesProof { - fn size(&self) -> u32 { - 0 - } -} - -impl From<Result<Vec<Message>, ()>> for TestMessagesProof { - fn from(result: Result<Vec<Message>, ()>) -> Self { - Self { - result: result.map(|messages| { - let mut messages_by_lane: BTreeMap<LaneId, ProvedLaneMessages<Message>> = - BTreeMap::new(); - for message in messages { - messages_by_lane.entry(message.key.lane_id).or_default().messages.push(message); - } - messages_by_lane.into_iter().collect() - }), - } - } -} - -/// Messages delivery proof used in tests. -#[derive(Debug, Encode, Decode, Eq, Clone, PartialEq, TypeInfo)] -pub struct TestMessagesDeliveryProof(pub Result<(LaneId, InboundLaneData<TestRelayer>), ()>); - -impl Size for TestMessagesDeliveryProof { - fn size(&self) -> u32 { - 0 - } -} - -/// Target header chain that is used in tests. -#[derive(Debug, Default)] -pub struct TestTargetHeaderChain; - -impl TargetHeaderChain<TestPayload, TestRelayer> for TestTargetHeaderChain { - type MessagesDeliveryProof = TestMessagesDeliveryProof; - - fn verify_message(payload: &TestPayload) -> Result<(), VerificationError> { - if *payload == PAYLOAD_REJECTED_BY_TARGET_CHAIN { - Err(VerificationError::Other(TEST_ERROR)) - } else { - Ok(()) - } - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData<TestRelayer>), VerificationError> { - proof.0.map_err(|_| VerificationError::Other(TEST_ERROR)) - } -} - /// Reward payments at the target chain during delivery transaction. #[derive(Debug, Default)] pub struct TestDeliveryPayments; @@ -322,24 +338,6 @@ impl DeliveryConfirmationPayments<AccountId> for TestDeliveryConfirmationPayment } } -/// Source header chain that is used in tests. -#[derive(Debug)] -pub struct TestSourceHeaderChain; - -impl SourceHeaderChain for TestSourceHeaderChain { - type MessagesProof = TestMessagesProof; - - fn verify_messages_proof( - proof: Self::MessagesProof, - _messages_count: u32, - ) -> Result<ProvedMessages<Message>, VerificationError> { - proof - .result - .map(|proof| proof.into_iter().collect()) - .map_err(|_| VerificationError::Other(TEST_ERROR)) - } -} - /// Test message dispatcher. #[derive(Debug)] pub struct TestMessageDispatch; @@ -458,3 +456,75 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pub fn run_test<T>(test: impl FnOnce() -> T) -> T { new_test_ext().execute_with(test) } + +/// Prepare valid storage proof for given messages and insert appropriate header to the +/// bridged header chain. +/// +/// Since this function changes the runtime storage, you can't "inline" it in the +/// `asset_noop` macro calls. +pub fn prepare_messages_proof( + messages: Vec<Message>, + outbound_lane_data: Option<OutboundLaneData>, +) -> Box<FromBridgedChainMessagesProof<BridgedHeaderHash>> { + // first - let's generate storage proof + let lane = messages.first().unwrap().key.lane_id; + let nonces_start = messages.first().unwrap().key.nonce; + let nonces_end = messages.last().unwrap().key.nonce; + let (storage_root, storage_proof) = prepare_messages_storage_proof::<BridgedChain, ThisChain>( + TEST_LANE_ID, + nonces_start..=nonces_end, + outbound_lane_data, + UnverifiedStorageProofParams::default(), + |nonce| messages[(nonce - nonces_start) as usize].payload.clone(), + encode_all_messages, + encode_lane_data, + false, + false, + ); + + // let's now insert bridged chain header into the storage + let bridged_header_hash = Default::default(); + pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert( + bridged_header_hash, + StoredHeaderData { number: 0, state_root: storage_root }, + ); + + Box::new(FromBridgedChainMessagesProof::<BridgedHeaderHash> { + bridged_header_hash, + storage_proof, + lane, + nonces_start, + nonces_end, + }) +} + +/// Prepare valid storage proof for given messages and insert appropriate header to the +/// bridged header chain. +/// +/// Since this function changes the runtime storage, you can't "inline" it in the +/// `asset_noop` macro calls. +pub fn prepare_messages_delivery_proof( + lane: LaneId, + inbound_lane_data: InboundLaneData<AccountId>, +) -> FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash> { + // first - let's generate storage proof + let (storage_root, storage_proof) = + prepare_message_delivery_storage_proof::<BridgedChain, ThisChain>( + lane, + inbound_lane_data, + UnverifiedStorageProofParams::default(), + ); + + // let's now insert bridged chain header into the storage + let bridged_header_hash = Default::default(); + pallet_bridge_grandpa::ImportedHeaders::<TestRuntime>::insert( + bridged_header_hash, + StoredHeaderData { number: 0, state_root: storage_root }, + ); + + FromBridgedChainMessagesDeliveryProof::<BridgedHeaderHash> { + bridged_header_hash, + storage_proof, + lane, + } +} diff --git a/bridges/modules/messages/src/tests/mod.rs b/bridges/modules/messages/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3bde5fc275849fab930ad0b1ec9f0b4e80ce4ea --- /dev/null +++ b/bridges/modules/messages/src/tests/mod.rs @@ -0,0 +1,26 @@ +// 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 <http://www.gnu.org/licenses/>. + +//! Tests and test helpers for messages pallet. + +#![cfg(any(feature = "test-helpers", test))] + +#[cfg(test)] +pub(crate) mod mock; +#[cfg(test)] +mod pallet_tests; + +pub mod messages_generation; diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..42e1042717de07656630855c00967361be78f664 --- /dev/null +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -0,0 +1,1100 @@ +// 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 <http://www.gnu.org/licenses/>. + +//! Pallet-level tests. + +use crate::{ + outbound_lane, + outbound_lane::ReceptionConfirmationError, + tests::mock::{self, RuntimeEvent as TestEvent, *}, + weights_ext::WeightInfoExt, + Call, Config, Error, Event, InboundLanes, MaybeOutboundLanesCount, OutboundLanes, + OutboundMessages, Pallet, PalletOperatingMode, PalletOwner, RuntimeInboundLaneStorage, + StoredInboundLaneData, +}; + +use bp_messages::{ + source_chain::{FromBridgedChainMessagesDeliveryProof, MessagesBridge}, + target_chain::FromBridgedChainMessagesProof, + BridgeMessagesCall, ChainWithMessages, DeliveredMessages, InboundLaneData, + InboundMessageDetails, LaneId, MessageKey, MessageNonce, MessagesOperatingMode, + OutboundLaneData, OutboundMessageDetails, UnrewardedRelayer, UnrewardedRelayersState, + VerificationError, +}; +use bp_runtime::{BasicOperatingMode, PreComputedSize, RangeInclusiveExt, Size}; +use bp_test_utils::generate_owned_bridge_module_tests; +use codec::Encode; +use frame_support::{ + assert_noop, assert_ok, + dispatch::Pays, + storage::generator::{StorageMap, StorageValue}, + traits::Hooks, + weights::Weight, +}; +use frame_system::{EventRecord, Pallet as System, Phase}; +use sp_core::Get; +use sp_runtime::DispatchError; + +fn get_ready_for_events() { + System::<TestRuntime>::set_block_number(1); + System::<TestRuntime>::reset_events(); +} + +fn send_regular_message(lane_id: LaneId) { + get_ready_for_events(); + + let outbound_lane = outbound_lane::<TestRuntime, ()>(lane_id); + let message_nonce = outbound_lane.data().latest_generated_nonce + 1; + let prev_enqueued_messages = outbound_lane.data().queued_messages().saturating_len(); + let valid_message = Pallet::<TestRuntime, ()>::validate_message(lane_id, ®ULAR_PAYLOAD) + .expect("validate_message has failed"); + let artifacts = Pallet::<TestRuntime, ()>::send_message(valid_message); + assert_eq!(artifacts.enqueued_messages, prev_enqueued_messages + 1); + + // check event with assigned nonce + assert_eq!( + System::<TestRuntime>::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: TestEvent::Messages(Event::MessageAccepted { lane_id, nonce: message_nonce }), + topics: vec![], + }], + ); +} + +fn receive_messages_delivery_proof() { + System::<TestRuntime>::set_block_number(1); + System::<TestRuntime>::reset_events(); + + assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + last_confirmed_nonce: 1, + relayers: vec![UnrewardedRelayer { + relayer: 0, + messages: DeliveredMessages::new(1), + }] + .into(), + }, + ), + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + messages_in_oldest_entry: 1, + total_messages: 1, + last_delivered_nonce: 1, + }, + )); + + assert_eq!( + System::<TestRuntime>::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: TestEvent::Messages(Event::MessagesDelivered { + lane_id: TEST_LANE_ID, + messages: DeliveredMessages::new(1), + }), + topics: vec![], + }], + ); +} + +#[test] +fn pallet_rejects_transactions_if_halted() { + run_test(|| { + // send message first to be able to check that delivery_proof fails later + send_regular_message(TEST_LANE_ID); + + PalletOperatingMode::<TestRuntime, ()>::put(MessagesOperatingMode::Basic( + BasicOperatingMode::Halted, + )); + + assert_noop!( + Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), + Error::<TestRuntime, ()>::NotOperatingNormally, + ); + + let messages_proof = prepare_messages_proof(vec![message(2, REGULAR_PAYLOAD)], None); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + messages_proof, + 1, + REGULAR_PAYLOAD.declared_weight, + ), + Error::<TestRuntime, ()>::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), + ); + + let delivery_proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + last_confirmed_nonce: 1, + relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)].into(), + }, + ); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + delivery_proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + messages_in_oldest_entry: 1, + total_messages: 1, + last_delivered_nonce: 1, + }, + ), + Error::<TestRuntime, ()>::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), + ); + }); +} + +#[test] +fn receive_messages_fails_if_dispatcher_is_inactive() { + run_test(|| { + TestMessageDispatch::deactivate(); + let proof = prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + 1, + REGULAR_PAYLOAD.declared_weight, + ), + Error::<TestRuntime, ()>::MessageDispatchInactive, + ); + }); +} + +#[test] +fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { + run_test(|| { + // send message first to be able to check that delivery_proof fails later + send_regular_message(TEST_LANE_ID); + + PalletOperatingMode::<TestRuntime, ()>::put( + MessagesOperatingMode::RejectingOutboundMessages, + ); + + assert_noop!( + Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), + Error::<TestRuntime, ()>::NotOperatingNormally, + ); + + assert_ok!(Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None), + 1, + REGULAR_PAYLOAD.declared_weight, + ),); + + assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + last_confirmed_nonce: 1, + relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)].into(), + }, + ), + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + messages_in_oldest_entry: 1, + total_messages: 1, + last_delivered_nonce: 1, + }, + )); + }); +} + +#[test] +fn send_message_works() { + run_test(|| { + send_regular_message(TEST_LANE_ID); + }); +} + +#[test] +fn send_message_rejects_too_large_message() { + run_test(|| { + let mut message_payload = message_payload(1, 0); + // the payload isn't simply extra, so it'll definitely overflow + // `max_outbound_payload_size` if we add `max_outbound_payload_size` bytes to extra + let max_outbound_payload_size = BridgedChain::maximal_incoming_message_size(); + message_payload + .extra + .extend_from_slice(&vec![0u8; max_outbound_payload_size as usize]); + assert_noop!( + Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &message_payload.clone(),), + Error::<TestRuntime, ()>::MessageRejectedByPallet(VerificationError::MessageTooLarge), + ); + + // let's check that we're able to send `max_outbound_payload_size` messages + while message_payload.encoded_size() as u32 > max_outbound_payload_size { + message_payload.extra.pop(); + } + assert_eq!(message_payload.encoded_size() as u32, max_outbound_payload_size); + + let valid_message = + Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &message_payload) + .expect("validate_message has failed"); + Pallet::<TestRuntime, ()>::send_message(valid_message); + }) +} + +#[test] +fn receive_messages_proof_works() { + run_test(|| { + assert_ok!(Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None), + 1, + REGULAR_PAYLOAD.declared_weight, + )); + + assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).0.last_delivered_nonce(), 1); + + assert!(TestDeliveryPayments::is_reward_paid(1)); + }); +} + +#[test] +fn receive_messages_proof_updates_confirmed_message_nonce() { + run_test(|| { + // say we have received 10 messages && last confirmed message is 8 + InboundLanes::<TestRuntime, ()>::insert( + TEST_LANE_ID, + InboundLaneData { + last_confirmed_nonce: 8, + relayers: vec![ + unrewarded_relayer(9, 9, TEST_RELAYER_A), + unrewarded_relayer(10, 10, TEST_RELAYER_B), + ] + .into(), + }, + ); + assert_eq!( + inbound_unrewarded_relayers_state(TEST_LANE_ID), + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + messages_in_oldest_entry: 1, + total_messages: 2, + last_delivered_nonce: 10, + }, + ); + + // message proof includes outbound lane state with latest confirmed message updated to 9 + assert_ok!(Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + prepare_messages_proof( + vec![message(11, REGULAR_PAYLOAD)], + Some(OutboundLaneData { latest_received_nonce: 9, ..Default::default() }), + ), + 1, + REGULAR_PAYLOAD.declared_weight, + )); + + assert_eq!( + InboundLanes::<TestRuntime>::get(TEST_LANE_ID).0, + InboundLaneData { + last_confirmed_nonce: 9, + relayers: vec![ + unrewarded_relayer(10, 10, TEST_RELAYER_B), + unrewarded_relayer(11, 11, TEST_RELAYER_A) + ] + .into(), + }, + ); + assert_eq!( + inbound_unrewarded_relayers_state(TEST_LANE_ID), + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + messages_in_oldest_entry: 1, + total_messages: 2, + last_delivered_nonce: 11, + }, + ); + }); +} + +#[test] +fn receive_messages_proof_does_not_accept_message_if_dispatch_weight_is_not_enough() { + run_test(|| { + let proof = prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None); + let mut declared_weight = REGULAR_PAYLOAD.declared_weight; + *declared_weight.ref_time_mut() -= 1; + + assert_noop!( + Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + 1, + declared_weight, + ), + Error::<TestRuntime, ()>::InsufficientDispatchWeight + ); + assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 0); + }); +} + +#[test] +fn receive_messages_proof_rejects_invalid_proof() { + run_test(|| { + let mut proof = prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None); + proof.nonces_end += 1; + + assert_noop!( + Pallet::<TestRuntime, ()>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + 1, + Weight::zero(), + ), + Error::<TestRuntime, ()>::InvalidMessagesProof, + ); + }); +} + +#[test] +fn receive_messages_proof_rejects_proof_with_too_many_messages() { + run_test(|| { + let proof = prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None); + assert_noop!( + Pallet::<TestRuntime, ()>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + u32::MAX, + Weight::zero(), + ), + Error::<TestRuntime, ()>::TooManyMessagesInTheProof, + ); + }); +} + +#[test] +fn receive_messages_delivery_proof_works() { + run_test(|| { + send_regular_message(TEST_LANE_ID); + receive_messages_delivery_proof(); + + assert_eq!(OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).latest_received_nonce, 1,); + }); +} + +#[test] +fn receive_messages_delivery_proof_rewards_relayers() { + run_test(|| { + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + + // this reports delivery of message 1 => reward is paid to TEST_RELAYER_A + let single_message_delivery_proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)].into(), + ..Default::default() + }, + ); + let single_message_delivery_proof_size = single_message_delivery_proof.size(); + let result = Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + single_message_delivery_proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + messages_in_oldest_entry: 1, + total_messages: 1, + last_delivered_nonce: 1, + }, + ); + assert_ok!(result); + assert_eq!( + result.unwrap().actual_weight.unwrap(), + TestWeightInfo::receive_messages_delivery_proof_weight( + &PreComputedSize(single_message_delivery_proof_size as _), + &UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + total_messages: 1, + ..Default::default() + }, + ) + ); + assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1)); + assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1)); + + // this reports delivery of both message 1 and message 2 => reward is paid only to + // TEST_RELAYER_B + let two_messages_delivery_proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + relayers: vec![ + unrewarded_relayer(1, 1, TEST_RELAYER_A), + unrewarded_relayer(2, 2, TEST_RELAYER_B), + ] + .into(), + ..Default::default() + }, + ); + let two_messages_delivery_proof_size = two_messages_delivery_proof.size(); + let result = Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + two_messages_delivery_proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + messages_in_oldest_entry: 1, + total_messages: 2, + last_delivered_nonce: 2, + }, + ); + assert_ok!(result); + // even though the pre-dispatch weight was for two messages, the actual weight is + // for single message only + assert_eq!( + result.unwrap().actual_weight.unwrap(), + TestWeightInfo::receive_messages_delivery_proof_weight( + &PreComputedSize(two_messages_delivery_proof_size as _), + &UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + total_messages: 1, + ..Default::default() + }, + ) + ); + assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1)); + assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1)); + assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 0))); + }); +} + +#[test] +fn receive_messages_delivery_proof_rejects_invalid_proof() { + run_test(|| { + let mut proof = prepare_messages_delivery_proof(TEST_LANE_ID, Default::default()); + proof.lane = bp_messages::LaneId([42, 42, 42, 42]); + + assert_noop!( + Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + Default::default(), + ), + Error::<TestRuntime, ()>::InvalidMessagesDeliveryProof, + ); + }); +} + +#[test] +fn receive_messages_delivery_proof_rejects_proof_if_declared_relayers_state_is_invalid() { + run_test(|| { + // when number of relayers entries is invalid + let proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + relayers: vec![ + unrewarded_relayer(1, 1, TEST_RELAYER_A), + unrewarded_relayer(2, 2, TEST_RELAYER_B), + ] + .into(), + ..Default::default() + }, + ); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + total_messages: 2, + last_delivered_nonce: 2, + ..Default::default() + }, + ), + Error::<TestRuntime, ()>::InvalidUnrewardedRelayersState, + ); + + // when number of messages is invalid + let proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + relayers: vec![ + unrewarded_relayer(1, 1, TEST_RELAYER_A), + unrewarded_relayer(2, 2, TEST_RELAYER_B), + ] + .into(), + ..Default::default() + }, + ); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + total_messages: 1, + last_delivered_nonce: 2, + ..Default::default() + }, + ), + Error::<TestRuntime, ()>::InvalidUnrewardedRelayersState, + ); + + // when last delivered nonce is invalid + let proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + relayers: vec![ + unrewarded_relayer(1, 1, TEST_RELAYER_A), + unrewarded_relayer(2, 2, TEST_RELAYER_B), + ] + .into(), + ..Default::default() + }, + ); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + total_messages: 2, + last_delivered_nonce: 8, + ..Default::default() + }, + ), + Error::<TestRuntime, ()>::InvalidUnrewardedRelayersState, + ); + }); +} + +#[test] +fn receive_messages_accepts_single_message_with_invalid_payload() { + run_test(|| { + let mut invalid_message = message(1, REGULAR_PAYLOAD); + invalid_message.payload = Vec::new(); + + assert_ok!(Pallet::<TestRuntime, ()>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + prepare_messages_proof(vec![invalid_message], None), + 1, + Weight::zero(), /* weight may be zero in this case (all messages are + * improperly encoded) */ + ),); + + assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 1,); + }); +} + +#[test] +fn receive_messages_accepts_batch_with_message_with_invalid_payload() { + run_test(|| { + let mut invalid_message = message(2, REGULAR_PAYLOAD); + invalid_message.payload = Vec::new(); + + assert_ok!(Pallet::<TestRuntime, ()>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + prepare_messages_proof( + vec![message(1, REGULAR_PAYLOAD), invalid_message, message(3, REGULAR_PAYLOAD),], + None + ), + 3, + REGULAR_PAYLOAD.declared_weight + REGULAR_PAYLOAD.declared_weight, + ),); + + assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 3,); + }); +} + +#[test] +fn actual_dispatch_weight_does_not_overflow() { + run_test(|| { + let message1 = message(1, message_payload(0, u64::MAX / 2)); + let message2 = message(2, message_payload(0, u64::MAX / 2)); + let message3 = message(3, message_payload(0, u64::MAX / 2)); + + let proof = prepare_messages_proof(vec![message1, message2, message3], None); + assert_noop!( + Pallet::<TestRuntime, ()>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + // this may cause overflow if source chain storage is invalid + proof, + 3, + Weight::MAX, + ), + Error::<TestRuntime, ()>::InsufficientDispatchWeight + ); + assert_eq!(InboundLanes::<TestRuntime>::get(TEST_LANE_ID).last_delivered_nonce(), 0); + }); +} + +#[test] +fn ref_time_refund_from_receive_messages_proof_works() { + run_test(|| { + fn submit_with_unspent_weight( + nonce: MessageNonce, + unspent_weight: u64, + ) -> (Weight, Weight) { + let mut payload = REGULAR_PAYLOAD; + *payload.dispatch_result.unspent_weight.ref_time_mut() = unspent_weight; + let proof = prepare_messages_proof(vec![message(nonce, payload)], None); + let messages_count = 1; + let pre_dispatch_weight = + <TestRuntime as Config>::WeightInfo::receive_messages_proof_weight( + &*proof, + messages_count, + REGULAR_PAYLOAD.declared_weight, + ); + let result = Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + messages_count, + REGULAR_PAYLOAD.declared_weight, + ) + .expect("delivery has failed"); + let post_dispatch_weight = + result.actual_weight.expect("receive_messages_proof always returns Some"); + + // message delivery transactions are never free + assert_eq!(result.pays_fee, Pays::Yes); + + (pre_dispatch_weight, post_dispatch_weight) + } + + // when dispatch is returning `unspent_weight < declared_weight` + let (pre, post) = submit_with_unspent_weight(1, 1); + assert_eq!(post.ref_time(), pre.ref_time() - 1); + + // when dispatch is returning `unspent_weight = declared_weight` + let (pre, post) = submit_with_unspent_weight(2, REGULAR_PAYLOAD.declared_weight.ref_time()); + assert_eq!(post.ref_time(), pre.ref_time() - REGULAR_PAYLOAD.declared_weight.ref_time()); + + // when dispatch is returning `unspent_weight > declared_weight` + let (pre, post) = + submit_with_unspent_weight(3, REGULAR_PAYLOAD.declared_weight.ref_time() + 1); + assert_eq!(post.ref_time(), pre.ref_time() - REGULAR_PAYLOAD.declared_weight.ref_time()); + + // when there's no unspent weight + let (pre, post) = submit_with_unspent_weight(4, 0); + assert_eq!(post.ref_time(), pre.ref_time()); + + // when dispatch is returning `unspent_weight < declared_weight` + let (pre, post) = submit_with_unspent_weight(5, 1); + assert_eq!(post.ref_time(), pre.ref_time() - 1); + }); +} + +#[test] +fn proof_size_refund_from_receive_messages_proof_works() { + run_test(|| { + let max_entries = BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as usize; + + // if there's maximal number of unrewarded relayer entries at the inbound lane, then + // `proof_size` is unchanged in post-dispatch weight + let proof = prepare_messages_proof(vec![message(101, REGULAR_PAYLOAD)], None); + let messages_count = 1; + let pre_dispatch_weight = + <TestRuntime as Config>::WeightInfo::receive_messages_proof_weight( + &*proof, + messages_count, + REGULAR_PAYLOAD.declared_weight, + ); + InboundLanes::<TestRuntime>::insert( + TEST_LANE_ID, + StoredInboundLaneData(InboundLaneData { + relayers: vec![ + UnrewardedRelayer { + relayer: 42, + messages: DeliveredMessages { begin: 0, end: 100 } + }; + max_entries + ] + .into(), + last_confirmed_nonce: 0, + }), + ); + let post_dispatch_weight = Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof.clone(), + messages_count, + REGULAR_PAYLOAD.declared_weight, + ) + .unwrap() + .actual_weight + .unwrap(); + assert_eq!(post_dispatch_weight.proof_size(), pre_dispatch_weight.proof_size()); + + // if count of unrewarded relayer entries is less than maximal, then some `proof_size` + // must be refunded + InboundLanes::<TestRuntime>::insert( + TEST_LANE_ID, + StoredInboundLaneData(InboundLaneData { + relayers: vec![ + UnrewardedRelayer { + relayer: 42, + messages: DeliveredMessages { begin: 0, end: 100 } + }; + max_entries - 1 + ] + .into(), + last_confirmed_nonce: 0, + }), + ); + let post_dispatch_weight = Pallet::<TestRuntime>::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + messages_count, + REGULAR_PAYLOAD.declared_weight, + ) + .unwrap() + .actual_weight + .unwrap(); + assert!( + post_dispatch_weight.proof_size() < pre_dispatch_weight.proof_size(), + "Expected post-dispatch PoV {} to be less than pre-dispatch PoV {}", + post_dispatch_weight.proof_size(), + pre_dispatch_weight.proof_size(), + ); + }); +} + +#[test] +fn receive_messages_delivery_proof_rejects_proof_if_trying_to_confirm_more_messages_than_expected() +{ + run_test(|| { + // send message first to be able to check that delivery_proof fails later + send_regular_message(TEST_LANE_ID); + + // 1) InboundLaneData declares that the `last_confirmed_nonce` is 1; + // 2) InboundLaneData has no entries => `InboundLaneData::last_delivered_nonce()` returns + // `last_confirmed_nonce`; + // 3) it means that we're going to confirm delivery of messages 1..=1; + // 4) so the number of declared messages (see `UnrewardedRelayersState`) is `0` and numer of + // actually confirmed messages is `1`. + let proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { last_confirmed_nonce: 1, relayers: Default::default() }, + ); + assert_noop!( + Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { last_delivered_nonce: 1, ..Default::default() }, + ), + Error::<TestRuntime, ()>::ReceptionConfirmation( + ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected + ), + ); + }); +} + +#[test] +fn storage_keys_computed_properly() { + assert_eq!( + PalletOperatingMode::<TestRuntime>::storage_value_final_key().to_vec(), + bp_messages::storage_keys::operating_mode_key("Messages").0, + ); + + assert_eq!( + OutboundMessages::<TestRuntime>::storage_map_final_key(MessageKey { + lane_id: TEST_LANE_ID, + nonce: 42 + }), + bp_messages::storage_keys::message_key("Messages", &TEST_LANE_ID, 42).0, + ); + + assert_eq!( + OutboundLanes::<TestRuntime>::storage_map_final_key(TEST_LANE_ID), + bp_messages::storage_keys::outbound_lane_data_key("Messages", &TEST_LANE_ID).0, + ); + + assert_eq!( + InboundLanes::<TestRuntime>::storage_map_final_key(TEST_LANE_ID), + bp_messages::storage_keys::inbound_lane_data_key("Messages", &TEST_LANE_ID).0, + ); +} + +#[test] +fn inbound_message_details_works() { + run_test(|| { + assert_eq!( + Pallet::<TestRuntime>::inbound_message_data( + TEST_LANE_ID, + REGULAR_PAYLOAD.encode(), + OutboundMessageDetails { nonce: 0, dispatch_weight: Weight::zero(), size: 0 }, + ), + InboundMessageDetails { dispatch_weight: REGULAR_PAYLOAD.declared_weight }, + ); + }); +} + +#[test] +fn on_idle_callback_respects_remaining_weight() { + run_test(|| { + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + + assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + last_confirmed_nonce: 4, + relayers: vec![unrewarded_relayer(1, 4, TEST_RELAYER_A)].into(), + }, + ), + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + messages_in_oldest_entry: 4, + total_messages: 4, + last_delivered_nonce: 4, + }, + )); + + // all 4 messages may be pruned now + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_received_nonce, 4); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + System::<TestRuntime>::set_block_number(2); + + // if passed wight is too low to do anything + let dbw = DbWeight::get(); + assert_eq!(Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(1, 1)), Weight::zero(),); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + + // if passed wight is enough to prune single message + assert_eq!( + Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(1, 2)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + + // if passed wight is enough to prune two more messages + assert_eq!( + Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(1, 3)), + dbw.reads_writes(1, 3), + ); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 4); + + // if passed wight is enough to prune many messages + assert_eq!( + Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 5); + }); +} + +#[test] +fn on_idle_callback_is_rotating_lanes_to_prune() { + run_test(|| { + // send + receive confirmation for lane 1 + send_regular_message(TEST_LANE_ID); + receive_messages_delivery_proof(); + // send + receive confirmation for lane 2 + send_regular_message(TEST_LANE_ID_2); + assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + prepare_messages_delivery_proof( + TEST_LANE_ID_2, + InboundLaneData { + last_confirmed_nonce: 1, + relayers: vec![unrewarded_relayer(1, 1, TEST_RELAYER_A)].into(), + }, + ), + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + messages_in_oldest_entry: 1, + total_messages: 1, + last_delivered_nonce: 1, + }, + )); + + // nothing is pruned yet + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_received_nonce, 1); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + assert_eq!( + outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().latest_received_nonce, + 1 + ); + assert_eq!( + outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 1 + ); + + // in block#2.on_idle lane messages of lane 1 are pruned + let dbw = DbWeight::get(); + System::<TestRuntime>::set_block_number(2); + assert_eq!( + Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 1 + ); + + // in block#3.on_idle lane messages of lane 2 are pruned + System::<TestRuntime>::set_block_number(3); + + assert_eq!( + Pallet::<TestRuntime, ()>::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::<TestRuntime, ()>(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 2 + ); + }); +} + +#[test] +fn outbound_message_from_unconfigured_lane_is_rejected() { + run_test(|| { + assert_noop!( + Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), + Error::<TestRuntime, ()>::InactiveOutboundLane, + ); + }); +} + +#[test] +fn test_bridge_messages_call_is_correctly_defined() { + run_test(|| { + let account_id = 1; + let message_proof = prepare_messages_proof(vec![message(1, REGULAR_PAYLOAD)], None); + let message_delivery_proof = prepare_messages_delivery_proof( + TEST_LANE_ID, + InboundLaneData { + last_confirmed_nonce: 1, + relayers: vec![UnrewardedRelayer { + relayer: 0, + messages: DeliveredMessages::new(1), + }] + .into(), + }, + ); + let unrewarded_relayer_state = UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + total_messages: 1, + last_delivered_nonce: 1, + ..Default::default() + }; + + let direct_receive_messages_proof_call = Call::<TestRuntime>::receive_messages_proof { + relayer_id_at_bridged_chain: account_id, + proof: message_proof.clone(), + messages_count: 1, + dispatch_weight: REGULAR_PAYLOAD.declared_weight, + }; + let indirect_receive_messages_proof_call = BridgeMessagesCall::< + AccountId, + FromBridgedChainMessagesProof<BridgedHeaderHash>, + FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash>, + >::receive_messages_proof { + relayer_id_at_bridged_chain: account_id, + proof: *message_proof, + messages_count: 1, + dispatch_weight: REGULAR_PAYLOAD.declared_weight, + }; + assert_eq!( + direct_receive_messages_proof_call.encode(), + indirect_receive_messages_proof_call.encode() + ); + + let direct_receive_messages_delivery_proof_call = + Call::<TestRuntime>::receive_messages_delivery_proof { + proof: message_delivery_proof.clone(), + relayers_state: unrewarded_relayer_state.clone(), + }; + let indirect_receive_messages_delivery_proof_call = BridgeMessagesCall::< + AccountId, + FromBridgedChainMessagesProof<BridgedHeaderHash>, + FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash>, + >::receive_messages_delivery_proof { + proof: message_delivery_proof, + relayers_state: unrewarded_relayer_state, + }; + assert_eq!( + direct_receive_messages_delivery_proof_call.encode(), + indirect_receive_messages_delivery_proof_call.encode() + ); + }); +} + +generate_owned_bridge_module_tests!( + MessagesOperatingMode::Basic(BasicOperatingMode::Normal), + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) +); + +#[test] +fn inbound_storage_extra_proof_size_bytes_works() { + fn relayer_entry() -> UnrewardedRelayer<TestRelayer> { + UnrewardedRelayer { relayer: 42u64, messages: DeliveredMessages { begin: 0, end: 100 } } + } + + fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage<TestRuntime, ()> { + RuntimeInboundLaneStorage { + lane_id: Default::default(), + cached_data: Some(InboundLaneData { + relayers: vec![relayer_entry(); relayer_entries].into(), + last_confirmed_nonce: 0, + }), + _phantom: Default::default(), + } + } + + let max_entries = BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as usize; + + // when we have exactly `MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX` unrewarded relayers + assert_eq!(storage(max_entries).extra_proof_size_bytes(), 0); + + // when we have less than `MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX` unrewarded relayers + assert_eq!( + storage(max_entries - 1).extra_proof_size_bytes(), + relayer_entry().encode().len() as u64 + ); + assert_eq!( + storage(max_entries - 2).extra_proof_size_bytes(), + 2 * relayer_entry().encode().len() as u64 + ); + + // when we have more than `MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX` unrewarded relayers + // (shall not happen in practice) + assert_eq!(storage(max_entries + 1).extra_proof_size_bytes(), 0); +} + +#[test] +fn maybe_outbound_lanes_count_returns_correct_value() { + assert_eq!( + MaybeOutboundLanesCount::<TestRuntime, ()>::get(), + Some(mock::ActiveOutboundLanes::get().len() as u32) + ); +} diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index 5bf7d56756079df8a5e469b9c50ba7607b65d983..72a06599b1655c52b9761c1b9af7c8d798631ddf 100644 --- a/bridges/modules/messages/src/weights.rs +++ b/bridges/modules/messages/src/weights.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for pallet_bridge_messages //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-03-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-06-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `covid`, CPU: `11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz` +//! HOSTNAME: `serban-ROG-Zephyrus`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: @@ -51,14 +51,13 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_bridge_messages. pub trait WeightInfo { fn receive_single_message_proof() -> Weight; - fn receive_two_messages_proof() -> Weight; + fn receive_n_messages_proof(n: u32) -> Weight; fn receive_single_message_proof_with_outbound_lane_state() -> Weight; - fn receive_single_message_proof_1_kb() -> Weight; - fn receive_single_message_proof_16_kb() -> Weight; + fn receive_single_n_bytes_message_proof(n: u32) -> Weight; fn receive_delivery_proof_for_single_message() -> Weight; fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight; fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight; - fn receive_single_message_proof_with_dispatch(i: u32) -> Weight; + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32) -> Weight; } /// Weights for `pallet_bridge_messages` that are generated using one of the Bridge testnets. @@ -82,56 +81,39 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 52_321 nanoseconds. - Weight::from_parts(54_478_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 38_724 nanoseconds. + Weight::from_parts(40_650_000, 52673) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoMessages PalletOperatingMode (r:1 w:0) /// - /// Proof: BridgeUnknownMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), + /// Proof: BridgeRialtoMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), /// added: 497, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownGrandpa ImportedHeaders (r:1 w:0) + /// Storage: BridgeRialtoGrandpa ImportedHeaders (r:1 w:0) /// - /// Proof: BridgeUnknownGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), + /// Proof: BridgeRialtoGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), /// added: 2048, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) - /// - /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) - fn receive_two_messages_proof() -> Weight { - // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 64_597 nanoseconds. - Weight::from_parts(69_267_000, 57170) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeUnknownMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), - /// added: 497, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49208), added: + /// 51683, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownGrandpa ImportedHeaders (r:1 w:0) + /// The range of component `n` is `[1, 1004]`. /// - /// Proof: BridgeUnknownGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), - /// added: 2048, mode: MaxEncodedLen) - /// - /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) - /// - /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) - fn receive_single_message_proof_with_outbound_lane_state() -> Weight { + /// The range of component `n` is `[1, 1004]`. + fn receive_n_messages_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 64_079 nanoseconds. - Weight::from_parts(65_905_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 39_354 nanoseconds. + Weight::from_parts(29_708_543, 52673) + // Standard Error: 1_185 + .saturating_add(Weight::from_parts(7_648_787, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -149,12 +131,12 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) - fn receive_single_message_proof_1_kb() -> Weight { + fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 50_588 nanoseconds. - Weight::from_parts(53_544_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 45_578 nanoseconds. + Weight::from_parts(47_161_000, 52673) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -172,12 +154,16 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) - fn receive_single_message_proof_16_kb() -> Weight { + /// + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 78_269 nanoseconds. - Weight::from_parts(81_748_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 38_702 nanoseconds. + Weight::from_parts(41_040_143, 52673) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_174, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -198,16 +184,21 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// /// Storage: BridgeRelayers RelayerRewards (r:1 w:1) /// - /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, + /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(93), added: 2568, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:1) + /// + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65596), + /// added: 68071, mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `579` - // Estimated: `9584` - // Minimum execution time: 45_786 nanoseconds. - Weight::from_parts(47_382_000, 9584) + // Measured: `701` + // Estimated: `3558` + // Minimum execution time: 37_197 nanoseconds. + Weight::from_parts(38_371_000, 3558) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) /// @@ -226,16 +217,21 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// /// Storage: BridgeRelayers RelayerRewards (r:1 w:1) /// - /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, + /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(93), added: 2568, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65596), + /// added: 68071, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `596` - // Estimated: `9584` - // Minimum execution time: 44_544 nanoseconds. - Weight::from_parts(45_451_000, 9584) + // Measured: `701` + // Estimated: `3558` + // Minimum execution time: 38_684 nanoseconds. + Weight::from_parts(39_929_000, 3558) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) /// @@ -254,16 +250,21 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// /// Storage: BridgeRelayers RelayerRewards (r:2 w:2) /// - /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, + /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(93), added: 2568, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65596), + /// added: 68071, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `596` - // Estimated: `12124` - // Minimum execution time: 47_344 nanoseconds. - Weight::from_parts(48_311_000, 12124) + // Measured: `701` + // Estimated: `6126` + // Minimum execution time: 41_363 nanoseconds. + Weight::from_parts(42_621_000, 6126) .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) /// @@ -280,15 +281,15 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) /// - /// The range of component `i` is `[128, 2048]`. - fn receive_single_message_proof_with_dispatch(i: u32) -> Weight { + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 52_385 nanoseconds. - Weight::from_parts(54_919_468, 57170) - // Standard Error: 108 - .saturating_add(Weight::from_parts(3_286, 0).saturating_mul(i.into())) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 38_925 nanoseconds. + Weight::from_parts(39_617_000, 52673) + // Standard Error: 612 + .saturating_add(Weight::from_parts(372_813, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -312,33 +313,39 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 52_321 nanoseconds. - Weight::from_parts(54_478_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 38_724 nanoseconds. + Weight::from_parts(40_650_000, 52673) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoMessages PalletOperatingMode (r:1 w:0) /// - /// Proof: BridgeUnknownMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), + /// Proof: BridgeRialtoMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), /// added: 497, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownGrandpa ImportedHeaders (r:1 w:0) + /// Storage: BridgeRialtoGrandpa ImportedHeaders (r:1 w:0) /// - /// Proof: BridgeUnknownGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), + /// Proof: BridgeRialtoGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), /// added: 2048, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) + /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) - fn receive_two_messages_proof() -> Weight { + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49208), added: + /// 51683, mode: MaxEncodedLen) + /// + /// The range of component `n` is `[1, 1004]`. + /// + /// The range of component `n` is `[1, 1004]`. + fn receive_n_messages_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 64_597 nanoseconds. - Weight::from_parts(69_267_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 39_354 nanoseconds. + Weight::from_parts(29_708_543, 52673) + // Standard Error: 1_185 + .saturating_add(Weight::from_parts(7_648_787, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -358,10 +365,10 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 64_079 nanoseconds. - Weight::from_parts(65_905_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 45_578 nanoseconds. + Weight::from_parts(47_161_000, 52673) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -377,37 +384,20 @@ impl WeightInfo for () { /// /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) - fn receive_single_message_proof_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 50_588 nanoseconds. - Weight::from_parts(53_544_000, 57170) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) - /// - /// Proof: BridgeUnknownMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), - /// added: 497, mode: MaxEncodedLen) - /// - /// Storage: BridgeUnknownGrandpa ImportedHeaders (r:1 w:0) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49208), added: + /// 51683, mode: MaxEncodedLen) /// - /// Proof: BridgeUnknownGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), - /// added: 2048, mode: MaxEncodedLen) + /// The range of component `n` is `[1, 16384]`. /// - /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) - /// - /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) - fn receive_single_message_proof_16_kb() -> Weight { + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 78_269 nanoseconds. - Weight::from_parts(81_748_000, 57170) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 38_702 nanoseconds. + Weight::from_parts(41_040_143, 52673) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_174, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -428,16 +418,21 @@ impl WeightInfo for () { /// /// Storage: BridgeRelayers RelayerRewards (r:1 w:1) /// - /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, + /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(93), added: 2568, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:1) + /// + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65596), + /// added: 68071, mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `579` - // Estimated: `9584` - // Minimum execution time: 45_786 nanoseconds. - Weight::from_parts(47_382_000, 9584) + // Measured: `701` + // Estimated: `3558` + // Minimum execution time: 37_197 nanoseconds. + Weight::from_parts(38_371_000, 3558) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) /// @@ -456,16 +451,21 @@ impl WeightInfo for () { /// /// Storage: BridgeRelayers RelayerRewards (r:1 w:1) /// - /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, + /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(93), added: 2568, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65596), + /// added: 68071, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `596` - // Estimated: `9584` - // Minimum execution time: 44_544 nanoseconds. - Weight::from_parts(45_451_000, 9584) + // Measured: `701` + // Estimated: `3558` + // Minimum execution time: 38_684 nanoseconds. + Weight::from_parts(39_929_000, 3558) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) /// @@ -484,16 +484,21 @@ impl WeightInfo for () { /// /// Storage: BridgeRelayers RelayerRewards (r:2 w:2) /// - /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, + /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(93), added: 2568, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65596), + /// added: 68071, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `596` - // Estimated: `12124` - // Minimum execution time: 47_344 nanoseconds. - Weight::from_parts(48_311_000, 12124) + // Measured: `701` + // Estimated: `6126` + // Minimum execution time: 41_363 nanoseconds. + Weight::from_parts(42_621_000, 6126) .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } /// Storage: BridgeUnknownMessages PalletOperatingMode (r:1 w:0) /// @@ -510,15 +515,15 @@ impl WeightInfo for () { /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) /// - /// The range of component `i` is `[128, 2048]`. - fn receive_single_message_proof_with_dispatch(i: u32) -> Weight { + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 52_385 nanoseconds. - Weight::from_parts(54_919_468, 57170) - // Standard Error: 108 - .saturating_add(Weight::from_parts(3_286, 0).saturating_mul(i.into())) + // Measured: `653` + // Estimated: `52673` + // Minimum execution time: 38_925 nanoseconds. + Weight::from_parts(39_617_000, 52673) + // Standard Error: 612 + .saturating_add(Weight::from_parts(372_813, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/bridges/modules/messages/src/weights_ext.rs b/bridges/modules/messages/src/weights_ext.rs index c12e04f692bf8304fb58d7c97ec50d1b860ccb56..7711e212efb06da0421f57b01ab4d1eef8b48f16 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -40,13 +40,6 @@ pub fn ensure_weights_are_correct<W: WeightInfoExt>() { // benchmarked using `MaxEncodedLen` approach and there are no components that cause additional // db reads - // verify `receive_messages_proof` weight components - assert_ne!(W::receive_messages_proof_overhead().ref_time(), 0); - assert_ne!(W::receive_messages_proof_overhead().proof_size(), 0); - // W::receive_messages_proof_messages_overhead(1).ref_time() may be zero because: - // the message processing code (`InboundLane::receive_message`) is minimal and may not be - // accounted by our benchmarks - assert_eq!(W::receive_messages_proof_messages_overhead(1).proof_size(), 0); // W::receive_messages_proof_outbound_lane_state_overhead().ref_time() may be zero because: // the outbound lane state processing code (`InboundLane::receive_state_update`) is minimal and // may not be accounted by our benchmarks @@ -86,6 +79,19 @@ pub fn ensure_weights_are_correct<W: WeightInfoExt>() { total_messages_in_delivery_proof_does_not_affect_proof_size::<W>(); } +/// Ensure that we are able to dispatch maximal size messages. +pub fn ensure_maximal_message_dispatch<W: WeightInfoExt>( + max_incoming_message_size: u32, + max_incoming_message_dispatch_weight: Weight, +) { + let message_dispatch_weight = W::message_dispatch_weight(max_incoming_message_size); + assert!( + message_dispatch_weight.all_lte(max_incoming_message_dispatch_weight), + "Dispatch weight of maximal message {message_dispatch_weight:?} must be lower \ + than the hardcoded {max_incoming_message_dispatch_weight:?}", + ); +} + /// Ensure that we're able to receive maximal (by-size and by-weight) message from other chain. pub fn ensure_able_to_receive_message<W: WeightInfoExt>( max_extrinsic_size: u32, @@ -98,7 +104,8 @@ pub fn ensure_able_to_receive_message<W: WeightInfoExt>( max_incoming_message_proof_size.saturating_add(SIGNED_EXTENSIONS_SIZE); assert!( max_delivery_transaction_size <= max_extrinsic_size, - "Size of maximal message delivery transaction {max_incoming_message_proof_size} + {SIGNED_EXTENSIONS_SIZE} is larger than maximal possible transaction size {max_extrinsic_size}", + "Size of maximal message delivery transaction {max_incoming_message_proof_size} + \ + {SIGNED_EXTENSIONS_SIZE} is larger than maximal possible transaction size {max_extrinsic_size}", ); // verify that we're able to receive proof of maximal-size message with maximal dispatch weight @@ -297,13 +304,11 @@ pub trait WeightInfoExt: WeightInfo { dispatch_weight: Weight, ) -> Weight { // basic components of extrinsic weight - let transaction_overhead = Self::receive_messages_proof_overhead(); + let base_weight = Self::receive_n_messages_proof(messages_count); let transaction_overhead_from_runtime = Self::receive_messages_proof_overhead_from_runtime(); let outbound_state_delivery_weight = Self::receive_messages_proof_outbound_lane_state_overhead(); - let messages_delivery_weight = - Self::receive_messages_proof_messages_overhead(MessageNonce::from(messages_count)); let messages_dispatch_weight = dispatch_weight; // proof size overhead weight @@ -315,10 +320,9 @@ pub trait WeightInfoExt: WeightInfo { actual_proof_size.saturating_sub(expected_proof_size), ); - transaction_overhead + base_weight .saturating_add(transaction_overhead_from_runtime) .saturating_add(outbound_state_delivery_weight) - .saturating_add(messages_delivery_weight) .saturating_add(messages_dispatch_weight) .saturating_add(proof_size_overhead) } @@ -354,25 +358,6 @@ pub trait WeightInfoExt: WeightInfo { // Functions that are used by extrinsics weights formulas. - /// Returns weight overhead of message delivery transaction (`receive_messages_proof`). - fn receive_messages_proof_overhead() -> Weight { - let weight_of_two_messages_and_two_tx_overheads = - Self::receive_single_message_proof().saturating_mul(2); - let weight_of_two_messages_and_single_tx_overhead = Self::receive_two_messages_proof(); - weight_of_two_messages_and_two_tx_overheads - .saturating_sub(weight_of_two_messages_and_single_tx_overhead) - } - - /// Returns weight that needs to be accounted when receiving given a number of messages with - /// message delivery transaction (`receive_messages_proof`). - fn receive_messages_proof_messages_overhead(messages: MessageNonce) -> Weight { - let weight_of_two_messages_and_single_tx_overhead = Self::receive_two_messages_proof(); - let weight_of_single_message_and_single_tx_overhead = Self::receive_single_message_proof(); - weight_of_two_messages_and_single_tx_overhead - .saturating_sub(weight_of_single_message_and_single_tx_overhead) - .saturating_mul(messages as _) - } - /// Returns weight that needs to be accounted when message delivery transaction /// (`receive_messages_proof`) is carrying outbound lane state proof. fn receive_messages_proof_outbound_lane_state_overhead() -> Weight { @@ -426,9 +411,8 @@ pub trait WeightInfoExt: WeightInfo { /// is less than that cost). fn storage_proof_size_overhead(proof_size: u32) -> Weight { let proof_size_in_bytes = proof_size; - let byte_weight = (Self::receive_single_message_proof_16_kb() - - Self::receive_single_message_proof_1_kb()) / - (15 * 1024); + let byte_weight = Self::receive_single_n_bytes_message_proof(2) - + Self::receive_single_n_bytes_message_proof(1); proof_size_in_bytes * byte_weight } @@ -440,11 +424,9 @@ pub trait WeightInfoExt: WeightInfo { /// `receive_single_message_proof_with_dispatch` benchmark. See its requirements for /// details. fn message_dispatch_weight(message_size: u32) -> Weight { - // There may be a tiny overweight/underweight here, because we don't account how message - // size affects all steps before dispatch. But the effect should be small enough and we - // may ignore it. - Self::receive_single_message_proof_with_dispatch(message_size) - .saturating_sub(Self::receive_single_message_proof()) + let message_size_in_bytes = message_size; + Self::receive_single_n_bytes_message_proof_with_dispatch(message_size_in_bytes) + .saturating_sub(Self::receive_single_n_bytes_message_proof(message_size_in_bytes)) } } @@ -479,7 +461,7 @@ impl<T: frame_system::Config> WeightInfoExt for crate::weights::BridgeWeight<T> #[cfg(test)] mod tests { use super::*; - use crate::{mock::TestRuntime, weights::BridgeWeight}; + use crate::{tests::mock::TestRuntime, weights::BridgeWeight}; #[test] fn ensure_default_weights_are_correct() { diff --git a/bridges/modules/parachains/Cargo.toml b/bridges/modules/parachains/Cargo.toml index 97bad724a789ea0cdf0f0c972b153606fc302e7f..cda0ee8106d5400c33e186265d672f1b9282dc0d 100644 --- a/bridges/modules/parachains/Cargo.toml +++ b/bridges/modules/parachains/Cargo.toml @@ -30,7 +30,6 @@ frame-support = { workspace = true } frame-system = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } -sp-trie = { workspace = true } [dev-dependencies] bp-header-chain = { workspace = true, default-features = true } @@ -54,7 +53,6 @@ std = [ "scale-info/std", "sp-runtime/std", "sp-std/std", - "sp-trie/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/bridges/modules/parachains/src/benchmarking.rs b/bridges/modules/parachains/src/benchmarking.rs index 27e06a12a1d93486d93aa258afc1d7de4713df2c..92ece6d688cbea3bed2e5d489163f2416bef9bbc 100644 --- a/bridges/modules/parachains/src/benchmarking.rs +++ b/bridges/modules/parachains/src/benchmarking.rs @@ -22,7 +22,7 @@ use crate::{ }; use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId}; -use bp_runtime::StorageProofSize; +use bp_runtime::UnverifiedStorageProofParams; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_system::RawOrigin; use sp_std::prelude::*; @@ -38,7 +38,7 @@ pub trait Config<I: 'static>: crate::Config<I> { fn prepare_parachain_heads_proof( parachains: &[ParaId], parachain_head_size: u32, - proof_size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>); } @@ -68,7 +68,7 @@ benchmarks_instance_pallet! { let (relay_block_number, relay_block_hash, parachain_heads_proof, parachains_heads) = T::prepare_parachain_heads_proof( ¶chains, DEFAULT_PARACHAIN_HEAD_SIZE, - StorageProofSize::Minimal(0), + UnverifiedStorageProofParams::default(), ); let at_relay_block = (relay_block_number, relay_block_hash); }: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains_heads, parachain_heads_proof) @@ -85,7 +85,7 @@ benchmarks_instance_pallet! { let (relay_block_number, relay_block_hash, parachain_heads_proof, parachains_heads) = T::prepare_parachain_heads_proof( ¶chains, DEFAULT_PARACHAIN_HEAD_SIZE, - StorageProofSize::HasLargeLeaf(1024), + UnverifiedStorageProofParams::from_db_size(1024), ); let at_relay_block = (relay_block_number, relay_block_hash); }: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains_heads, parachain_heads_proof) @@ -102,7 +102,7 @@ benchmarks_instance_pallet! { let (relay_block_number, relay_block_hash, parachain_heads_proof, parachains_heads) = T::prepare_parachain_heads_proof( ¶chains, DEFAULT_PARACHAIN_HEAD_SIZE, - StorageProofSize::HasLargeLeaf(16 * 1024), + UnverifiedStorageProofParams::from_db_size(16 * 1024), ); let at_relay_block = (relay_block_number, relay_block_hash); }: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains_heads, parachain_heads_proof) diff --git a/bridges/modules/parachains/src/call_ext.rs b/bridges/modules/parachains/src/call_ext.rs index fe6b319205d41491ce2df36d8a1d112eb37f94b4..0f77eaf2c5a93d372cab8af0857f10fa40ca920f 100644 --- a/bridges/modules/parachains/src/call_ext.rs +++ b/bridges/modules/parachains/src/call_ext.rs @@ -289,7 +289,7 @@ mod tests { RuntimeCall::Parachains(crate::Call::<TestRuntime, ()>::submit_parachain_heads_ex { at_relay_block: (num, [num as u8; 32].into()), parachains, - parachain_heads_proof: ParaHeadsProof { storage_proof: Vec::new() }, + parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() }, is_free_execution_expected: false, }) .check_obsolete_submit_parachain_heads() @@ -303,7 +303,7 @@ mod tests { RuntimeCall::Parachains(crate::Call::<TestRuntime, ()>::submit_parachain_heads_ex { at_relay_block: (num, [num as u8; 32].into()), parachains, - parachain_heads_proof: ParaHeadsProof { storage_proof: Vec::new() }, + parachain_heads_proof: ParaHeadsProof { storage_proof: Default::default() }, is_free_execution_expected: true, }) .check_obsolete_submit_parachain_heads() diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index d323aef3b22070d1db1e4709fe0dad8bf0360caf..e2c30ce9aecc1eb3b39fc588cc6386481f82fa7f 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -28,11 +28,12 @@ pub use weights::WeightInfo; pub use weights_ext::WeightInfoExt; use bp_header_chain::{HeaderChain, HeaderChainError}; -use bp_parachains::{parachain_head_storage_key_at_source, ParaInfo, ParaStoredHeaderData}; -use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId}; -use bp_runtime::{Chain, HashOf, HeaderId, HeaderIdOf, Parachain, StorageProofError}; +use bp_parachains::{ParaInfo, ParaStoredHeaderData}; +use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId}; +use bp_runtime::{Chain, HashOf, HeaderId, HeaderIdOf, Parachain}; use frame_support::{dispatch::PostDispatchInfo, DefaultNoBound}; use pallet_bridge_grandpa::SubmitFinalityProofHelper; +use proofs::{ParachainsStorageProofAdapter, StorageProofAdapter}; use sp_std::{marker::PhantomData, vec::Vec}; #[cfg(feature = "runtime-benchmarks")] @@ -55,6 +56,7 @@ pub mod benchmarking; mod call_ext; #[cfg(test)] mod mock; +mod proofs; /// The target that will be used when publishing logs related to this pallet. pub const LOG_TARGET: &str = "runtime::bridge-parachains"; @@ -448,15 +450,15 @@ pub mod pallet { parachains.len() as _, ); - let mut is_updated_something = false; - let mut storage = GrandpaPalletOf::<T, I>::storage_proof_checker( - relay_block_hash, - parachain_heads_proof.storage_proof, - ) - .map_err(Error::<T, I>::HeaderChainStorageProof)?; + let mut storage: ParachainsStorageProofAdapter<T, I> = + ParachainsStorageProofAdapter::try_new_with_verified_storage_proof( + relay_block_hash, + parachain_heads_proof.storage_proof, + ) + .map_err(Error::<T, I>::HeaderChainStorageProof)?; for (parachain, parachain_head_hash) in parachains { - let parachain_head = match Self::read_parachain_head(&mut storage, parachain) { + let parachain_head = match storage.read_parachain_head(parachain) { Ok(Some(parachain_head)) => parachain_head, Ok(None) => { log::trace!( @@ -541,7 +543,6 @@ pub mod pallet { parachain_head_hash, )?; - is_updated_something = true; if is_free { free_parachain_heads = free_parachain_heads + 1; } @@ -572,7 +573,7 @@ pub mod pallet { // => treat this as an error // // (we can throw error here, because now all our calls are transactional) - storage.ensure_no_unused_nodes().map_err(|e| { + storage.ensure_no_unused_keys().map_err(|e| { Error::<T, I>::HeaderChainStorageProof(HeaderChainError::StorageProof(e)) })?; @@ -633,16 +634,6 @@ pub mod pallet { ImportedParaHeads::<T, I>::get(parachain, hash).map(|h| h.into_inner()) } - /// Read parachain head from storage proof. - fn read_parachain_head( - storage: &mut bp_runtime::StorageProofChecker<RelayBlockHasher>, - parachain: ParaId, - ) -> Result<Option<ParaHead>, StorageProofError> { - let parachain_head_key = - parachain_head_storage_key_at_source(T::ParasPalletName::get(), parachain); - storage.read_and_decode_value(parachain_head_key.0.as_ref()) - } - /// Try to update parachain head. pub(super) fn update_parachain_head( parachain: ParaId, @@ -801,6 +792,7 @@ impl<T: Config<I>, I: 'static, C: Parachain<Hash = ParaHash>> HeaderChain<C> pub fn initialize_for_benchmarks<T: Config<I>, I: 'static, PC: Parachain<Hash = ParaHash>>( header: HeaderOf<PC>, ) { + use bp_polkadot_core::parachains::ParaHead; use bp_runtime::HeaderIdProvider; use sp_runtime::traits::Header; @@ -844,9 +836,10 @@ pub(crate) mod tests { use bp_parachains::{ BestParaHeadHash, BridgeParachainCall, ImportedParaHeadsKeyProvider, ParasInfoKeyProvider, }; + use bp_polkadot_core::parachains::ParaHead; use bp_runtime::{ BasicOperatingMode, OwnedBridgeModuleError, StorageDoubleMapKeyProvider, - StorageMapKeyProvider, + StorageMapKeyProvider, StorageProofError, }; use bp_test_utils::{ authority_list, generate_owned_bridge_module_tests, make_default_justification, diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index dbb62845392d5fd2f408744f4f8a2321ec4bd34d..c49b5939093c50a17fbf369533d5ff9c01b625bc 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -23,7 +23,7 @@ use frame_support::{ use sp_runtime::{ testing::H256, traits::{BlakeTwo256, Header as HeaderT}, - MultiSignature, + MultiSignature, StateVersion, }; use crate as pallet_bridge_parachains; @@ -60,6 +60,8 @@ impl Chain for Parachain1 { type Nonce = u64; type Signature = MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 0 } @@ -87,6 +89,8 @@ impl Chain for Parachain2 { type Nonce = u64; type Signature = MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 0 } @@ -114,6 +118,8 @@ impl Chain for Parachain3 { type Nonce = u64; type Signature = MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 0 } @@ -142,6 +148,8 @@ impl Chain for BigParachain { type Nonce = u64; type Signature = MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 0 } @@ -222,7 +230,7 @@ impl pallet_bridge_parachains::benchmarking::Config<()> for TestRuntime { fn prepare_parachain_heads_proof( parachains: &[ParaId], _parachain_head_size: u32, - _proof_size: bp_runtime::StorageProofSize, + _proof_params: bp_runtime::UnverifiedStorageProofParams, ) -> ( crate::RelayBlockNumber, crate::RelayBlockHash, @@ -256,38 +264,7 @@ impl Chain for TestBridgedChain { type Nonce = u32; type Signature = sp_runtime::testing::TestSignature; - fn max_extrinsic_size() -> u32 { - unreachable!() - } - - fn max_extrinsic_weight() -> Weight { - unreachable!() - } -} - -impl ChainWithGrandpa for TestBridgedChain { - const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = ""; - const MAX_AUTHORITIES_COUNT: u32 = 16; - const REASONABLE_HEADERS_IN_JUSTIFICATION_ANCESTRY: u32 = 8; - const MAX_MANDATORY_HEADER_SIZE: u32 = 256; - const AVERAGE_HEADER_SIZE: u32 = 64; -} - -#[derive(Debug)] -pub struct OtherBridgedChain; - -impl Chain for OtherBridgedChain { - const ID: ChainId = *b"obch"; - - type BlockNumber = u64; - type Hash = crate::RelayBlockHash; - type Hasher = crate::RelayBlockHasher; - type Header = sp_runtime::generic::Header<u64, crate::RelayBlockHasher>; - - type AccountId = AccountId; - type Balance = u32; - type Nonce = u32; - type Signature = sp_runtime::testing::TestSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; fn max_extrinsic_size() -> u32 { unreachable!() @@ -298,7 +275,7 @@ impl Chain for OtherBridgedChain { } } -impl ChainWithGrandpa for OtherBridgedChain { +impl ChainWithGrandpa for TestBridgedChain { const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str = ""; const MAX_AUTHORITIES_COUNT: u32 = 16; const REASONABLE_HEADERS_IN_JUSTIFICATION_ANCESTRY: u32 = 8; diff --git a/bridges/modules/parachains/src/proofs.rs b/bridges/modules/parachains/src/proofs.rs new file mode 100644 index 0000000000000000000000000000000000000000..dcf22229f3423a9a75f4be68d1af2b1bf2e7ea1e --- /dev/null +++ b/bridges/modules/parachains/src/proofs.rs @@ -0,0 +1,81 @@ +// 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 <http://www.gnu.org/licenses/>. + +//! Tools for parachain head proof verification. + +use crate::{Config, GrandpaPalletOf, RelayBlockHash, RelayBlockHasher}; +use bp_header_chain::{HeaderChain, HeaderChainError}; +use bp_parachains::parachain_head_storage_key_at_source; +use bp_polkadot_core::parachains::{ParaHead, ParaId}; +use bp_runtime::{RawStorageProof, StorageProofChecker, StorageProofError}; +use codec::Decode; +use frame_support::traits::Get; + +/// Abstraction over storage proof manipulation, hiding implementation details of actual storage +/// proofs. +pub trait StorageProofAdapter<T: Config<I>, I: 'static> { + /// Read and decode optional value from the proof. + fn read_and_decode_optional_value<D: Decode>( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result<Option<D>, StorageProofError>; + + /// Checks if each key was read. + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError>; + + /// Read parachain head from storage proof. + fn read_parachain_head( + &mut self, + parachain: ParaId, + ) -> Result<Option<ParaHead>, StorageProofError> { + let parachain_head_key = + parachain_head_storage_key_at_source(T::ParasPalletName::get(), parachain); + self.read_and_decode_optional_value(¶chain_head_key) + } +} + +/// Actual storage proof adapter for parachain proofs. +pub type ParachainsStorageProofAdapter<T, I> = RawStorageProofAdapter<T, I>; + +/// A `StorageProofAdapter` implementation for raw storage proofs. +pub struct RawStorageProofAdapter<T: Config<I>, I: 'static> { + storage: StorageProofChecker<RelayBlockHasher>, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl<T: Config<I>, I: 'static> RawStorageProofAdapter<T, I> { + /// Try to create a new instance of `RawStorageProofAdapter`. + pub fn try_new_with_verified_storage_proof( + relay_block_hash: RelayBlockHash, + storage_proof: RawStorageProof, + ) -> Result<Self, HeaderChainError> { + GrandpaPalletOf::<T, I>::verify_storage_proof(relay_block_hash, storage_proof) + .map(|storage| RawStorageProofAdapter::<T, I> { storage, _dummy: Default::default() }) + } +} + +impl<T: Config<I>, I: 'static> StorageProofAdapter<T, I> for RawStorageProofAdapter<T, I> { + fn read_and_decode_optional_value<D: Decode>( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result<Option<D>, StorageProofError> { + self.storage.read_and_decode_opt_value(key.as_ref()) + } + + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { + self.storage.ensure_no_unused_nodes() + } +} diff --git a/bridges/modules/parachains/src/weights.rs b/bridges/modules/parachains/src/weights.rs index abddc8768947006e574bf6bca4d2301c2047199a..1f92b7ff763c3f572efef1acf141a9eba0d3eb0e 100644 --- a/bridges/modules/parachains/src/weights.rs +++ b/bridges/modules/parachains/src/weights.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for pallet_bridge_parachains //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-03-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-06-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `covid`, CPU: `11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz` +//! HOSTNAME: `serban-ROG-Zephyrus`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: @@ -86,14 +86,12 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// Some(196), added: 1681, mode: MaxEncodedLen) /// /// The range of component `p` is `[1, 2]`. - fn submit_parachain_heads_with_n_parachains(p: u32) -> Weight { + fn submit_parachain_heads_with_n_parachains(_p: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `366` - // Estimated: `4648` - // Minimum execution time: 36_701 nanoseconds. - Weight::from_parts(38_597_828, 4648) - // Standard Error: 190_859 - .saturating_add(Weight::from_parts(60_685, 0).saturating_mul(p.into())) + // Measured: `302` + // Estimated: `3038` + // Minimum execution time: 30_211 nanoseconds. + Weight::from_parts(32_633_893, 3038) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -123,10 +121,10 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// Some(196), added: 1681, mode: MaxEncodedLen) fn submit_parachain_heads_with_1kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `366` - // Estimated: `4648` - // Minimum execution time: 38_189 nanoseconds. - Weight::from_parts(39_252_000, 4648) + // Measured: `302` + // Estimated: `3038` + // Minimum execution time: 30_830 nanoseconds. + Weight::from_parts(31_801_000, 3038) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -156,10 +154,10 @@ impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> { /// Some(196), added: 1681, mode: MaxEncodedLen) fn submit_parachain_heads_with_16kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `366` - // Estimated: `4648` - // Minimum execution time: 62_868 nanoseconds. - Weight::from_parts(63_581_000, 4648) + // Measured: `302` + // Estimated: `3038` + // Minimum execution time: 44_736 nanoseconds. + Weight::from_parts(45_296_000, 3038) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -193,14 +191,12 @@ impl WeightInfo for () { /// Some(196), added: 1681, mode: MaxEncodedLen) /// /// The range of component `p` is `[1, 2]`. - fn submit_parachain_heads_with_n_parachains(p: u32) -> Weight { + fn submit_parachain_heads_with_n_parachains(_p: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `366` - // Estimated: `4648` - // Minimum execution time: 36_701 nanoseconds. - Weight::from_parts(38_597_828, 4648) - // Standard Error: 190_859 - .saturating_add(Weight::from_parts(60_685, 0).saturating_mul(p.into())) + // Measured: `302` + // Estimated: `3038` + // Minimum execution time: 30_211 nanoseconds. + Weight::from_parts(32_633_893, 3038) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -230,10 +226,10 @@ impl WeightInfo for () { /// Some(196), added: 1681, mode: MaxEncodedLen) fn submit_parachain_heads_with_1kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `366` - // Estimated: `4648` - // Minimum execution time: 38_189 nanoseconds. - Weight::from_parts(39_252_000, 4648) + // Measured: `302` + // Estimated: `3038` + // Minimum execution time: 30_830 nanoseconds. + Weight::from_parts(31_801_000, 3038) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -263,10 +259,10 @@ impl WeightInfo for () { /// Some(196), added: 1681, mode: MaxEncodedLen) fn submit_parachain_heads_with_16kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `366` - // Estimated: `4648` - // Minimum execution time: 62_868 nanoseconds. - Weight::from_parts(63_581_000, 4648) + // Measured: `302` + // Estimated: `3038` + // Minimum execution time: 44_736 nanoseconds. + Weight::from_parts(45_296_000, 3038) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } diff --git a/bridges/modules/relayers/src/payment_adapter.rs b/bridges/modules/relayers/src/payment_adapter.rs index b2d9c676bddc493700a45fc957235dbb9516296b..f75c409aca4f3ef85fab748e4dc41af12b545562 100644 --- a/bridges/modules/relayers/src/payment_adapter.rs +++ b/bridges/modules/relayers/src/payment_adapter.rs @@ -23,6 +23,7 @@ use bp_messages::{ LaneId, MessageNonce, }; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; +use bp_runtime::Chain; use frame_support::{sp_runtime::SaturatedConversion, traits::Get}; use sp_arithmetic::traits::{Saturating, Zero}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive}; @@ -57,7 +58,7 @@ where relayers_rewards, RewardsAccountParams::new( lane_id, - T::BridgedChainId::get(), + T::BridgedChain::ID, RewardsAccountOwner::BridgedChain, ), DeliveryReward::get(), diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 4c09bce56d73eea717ad5149084e2ae337e48e87..df72e7a3c4fcc596cd89cc119c44aeb7c6915eaf 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -20,23 +20,17 @@ use crate as pallet_xcm_bridge_hub; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, - LaneId, -}; -use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, UnderlyingChainProvider}; -use bridge_runtime_common::{ - messages::{ - source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, - BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, - }, - messages_xcm_extension::{SenderAndLane, XcmBlobHauler}, + ChainWithMessages, LaneId, MessageNonce, }; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; +use bridge_runtime_common::messages_xcm_extension::{SenderAndLane, XcmBlobHauler}; use codec::Encode; -use frame_support::{derive_impl, parameter_types, traits::ConstU32, weights::RuntimeDbWeight}; +use frame_support::{derive_impl, parameter_types, weights::RuntimeDbWeight}; use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, traits::{BlakeTwo256, IdentityLookup}, - AccountId32, BuildStorage, + AccountId32, BuildStorage, StateVersion, }; use xcm::prelude::*; @@ -85,20 +79,17 @@ impl pallet_bridge_messages::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = TestMessagesWeights; - type BridgedChainId = (); type ActiveOutboundLanes = ActiveOutboundLanes; - type MaxUnrewardedRelayerEntriesAtInboundLane = (); - type MaxUnconfirmedMessagesAtInboundLane = (); - type MaximalOutboundPayloadSize = ConstU32<2048>; type OutboundPayload = Vec<u8>; type InboundPayload = Vec<u8>; - type InboundRelayer = (); type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter<OnThisChainBridge>; type DeliveryConfirmationPayments = (); type OnMessagesDelivered = (); - type SourceHeaderChain = SourceHeaderChainAdapter<OnThisChainBridge>; type MessageDispatch = TestMessageDispatch; + + type ThisChain = ThisUnderlyingChain; + type BridgedChain = BridgedUnderlyingChain; + type BridgedHeaderChain = BridgedHeaderChain; } pub struct TestMessagesWeights; @@ -107,34 +98,27 @@ impl pallet_bridge_messages::WeightInfo for TestMessagesWeights { fn receive_single_message_proof() -> Weight { Weight::zero() } - fn receive_single_message_proof_with_outbound_lane_state() -> Weight { + fn receive_n_messages_proof(_: u32) -> Weight { Weight::zero() } - fn receive_delivery_proof_for_single_message() -> Weight { + fn receive_single_message_proof_with_outbound_lane_state() -> Weight { Weight::zero() } - fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { + fn receive_single_n_bytes_message_proof(_: u32) -> Weight { Weight::zero() } - fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { + fn receive_delivery_proof_for_single_message() -> Weight { Weight::zero() } - - fn receive_two_messages_proof() -> Weight { + fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { Weight::zero() } - - fn receive_single_message_proof_1_kb() -> Weight { + fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { Weight::zero() } - - fn receive_single_message_proof_16_kb() -> Weight { + fn receive_single_n_bytes_message_proof_with_dispatch(_: u32) -> Weight { Weight::zero() } - - fn receive_single_message_proof_with_dispatch(_: u32) -> Weight { - Weight::from_parts(1, 0) - } } impl pallet_bridge_messages::WeightInfoExt for TestMessagesWeights { @@ -198,9 +182,9 @@ impl XcmBlobHauler for TestXcmBlobHauler { type UncongestedMessage = (); } -pub struct ThisChain; +pub struct ThisUnderlyingChain; -impl Chain for ThisChain { +impl Chain for ThisUnderlyingChain { const ID: ChainId = *b"tuch"; type BlockNumber = u64; type Hash = H256; @@ -211,6 +195,8 @@ impl Chain for ThisChain { type Nonce = u64; type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { u32::MAX } @@ -220,12 +206,19 @@ impl Chain for ThisChain { } } -pub struct BridgedChain; +impl ChainWithMessages for ThisUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; +} + +pub struct BridgedUnderlyingChain; pub type BridgedHeaderHash = H256; pub type BridgedChainHeader = SubstrateHeader; -impl Chain for BridgedChain { - const ID: ChainId = *b"tuch"; +impl Chain for BridgedUnderlyingChain { + const ID: ChainId = *b"bgdc"; type BlockNumber = u64; type Hash = BridgedHeaderHash; type Hasher = BlakeTwo256; @@ -235,6 +228,8 @@ impl Chain for BridgedChain { type Nonce = u64; type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 4096 } @@ -244,6 +239,12 @@ impl Chain for BridgedChain { } } +impl ChainWithMessages for BridgedUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; +} + /// Test message dispatcher. pub struct TestMessageDispatch; @@ -272,42 +273,15 @@ impl MessageDispatch for TestMessageDispatch { } } -pub struct WrappedThisChain; -impl UnderlyingChainProvider for WrappedThisChain { - type Chain = ThisChain; -} -impl ThisChainWithMessages for WrappedThisChain { - type RuntimeOrigin = RuntimeOrigin; -} - -pub struct WrappedBridgedChain; -impl UnderlyingChainProvider for WrappedBridgedChain { - type Chain = BridgedChain; -} -impl BridgedChainWithMessages for WrappedBridgedChain {} - pub struct BridgedHeaderChain; -impl bp_header_chain::HeaderChain<BridgedChain> for BridgedHeaderChain { +impl bp_header_chain::HeaderChain<BridgedUnderlyingChain> for BridgedHeaderChain { fn finalized_header_state_root( - _hash: HashOf<WrappedBridgedChain>, - ) -> Option<HashOf<WrappedBridgedChain>> { + _hash: HashOf<BridgedUnderlyingChain>, + ) -> Option<HashOf<BridgedUnderlyingChain>> { unreachable!() } } -/// 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 BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; - - type ThisChain = WrappedThisChain; - type BridgedChain = WrappedBridgedChain; - type BridgedHeaderChain = BridgedHeaderChain; -} - /// Run pallet test. pub fn run_test<T>(test: impl FnOnce() -> T) -> T { sp_io::TestExternalities::new( diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index af2afb65a26a7f206fdbfcf22e20cb5100a8c95f..26295dee1801a127f455ed3288bd5232cb60bc10 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -46,7 +46,7 @@ pub mod storage_keys; pub enum HeaderChainError { /// Header with given hash is missing from the chain. UnknownHeader, - /// Storage proof related error. + /// Error generated by the `storage_proof` module. StorageProof(StorageProofError), } @@ -78,8 +78,9 @@ impl<H: HeaderT> StoredHeaderDataBuilder<H::Number, H::Hash> for H { pub trait HeaderChain<C: Chain> { /// Returns state (storage) root of given finalized header. fn finalized_header_state_root(header_hash: HashOf<C>) -> Option<HashOf<C>>; + /// Get storage proof checker using finalized header. - fn storage_proof_checker( + fn verify_storage_proof( header_hash: HashOf<C>, storage_proof: RawStorageProof, ) -> Result<StorageProofChecker<HasherOf<C>>, HeaderChainError> { @@ -409,7 +410,9 @@ mod tests { use super::*; use bp_runtime::ChainId; use frame_support::weights::Weight; - use sp_runtime::{testing::H256, traits::BlakeTwo256, DigestItem, MultiSignature}; + use sp_runtime::{ + testing::H256, traits::BlakeTwo256, DigestItem, MultiSignature, StateVersion, + }; struct TestChain; @@ -425,6 +428,8 @@ mod tests { type Nonce = u64; type Signature = MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 0 } diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index c3f79b3ee388c4584def56056f6cdf6328032e18..9984f8ac3222780ea2fd6af56dd896beb264b2d5 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -38,6 +38,9 @@ pub mod source_chain; pub mod storage_keys; pub mod target_chain; +/// Hard limit on message size that can be sent over the bridge. +pub const HARD_MESSAGE_SIZE_LIMIT: u32 = 64 * 1024; + /// Substrate-based chain with messaging support. pub trait ChainWithMessages: Chain { /// Name of the bridge messages pallet (used in `construct_runtime` macro call) that is @@ -48,11 +51,63 @@ pub trait ChainWithMessages: Chain { const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str; /// Maximal number of unrewarded relayers in a single confirmation transaction at this - /// `ChainWithMessages`. + /// `ChainWithMessages`. Unrewarded means that the relayer has delivered messages, but + /// either confirmations haven't been delivered back to the source chain, or we haven't + /// received reward confirmations yet. + /// + /// This constant limits maximal number of entries in the `InboundLaneData::relayers`. Keep + /// in mind that the same relayer account may take several (non-consecutive) entries in this + /// set. const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce; /// Maximal number of unconfirmed messages in a single confirmation transaction at this - /// `ChainWithMessages`. + /// `ChainWithMessages`. Unconfirmed means that the + /// message has been delivered, but either confirmations haven't been delivered back to the + /// source chain, or we haven't received reward confirmations for these messages yet. + /// + /// This constant limits difference between last message from last entry of the + /// `InboundLaneData::relayers` and first message at the first entry. + /// + /// There is no point of making this parameter lesser than + /// `MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX`, because then maximal number of relayer entries + /// will be limited by maximal number of messages. + /// + /// This value also represents maximal number of messages in single delivery transaction. + /// Transaction that is declaring more messages than this value, will be rejected. Even if + /// these messages are from different lanes. const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce; + + /// Return maximal dispatch weight of the message we're able to receive. + fn maximal_incoming_message_dispatch_weight() -> Weight { + // we leave 1/2 of `max_extrinsic_weight` for the delivery transaction itself + Self::max_extrinsic_weight() / 2 + } + + /// Return maximal size of the message we're able to receive. + fn maximal_incoming_message_size() -> u32 { + maximal_incoming_message_size(Self::max_extrinsic_size()) + } +} + +/// Return maximal size of the message the chain with `max_extrinsic_size` is able to receive. +pub fn maximal_incoming_message_size(max_extrinsic_size: u32) -> u32 { + // The maximal size of extrinsic at Substrate-based chain depends on the + // `frame_system::Config::MaximumBlockLength` and + // `frame_system::Config::AvailableBlockRatio` constants. This check is here to be sure that + // the lane won't stuck because message is too large to fit into delivery transaction. + // + // **IMPORTANT NOTE**: the delivery transaction contains storage proof of the message, not + // the message itself. The proof is always larger than the message. But unless chain state + // is enormously large, it should be several dozens/hundreds of bytes. The delivery + // transaction also contains signatures and signed extensions. Because of this, we reserve + // 1/3 of the the maximal extrinsic size for this data. + // + // **ANOTHER IMPORTANT NOTE**: large message means not only larger proofs and heavier + // proof verification, but also heavier message decoding and dispatch. So we have a hard + // limit of `64Kb`, which in practice limits the message size on all chains. Without this + // limit the **weight** (not the size) of the message will be higher than the + // `Self::maximal_incoming_message_dispatch_weight()`. + + sp_std::cmp::min(max_extrinsic_size / 3 * 2, HARD_MESSAGE_SIZE_LIMIT) } impl<T> ChainWithMessages for T @@ -112,7 +167,19 @@ impl OperatingMode for MessagesOperatingMode { /// Lane id which implements `TypeId`. #[derive( - Clone, Copy, Decode, Default, Encode, Eq, Ord, PartialOrd, PartialEq, TypeInfo, MaxEncodedLen, + Clone, + Copy, + Decode, + Default, + Encode, + Eq, + Ord, + PartialOrd, + PartialEq, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, )] pub struct LaneId(pub [u8; 4]); @@ -435,7 +502,7 @@ where AccountId: sp_std::cmp::Ord, { // remember to reward relayers that have delivered messages - // this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain + // this loop is bounded by `T::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX` on the bridged chain let mut relayers_rewards = RelayersRewards::new(); for entry in messages_relayers { let nonce_begin = sp_std::cmp::max(entry.messages.begin, *received_range.start()); @@ -486,11 +553,11 @@ pub enum VerificationError { InvalidMessageWeight, /// Declared messages count doesn't match actual value. MessagesCountMismatch, - /// Error returned while reading/decoding message data from the storage proof. + /// Error returned while reading/decoding message data from the `VerifiedStorageProof`. MessageStorage(StorageProofError), /// The message is too large. MessageTooLarge, - /// Error returned while reading/decoding outbound lane data from the storage proof. + /// Error returned while reading/decoding outbound lane data from the `VerifiedStorageProof`. OutboundLaneStorage(StorageProofError), /// Storage proof related error. StorageProof(StorageProofError), diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index f4aefd9735583e265c3e44713f13f81ae63ba276..64f015bdb822eb25ff42a3fdb52bf6405a5424bf 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -16,11 +16,11 @@ //! Primitives of messages module, that are used on the source chain. -use crate::{InboundLaneData, LaneId, MessageNonce, VerificationError}; +use crate::{LaneId, MessageNonce, UnrewardedRelayer}; -use crate::UnrewardedRelayer; -use bp_runtime::Size; -use frame_support::Parameter; +use bp_runtime::{raw_storage_proof_size, RawStorageProof, Size}; +use codec::{Decode, Encode}; +use scale_info::TypeInfo; use sp_core::RuntimeDebug; use sp_std::{ collections::{btree_map::BTreeMap, vec_deque::VecDeque}, @@ -28,42 +28,36 @@ use sp_std::{ ops::RangeInclusive, }; -/// Number of messages, delivered by relayers. -pub type RelayersRewards<AccountId> = BTreeMap<AccountId, MessageNonce>; - -/// Target chain API. Used by source chain to verify target chain proofs. +/// Messages delivery proof from the bridged chain. /// -/// All implementations of this trait should only work with finalized data that -/// can't change. Wrong implementation may lead to invalid lane states (i.e. lane -/// that's stuck) and/or processing messages without paying fees. +/// It contains everything required to prove that our (this chain) messages have been +/// delivered to the bridged (target) chain: /// -/// The `Payload` type here means the payload of the message that is sent from the -/// source chain to the target chain. The `AccountId` type here means the account -/// type used by the source chain. -pub trait TargetHeaderChain<Payload, AccountId> { - /// Proof that messages have been received by target chain. - type MessagesDeliveryProof: Parameter + Size; - - /// Verify message payload before we accept it. - /// - /// **CAUTION**: this is very important function. Incorrect implementation may lead - /// to stuck lanes and/or relayers loses. - /// - /// The proper implementation must ensure that the delivery-transaction with this - /// payload would (at least) be accepted into target chain transaction pool AND - /// eventually will be successfully mined. The most obvious incorrect implementation - /// example would be implementation for BTC chain that accepts payloads larger than - /// 1MB. BTC nodes aren't accepting transactions that are larger than 1MB, so relayer - /// will be unable to craft valid transaction => this (and all subsequent) messages will - /// never be delivered. - fn verify_message(payload: &Payload) -> Result<(), VerificationError>; - - /// Verify messages delivery proof and return lane && nonce of the latest received message. - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData<AccountId>), VerificationError>; +/// - hash of finalized header; +/// +/// - storage proof of the inbound lane state; +/// +/// - lane id. +#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash> { + /// Hash of the bridge header the proof is for. + pub bridged_header_hash: BridgedHeaderHash, + /// Storage trie proof generated for [`Self::bridged_header_hash`]. + pub storage_proof: RawStorageProof, + /// Lane id of which messages were delivered and the proof is for. + pub lane: LaneId, +} + +impl<BridgedHeaderHash> Size for FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash> { + fn size(&self) -> u32 { + use frame_support::sp_runtime::SaturatedConversion; + raw_storage_proof_size(&self.storage_proof).saturated_into() + } } +/// Number of messages, delivered by relayers. +pub type RelayersRewards<AccountId> = BTreeMap<AccountId, MessageNonce>; + /// Manages payments that are happening at the source chain during delivery confirmation /// transaction. pub trait DeliveryConfirmationPayments<AccountId> { @@ -143,28 +137,10 @@ pub trait MessagesBridge<Payload> { fn send_message(message: Self::SendMessageArgs) -> SendMessageArtifacts; } -/// Structure that may be used in place of `TargetHeaderChain` and -/// `MessageDeliveryAndDispatchPayment` on chains, where outbound messages are forbidden. +/// Structure that may be used in place `MessageDeliveryAndDispatchPayment` on chains, +/// where outbound messages are forbidden. pub struct ForbidOutboundMessages; -/// Error message that is used in `ForbidOutboundMessages` implementation. -const ALL_OUTBOUND_MESSAGES_REJECTED: &str = - "This chain is configured to reject all outbound messages"; - -impl<Payload, AccountId> TargetHeaderChain<Payload, AccountId> for ForbidOutboundMessages { - type MessagesDeliveryProof = (); - - fn verify_message(_payload: &Payload) -> Result<(), VerificationError> { - Err(VerificationError::Other(ALL_OUTBOUND_MESSAGES_REJECTED)) - } - - fn verify_messages_delivery_proof( - _proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData<AccountId>), VerificationError> { - Err(VerificationError::Other(ALL_OUTBOUND_MESSAGES_REJECTED)) - } -} - impl<AccountId> DeliveryConfirmationPayments<AccountId> for ForbidOutboundMessages { type Error = &'static str; diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index 388ce16ccdc06d3e2c42c3a094aae4d6180a0d09..74fecb9d9f0d89420d2ca54a4356e23c9130e614 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -16,17 +16,48 @@ //! Primitives of messages module, that are used on the target chain. -use crate::{ - LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, -}; +use crate::{LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData}; -use bp_runtime::{messages::MessageDispatchResult, Size}; +use bp_runtime::{messages::MessageDispatchResult, raw_storage_proof_size, RawStorageProof, Size}; use codec::{Decode, Encode, Error as CodecError}; -use frame_support::{weights::Weight, Parameter}; +use frame_support::weights::Weight; use scale_info::TypeInfo; use sp_core::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, marker::PhantomData, prelude::*}; +/// Messages proof from bridged chain. +/// +/// It contains everything required to prove that bridged (source) chain has +/// sent us some messages: +/// +/// - hash of finalized header; +/// +/// - storage proof of messages and (optionally) outbound lane state; +/// +/// - lane id; +/// +/// - nonces (inclusive range) of messages which are included in this proof. +#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct FromBridgedChainMessagesProof<BridgedHeaderHash> { + /// Hash of the finalized bridged header the proof is for. + pub bridged_header_hash: BridgedHeaderHash, + /// A storage trie proof of messages being delivered. + pub storage_proof: RawStorageProof, + /// Messages in this proof are sent over this lane. + pub lane: LaneId, + /// Nonce of the first message being delivered. + pub nonces_start: MessageNonce, + /// Nonce of the last message being delivered. + pub nonces_end: MessageNonce, +} + +impl<BridgedHeaderHash> Size for FromBridgedChainMessagesProof<BridgedHeaderHash> { + fn size(&self) -> u32 { + use frame_support::sp_runtime::SaturatedConversion; + raw_storage_proof_size(&self.storage_proof).saturated_into() + } +} + /// Proved messages from the source chain. pub type ProvedMessages<Message> = BTreeMap<LaneId, ProvedLaneMessages<Message>>; @@ -55,33 +86,6 @@ pub struct DispatchMessage<DispatchPayload> { pub data: DispatchMessageData<DispatchPayload>, } -/// Source chain API. Used by target chain, to verify source chain proofs. -/// -/// All implementations of this trait should only work with finalized data that -/// can't change. Wrong implementation may lead to invalid lane states (i.e. lane -/// that's stuck) and/or processing messages without paying fees. -pub trait SourceHeaderChain { - /// Proof that messages are sent from source chain. This may also include proof - /// of corresponding outbound lane states. - type MessagesProof: Parameter + Size; - - /// Verify messages proof and return proved messages. - /// - /// Returns error if either proof is incorrect, or the number of messages in the proof - /// is not matching the `messages_count`. - /// - /// Messages vector is required to be sorted by nonce within each lane. Out-of-order - /// messages will be rejected. - /// - /// The `messages_count` argument verification (sane limits) is supposed to be made - /// outside this function. This function only verifies that the proof declares exactly - /// `messages_count` messages. - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result<ProvedMessages<Message>, VerificationError>; -} - /// Called when inbound message is received. pub trait MessageDispatch { /// Decoded message payload type. Valid message may contain invalid payload. In this case @@ -167,32 +171,11 @@ impl<AccountId> DeliveryPayments<AccountId> for () { } } -/// Structure that may be used in place of `SourceHeaderChain` and `MessageDispatch` on chains, +/// Structure that may be used in place of `MessageDispatch` on chains, /// where inbound messages are forbidden. -pub struct ForbidInboundMessages<MessagesProof, DispatchPayload>( - PhantomData<(MessagesProof, DispatchPayload)>, -); - -/// Error message that is used in `ForbidInboundMessages` implementation. -const ALL_INBOUND_MESSAGES_REJECTED: &str = - "This chain is configured to reject all inbound messages"; - -impl<MessagesProof: Parameter + Size, DispatchPayload> SourceHeaderChain - for ForbidInboundMessages<MessagesProof, DispatchPayload> -{ - type MessagesProof = MessagesProof; - - fn verify_messages_proof( - _proof: Self::MessagesProof, - _messages_count: u32, - ) -> Result<ProvedMessages<Message>, VerificationError> { - Err(VerificationError::Other(ALL_INBOUND_MESSAGES_REJECTED)) - } -} +pub struct ForbidInboundMessages<DispatchPayload>(PhantomData<DispatchPayload>); -impl<MessagesProof, DispatchPayload: Decode> MessageDispatch - for ForbidInboundMessages<MessagesProof, DispatchPayload> -{ +impl<DispatchPayload: Decode> MessageDispatch for ForbidInboundMessages<DispatchPayload> { type DispatchPayload = DispatchPayload; type DispatchLevelResult = (); diff --git a/bridges/primitives/polkadot-core/src/parachains.rs b/bridges/primitives/polkadot-core/src/parachains.rs index 433cd2845abd9ae95687d6f1d024765ee3bd2ebb..d54ee108386edf50865c500eb1062c24b01c0c3e 100644 --- a/bridges/primitives/polkadot-core/src/parachains.rs +++ b/bridges/primitives/polkadot-core/src/parachains.rs @@ -22,7 +22,7 @@ //! parachains. Having pallets that are referencing polkadot, would mean that there may //! be two versions of polkadot crates included in the runtime. Which is bad. -use bp_runtime::{RawStorageProof, Size}; +use bp_runtime::{raw_storage_proof_size, RawStorageProof, Size}; use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_core::Hasher; @@ -96,11 +96,7 @@ pub struct ParaHeadsProof { impl Size for ParaHeadsProof { fn size(&self) -> u32 { - u32::try_from( - self.storage_proof - .iter() - .fold(0usize, |sum, node| sum.saturating_add(node.len())), - ) - .unwrap_or(u32::MAX) + use frame_support::sp_runtime::SaturatedConversion; + raw_storage_proof_size(&self.storage_proof).saturated_into() } } diff --git a/bridges/primitives/runtime/Cargo.toml b/bridges/primitives/runtime/Cargo.toml index 5fa35e688996f1c13ea7d94f0de5a3b9813d4574..117409b37b9457f93194585b12aabd0de00d5c7f 100644 --- a/bridges/primitives/runtime/Cargo.toml +++ b/bridges/primitives/runtime/Cargo.toml @@ -53,3 +53,4 @@ std = [ "sp-trie/std", "trie-db/std", ] +test-helpers = [] diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 369386e41b0cf9f2d911ca40fc9e6ccfb3de6e52..0db4eac79a7500bf295756efaef514f5a4429e6c 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -24,7 +24,7 @@ use sp_runtime::{ AtLeast32Bit, AtLeast32BitUnsigned, Hash as HashT, Header as HeaderT, MaybeDisplay, MaybeSerialize, MaybeSerializeDeserialize, Member, SimpleBitOps, Verify, }, - FixedPointOperand, + FixedPointOperand, StateVersion, }; use sp_std::{fmt::Debug, hash::Hash, str::FromStr, vec, vec::Vec}; @@ -196,6 +196,10 @@ pub trait Chain: Send + Sync + 'static { /// Signature type, used on this chain. type Signature: Parameter + Verify; + /// Version of the state implementation used by this chain. This is directly related with the + /// `TrieLayout` configuration used by the storage. + const STATE_VERSION: StateVersion; + /// Get the maximum size (in bytes) of a Normal extrinsic at this chain. fn max_extrinsic_size() -> u32; /// Get the maximum weight (compute time) that a Normal extrinsic at this chain can use. @@ -223,6 +227,8 @@ where type Nonce = <T::Chain as Chain>::Nonce; type Signature = <T::Chain as Chain>::Signature; + const STATE_VERSION: StateVersion = <T::Chain as Chain>::STATE_VERSION; + fn max_extrinsic_size() -> u32 { <T::Chain as Chain>::max_extrinsic_size() } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index d13c9b40efa0b4ddf1433fdc87ce59eb13c7d9a3..8f5040ad9a1bee5efad995b4e62d5e883dfb0c9f 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -40,15 +40,18 @@ pub use chain::{ }; pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; +#[cfg(feature = "std")] +pub use storage_proof::craft_valid_storage_proof; +#[cfg(feature = "test-helpers")] pub use storage_proof::{ - record_all_keys as record_all_trie_keys, Error as StorageProofError, - ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker, + grow_storage_proof, grow_storage_value, record_all_keys as record_all_trie_keys, + UnverifiedStorageProofParams, +}; +pub use storage_proof::{ + raw_storage_proof_size, RawStorageProof, StorageProofChecker, StorageProofError, }; pub use storage_types::BoundedStorageValue; -#[cfg(feature = "std")] -pub use storage_proof::craft_valid_storage_proof; - pub mod extensions; pub mod messages; @@ -461,38 +464,6 @@ macro_rules! generate_static_str_provider { }; } -/// Error message that is only displayable in `std` environment. -#[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, TypeInfo)] -#[scale_info(skip_type_params(T))] -pub struct StrippableError<T> { - _phantom_data: sp_std::marker::PhantomData<T>, - #[codec(skip)] - #[cfg(feature = "std")] - message: String, -} - -impl<T: Debug> From<T> for StrippableError<T> { - fn from(_err: T) -> Self { - Self { - _phantom_data: Default::default(), - #[cfg(feature = "std")] - message: format!("{:?}", _err), - } - } -} - -impl<T> Debug for StrippableError<T> { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { - f.write_str(&self.message) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { - f.write_str("Stripped error") - } -} - /// A trait defining helper methods for `RangeInclusive` (start..=end) pub trait RangeInclusiveExt<Idx> { /// Computes the length of the `RangeInclusive`, checking for underflow and overflow. diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 251ceec5a9ee7b18bce428a6e8128790e0542d29..7bfa0d6fde01186f1fe09e66dd3ba1accf286ce5 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -14,34 +14,91 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>. -//! Logic for checking Substrate storage proofs. +//! Logic for working with storage proofs. -use crate::StrippableError; -use codec::{Decode, Encode}; use frame_support::PalletError; -use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; -use scale_info::TypeInfo; -use sp_std::{boxed::Box, vec::Vec}; -pub use sp_trie::RawStorageProof; +use sp_core::RuntimeDebug; +use sp_std::{default::Default, vec::Vec}; use sp_trie::{ - accessed_nodes_tracker::{AccessedNodesTracker, Error as AccessedNodesTrackerError}, - read_trie_value, - recorder_ext::RecorderExt, - LayoutV1, MemoryDB, Recorder, StorageProof, StorageProofError, Trie, TrieConfiguration, - TrieDBBuilder, TrieError, TrieHash, + accessed_nodes_tracker::AccessedNodesTracker, read_trie_value, LayoutV1, MemoryDB, StorageProof, }; -/// Storage proof size requirements. +use codec::{Decode, Encode}; +use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; +use scale_info::TypeInfo; +#[cfg(feature = "test-helpers")] +use sp_trie::{recorder_ext::RecorderExt, Recorder, TrieDBBuilder, TrieError, TrieHash}; +#[cfg(feature = "test-helpers")] +use trie_db::{Trie, TrieConfiguration, TrieDBMut}; + +/// Errors that can occur when interacting with `UnverifiedStorageProof` and `VerifiedStorageProof`. +#[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] +pub enum StorageProofError { + /// Call to `generate_trie_proof()` failed. + UnableToGenerateTrieProof, + /// Call to `verify_trie_proof()` failed. + InvalidProof, + /// The `Vec` entries weren't sorted as expected. + UnsortedEntries, + /// The provided key wasn't found. + UnavailableKey, + /// The value associated to the provided key is `None`. + EmptyVal, + /// Error decoding value associated to a provided key. + DecodeError, + /// At least one key or node wasn't read. + UnusedKey, + + /// Expected storage root is missing from the proof. (for non-compact proofs) + StorageRootMismatch, + /// Unable to reach expected storage value using provided trie nodes. (for non-compact proofs) + StorageValueUnavailable, + /// The proof contains duplicate nodes. (for non-compact proofs) + DuplicateNodes, +} + +impl From<sp_trie::StorageProofError> for StorageProofError { + fn from(e: sp_trie::StorageProofError) -> Self { + match e { + sp_trie::StorageProofError::DuplicateNodes => StorageProofError::DuplicateNodes, + } + } +} + +impl From<sp_trie::accessed_nodes_tracker::Error> for StorageProofError { + fn from(e: sp_trie::accessed_nodes_tracker::Error) -> Self { + match e { + sp_trie::accessed_nodes_tracker::Error::UnusedNodes => StorageProofError::UnusedKey, + } + } +} + +/// Raw storage proof type (just raw trie nodes). +pub type RawStorageProof = sp_trie::RawStorageProof; + +/// Calculates size for `RawStorageProof`. +pub fn raw_storage_proof_size(raw_storage_proof: &RawStorageProof) -> usize { + raw_storage_proof + .iter() + .fold(0usize, |sum, node| sum.saturating_add(node.len())) +} + +/// Storage values size requirements. /// /// This is currently used by benchmarks when generating storage proofs. -#[derive(Clone, Copy, Debug)] -pub enum ProofSize { - /// The proof is expected to be minimal. If value size may be changed, then it is expected to - /// have given size. - Minimal(u32), - /// The proof is expected to have at least given size and grow by increasing value that is - /// stored in the trie. - HasLargeLeaf(u32), +#[cfg(feature = "test-helpers")] +#[derive(Clone, Copy, Debug, Default)] +pub struct UnverifiedStorageProofParams { + /// Expected storage proof size in bytes. + pub db_size: Option<u32>, +} + +#[cfg(feature = "test-helpers")] +impl UnverifiedStorageProofParams { + /// Make storage proof parameters that require proof of at least `db_size` bytes. + pub fn from_db_size(db_size: u32) -> Self { + Self { db_size: Some(db_size) } + } } /// This struct is used to read storage values from a subset of a Merklized database. The "proof" @@ -64,15 +121,14 @@ where /// Constructs a new storage proof checker. /// /// This returns an error if the given proof is invalid with respect to the given root. - pub fn new(root: H::Out, proof: RawStorageProof) -> Result<Self, Error> { - let proof = StorageProof::new_with_duplicate_nodes_check(proof) - .map_err(|e| Error::StorageProof(e.into()))?; + pub fn new(root: H::Out, proof: RawStorageProof) -> Result<Self, StorageProofError> { + let proof = StorageProof::new_with_duplicate_nodes_check(proof)?; let recorder = AccessedNodesTracker::new(proof.len()); let db = proof.into_memory_db(); if !db.contains(&root, EMPTY_PREFIX) { - return Err(Error::StorageRootMismatch) + return Err(StorageProofError::StorageRootMismatch) } Ok(StorageProofChecker { root, db, accessed_nodes_tracker: recorder }) @@ -80,15 +136,13 @@ where /// Returns error if the proof has some nodes that are left intact by previous `read_value` /// calls. - pub fn ensure_no_unused_nodes(self) -> Result<(), Error> { - self.accessed_nodes_tracker - .ensure_no_unused_nodes() - .map_err(|e| Error::AccessedNodesTracker(e.into())) + pub fn ensure_no_unused_nodes(self) -> Result<(), StorageProofError> { + self.accessed_nodes_tracker.ensure_no_unused_nodes().map_err(Into::into) } /// Reads a value from the available subset of storage. If the value cannot be read due to an /// incomplete or otherwise invalid proof, this function returns an error. - pub fn read_value(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> { + pub fn read_value(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>, StorageProofError> { // LayoutV1 or LayoutV0 is identical for proof that only read values. read_trie_value::<LayoutV1<H>, _>( &self.db, @@ -97,53 +151,131 @@ where Some(&mut self.accessed_nodes_tracker), None, ) - .map_err(|_| Error::StorageValueUnavailable) + .map_err(|_| StorageProofError::StorageValueUnavailable) } /// Reads and decodes a value from the available subset of storage. If the value cannot be read /// due to an incomplete or otherwise invalid proof, this function returns an error. If value is /// read, but decoding fails, this function returns an error. - pub fn read_and_decode_value<T: Decode>(&mut self, key: &[u8]) -> Result<Option<T>, Error> { + pub fn read_and_decode_value<T: Decode>( + &mut self, + key: &[u8], + ) -> Result<Option<T>, StorageProofError> { self.read_value(key).and_then(|v| { - v.map(|v| T::decode(&mut &v[..]).map_err(|e| Error::StorageValueDecodeFailed(e.into()))) - .transpose() + v.map(|v| { + T::decode(&mut &v[..]).map_err(|e| { + log::warn!(target: "bridge-storage-proofs", "read_and_decode_value error: {e:?}"); + StorageProofError::DecodeError + }) + }) + .transpose() }) } /// Reads and decodes a value from the available subset of storage. If the value cannot be read /// due to an incomplete or otherwise invalid proof, or if the value is `None`, this function /// returns an error. If value is read, but decoding fails, this function returns an error. - pub fn read_and_decode_mandatory_value<T: Decode>(&mut self, key: &[u8]) -> Result<T, Error> { - self.read_and_decode_value(key)?.ok_or(Error::StorageValueEmpty) + pub fn read_and_decode_mandatory_value<T: Decode>( + &mut self, + key: &[u8], + ) -> Result<T, StorageProofError> { + self.read_and_decode_value(key)?.ok_or(StorageProofError::EmptyVal) } /// Reads and decodes a value from the available subset of storage. If the value cannot be read /// due to an incomplete or otherwise invalid proof, this function returns `Ok(None)`. /// If value is read, but decoding fails, this function returns an error. - pub fn read_and_decode_opt_value<T: Decode>(&mut self, key: &[u8]) -> Result<Option<T>, Error> { + pub fn read_and_decode_opt_value<T: Decode>( + &mut self, + key: &[u8], + ) -> Result<Option<T>, StorageProofError> { match self.read_and_decode_value(key) { Ok(outbound_lane_data) => Ok(outbound_lane_data), - Err(Error::StorageValueUnavailable) => Ok(None), + Err(StorageProofError::StorageValueUnavailable) => Ok(None), Err(e) => Err(e), } } } -/// Storage proof related errors. -#[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, Debug, TypeInfo)] -pub enum Error { - /// Error generated by the `AccessedNodesTrackerError`. - AccessedNodesTracker(StrippableError<AccessedNodesTrackerError>), - /// Error originating in the `storage_proof` module. - StorageProof(StrippableError<StorageProofError>), - /// Expected storage root is missing from the proof. - StorageRootMismatch, - /// Unable to reach expected storage value using provided trie nodes. - StorageValueUnavailable, - /// The storage value is `None`. - StorageValueEmpty, - /// Failed to decode storage value. - StorageValueDecodeFailed(StrippableError<codec::Error>), +/// Add extra data to the storage value so that it'll be of given size. +#[cfg(feature = "test-helpers")] +pub fn grow_storage_value(mut value: Vec<u8>, params: &UnverifiedStorageProofParams) -> Vec<u8> { + if let Some(db_size) = params.db_size { + if db_size as usize > value.len() { + value.extend(sp_std::iter::repeat(42u8).take(db_size as usize - value.len())); + } + } + value +} + +/// Insert values in the provided trie at common-prefix keys in order to inflate the resulting +/// storage proof. +/// +/// This function can add at most 15 common-prefix keys per prefix nibble (4 bits). +/// Each such key adds about 33 bytes (a node) to the proof. +#[cfg(feature = "test-helpers")] +pub fn grow_storage_proof<L: TrieConfiguration>( + trie: &mut TrieDBMut<L>, + prefix: Vec<u8>, + num_extra_nodes: usize, +) { + use sp_trie::TrieMut; + + let mut added_nodes = 0; + for i in 0..prefix.len() { + let mut prefix = prefix[0..=i].to_vec(); + // 1 byte has 2 nibbles (4 bits each) + let first_nibble = (prefix[i] & 0xf0) >> 4; + let second_nibble = prefix[i] & 0x0f; + + // create branches at the 1st nibble + for branch in 1..=15 { + if added_nodes >= num_extra_nodes { + return + } + + // create branches at the 1st nibble + prefix[i] = (first_nibble.wrapping_add(branch) % 16) << 4; + trie.insert(&prefix, &[0; 32]) + .map_err(|_| "TrieMut::insert has failed") + .expect("TrieMut::insert should not fail in benchmarks"); + added_nodes += 1; + } + + // create branches at the 2nd nibble + for branch in 1..=15 { + if added_nodes >= num_extra_nodes { + return + } + + prefix[i] = (first_nibble << 4) | (second_nibble.wrapping_add(branch) % 16); + trie.insert(&prefix, &[0; 32]) + .map_err(|_| "TrieMut::insert has failed") + .expect("TrieMut::insert should not fail in benchmarks"); + added_nodes += 1; + } + } + + assert_eq!(added_nodes, num_extra_nodes) +} + +/// Record all keys for a given root. +#[cfg(feature = "test-helpers")] +pub fn record_all_keys<L: TrieConfiguration, DB>( + db: &DB, + root: &TrieHash<L>, +) -> Result<RawStorageProof, sp_std::boxed::Box<TrieError<L>>> +where + DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>, +{ + let mut recorder = Recorder::<L>::new(); + let trie = TrieDBBuilder::<L>::new(db, root).with_recorder(&mut recorder).build(); + for x in trie.iter()? { + let (key, _) = x?; + trie.get(&key)?; + } + + Ok(recorder.into_raw_storage_proof()) } /// Return valid storage proof and state root. @@ -157,7 +289,7 @@ pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { // construct storage proof let backend = <InMemoryBackend<sp_core::Blake2Hasher>>::from(( - vec![ + sp_std::vec![ (None, vec![(b"key1".to_vec(), Some(b"value1".to_vec()))]), (None, vec![(b"key2".to_vec(), Some(b"value2".to_vec()))]), (None, vec![(b"key3".to_vec(), Some(b"value3".to_vec()))]), @@ -167,33 +299,15 @@ pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { ], state_version, )); - let root = backend.storage_root(std::iter::empty(), state_version).0; + let root = backend.storage_root(sp_std::iter::empty(), state_version).0; let proof = prove_read(backend, &[&b"key1"[..], &b"key2"[..], &b"key4"[..], &b"key22"[..]]).unwrap(); (root, proof.into_nodes().into_iter().collect()) } -/// Record all keys for a given root. -pub fn record_all_keys<L: TrieConfiguration, DB>( - db: &DB, - root: &TrieHash<L>, -) -> Result<RawStorageProof, Box<TrieError<L>>> -where - DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>, -{ - let mut recorder = Recorder::<L>::new(); - let trie = TrieDBBuilder::<L>::new(db, root).with_recorder(&mut recorder).build(); - for x in trie.iter()? { - let (key, _) = x?; - trie.get(&key)?; - } - - Ok(recorder.into_raw_storage_proof()) -} - #[cfg(test)] -pub mod tests { +pub mod tests_for_storage_proof_checker { use super::*; use codec::Encode; @@ -207,18 +321,21 @@ pub mod tests { assert_eq!(checker.read_value(b"key1"), Ok(Some(b"value1".to_vec()))); assert_eq!(checker.read_value(b"key2"), Ok(Some(b"value2".to_vec()))); assert_eq!(checker.read_value(b"key4"), Ok(Some((42u64, 42u32, 42u16, 42u8).encode()))); - assert_eq!(checker.read_value(b"key11111"), Err(Error::StorageValueUnavailable)); + assert_eq!( + checker.read_value(b"key11111"), + Err(StorageProofError::StorageValueUnavailable) + ); assert_eq!(checker.read_value(b"key22"), Ok(None)); assert_eq!(checker.read_and_decode_value(b"key4"), Ok(Some((42u64, 42u32, 42u16, 42u8))),); assert!(matches!( checker.read_and_decode_value::<[u8; 64]>(b"key4"), - Err(Error::StorageValueDecodeFailed(_)), + Err(StorageProofError::DecodeError), )); // checking proof against invalid commitment fails assert_eq!( <StorageProofChecker<sp_core::Blake2Hasher>>::new(sp_core::H256::random(), proof).err(), - Some(Error::StorageRootMismatch) + Some(StorageProofError::StorageRootMismatch) ); } @@ -235,9 +352,6 @@ pub mod tests { assert_eq!(checker.ensure_no_unused_nodes(), Ok(())); let checker = StorageProofChecker::<sp_core::Blake2Hasher>::new(root, proof).unwrap(); - assert_eq!( - checker.ensure_no_unused_nodes(), - Err(Error::AccessedNodesTracker(AccessedNodesTrackerError::UnusedNodes.into())) - ); + assert_eq!(checker.ensure_no_unused_nodes(), Err(StorageProofError::UnusedKey)); } } diff --git a/bridges/primitives/test-utils/Cargo.toml b/bridges/primitives/test-utils/Cargo.toml index 0b7fb3fec077df6187ded588011cf99a64c588f0..5e6e3893393534aa828f323d8a28748742a7b5bb 100644 --- a/bridges/primitives/test-utils/Cargo.toml +++ b/bridges/primitives/test-utils/Cargo.toml @@ -14,7 +14,7 @@ workspace = true bp-header-chain = { workspace = true } bp-parachains = { workspace = true } bp-polkadot-core = { workspace = true } -bp-runtime = { workspace = true } +bp-runtime = { features = ["test-helpers"], workspace = true } codec = { workspace = true } ed25519-dalek = { workspace = true } finality-grandpa = { workspace = true } diff --git a/bridges/primitives/test-utils/src/lib.rs b/bridges/primitives/test-utils/src/lib.rs index f4fe4a242e79c0e1c8a499c4dd18ed4a2164c656..9855c32a468954dd0f3011c029c793e5cd2cbc35 100644 --- a/bridges/primitives/test-utils/src/lib.rs +++ b/bridges/primitives/test-utils/src/lib.rs @@ -177,6 +177,7 @@ pub fn prepare_parachain_heads_proof<H: HeaderT>( let mut parachains = Vec::with_capacity(heads.len()); let mut root = Default::default(); let mut mdb = MemoryDB::default(); + let mut storage_keys = vec![]; { let mut trie = TrieDBMutBuilderV1::<H::Hashing>::new(&mut mdb, &mut root).build(); for (parachain, head) in heads { @@ -185,11 +186,12 @@ pub fn prepare_parachain_heads_proof<H: HeaderT>( trie.insert(&storage_key.0, &head.encode()) .map_err(|_| "TrieMut::insert has failed") .expect("TrieMut::insert should not fail in tests"); + storage_keys.push(storage_key.0); parachains.push((ParaId(parachain), head.hash())); } } - // generate storage proof to be delivered to This chain + // generate storage proof to be delivered to this chain let storage_proof = record_all_trie_keys::<LayoutV1<H::Hashing>, _>(&mdb, &root) .map_err(|_| "record_all_trie_keys has failed") .expect("record_all_trie_keys should not fail in benchmarks"); diff --git a/bridges/relays/client-substrate/Cargo.toml b/bridges/relays/client-substrate/Cargo.toml index 66501d03691a949431c15060a398f1fd1c3cfa5f..969cd73d6194fcf42e03f54ae14029cfdf73d877 100644 --- a/bridges/relays/client-substrate/Cargo.toml +++ b/bridges/relays/client-substrate/Cargo.toml @@ -31,15 +31,12 @@ bp-header-chain = { workspace = true, default-features = true } bp-messages = { workspace = true, default-features = true } bp-polkadot-core = { workspace = true, default-features = true } bp-runtime = { workspace = true, default-features = true } -pallet-bridge-messages = { workspace = true, default-features = true } finality-relay = { workspace = true } relay-utils = { workspace = true } # Substrate Dependencies frame-support = { workspace = true, default-features = true } -frame-system = { workspace = true, default-features = true } -pallet-balances = { workspace = true, default-features = true } pallet-transaction-payment = { workspace = true, default-features = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true, default-features = true } pallet-utility = { workspace = true, default-features = true } diff --git a/bridges/relays/client-substrate/src/client/caching.rs b/bridges/relays/client-substrate/src/client/caching.rs index cb898cf517267a173b0ef4daf374c5b16b0757ba..a574e5985bc8280e030cfad08308a2c9bebe33a4 100644 --- a/bridges/relays/client-substrate/src/client/caching.rs +++ b/bridges/relays/client-substrate/src/client/caching.rs @@ -462,7 +462,11 @@ impl<C: Chain, B: Client<C>> Client<C> for CachingClient<C, B> { .await } - async fn prove_storage(&self, at: HashOf<C>, keys: Vec<StorageKey>) -> Result<StorageProof> { + async fn prove_storage( + &self, + at: HashOf<C>, + keys: Vec<StorageKey>, + ) -> Result<(StorageProof, HashOf<C>)> { self.backend.prove_storage(at, keys).await } } diff --git a/bridges/relays/client-substrate/src/client/rpc.rs b/bridges/relays/client-substrate/src/client/rpc.rs index bf7442a95141ff168229bffbc149f686d6b2771a..9c7f769462e5693bc944ed6a6525439f00311ee7 100644 --- a/bridges/relays/client-substrate/src/client/rpc.rs +++ b/bridges/relays/client-substrate/src/client/rpc.rs @@ -52,7 +52,10 @@ use sp_core::{ storage::{StorageData, StorageKey}, Bytes, Hasher, Pair, }; -use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity}; +use sp_runtime::{ + traits::Header, + transaction_validity::{TransactionSource, TransactionValidity}, +}; use sp_trie::StorageProof; use sp_version::RuntimeVersion; use std::{cmp::Ordering, future::Future, marker::PhantomData}; @@ -635,16 +638,25 @@ impl<C: Chain> Client<C> for RpcClient<C> { .map_err(|e| Error::failed_state_call::<C>(at, method_clone, arguments_clone, e)) } - async fn prove_storage(&self, at: HashOf<C>, keys: Vec<StorageKey>) -> Result<StorageProof> { + async fn prove_storage( + &self, + at: HashOf<C>, + keys: Vec<StorageKey>, + ) -> Result<(StorageProof, HashOf<C>)> { + let state_root = *self.header_by_hash(at).await?.state_root(); + let keys_clone = keys.clone(); - self.jsonrpsee_execute(move |client| async move { - SubstrateStateClient::<C>::prove_storage(&*client, keys, Some(at)) - .await - .map(|proof| StorageProof::new(proof.proof.into_iter().map(|b| b.0))) - .map_err(Into::into) - }) - .await - .map_err(|e| Error::failed_to_prove_storage::<C>(at, keys_clone, e)) + let read_proof = self + .jsonrpsee_execute(move |client| async move { + SubstrateStateClient::<C>::prove_storage(&*client, keys_clone, Some(at)) + .await + .map(|proof| StorageProof::new(proof.proof.into_iter().map(|b| b.0))) + .map_err(Into::into) + }) + .await + .map_err(|e| Error::failed_to_prove_storage::<C>(at, keys.clone(), e))?; + + Ok((read_proof, state_root)) } } diff --git a/bridges/relays/client-substrate/src/client/traits.rs b/bridges/relays/client-substrate/src/client/traits.rs index 49f5c001c3f7d80fd51892c8de73f41960557cba..6f4ef5aa951062ddd6586e0dadeb4ce7425eca5e 100644 --- a/bridges/relays/client-substrate/src/client/traits.rs +++ b/bridges/relays/client-substrate/src/client/traits.rs @@ -225,6 +225,10 @@ pub trait Client<C: Chain>: 'static + Send + Sync + Clone + Debug { }) } - /// Returns storage proof of given storage keys. - async fn prove_storage(&self, at: HashOf<C>, keys: Vec<StorageKey>) -> Result<StorageProof>; + /// Returns storage proof of given storage keys and state root. + async fn prove_storage( + &self, + at: HashOf<C>, + keys: Vec<StorageKey>, + ) -> Result<(StorageProof, HashOf<C>)>; } diff --git a/bridges/relays/client-substrate/src/error.rs b/bridges/relays/client-substrate/src/error.rs index b09e2c7abdc666735d7481d3f39c9492d851f76a..ee3c73f806e65362a10185d5dd9090f5bbc4c300 100644 --- a/bridges/relays/client-substrate/src/error.rs +++ b/bridges/relays/client-substrate/src/error.rs @@ -213,9 +213,6 @@ pub enum Error { /// The bridge pallet is not yet initialized and all transactions will be rejected. #[error("Bridge pallet is not initialized.")] BridgePalletIsNotInitialized, - /// An error has happened when we have tried to parse storage proof. - #[error("Error when parsing storage proof: {0:?}.")] - StorageProofError(bp_runtime::StorageProofError), /// The Substrate transaction is invalid. #[error("Substrate transaction is invalid: {0:?}")] TransactionInvalid(#[from] TransactionValidityError), diff --git a/bridges/relays/client-substrate/src/test_chain.rs b/bridges/relays/client-substrate/src/test_chain.rs index cfd241c022a269da799e8e03c4398566d98a14a0..991202e9874c790e404b42b74102248cb5f6723f 100644 --- a/bridges/relays/client-substrate/src/test_chain.rs +++ b/bridges/relays/client-substrate/src/test_chain.rs @@ -24,7 +24,7 @@ use crate::{Chain, ChainWithBalances, ChainWithMessages}; use bp_messages::{ChainWithMessages as ChainWithMessagesBase, MessageNonce}; use bp_runtime::ChainId; -use frame_support::weights::Weight; +use frame_support::{sp_runtime::StateVersion, weights::Weight}; use std::time::Duration; /// Chain that may be used in tests. @@ -44,6 +44,8 @@ impl bp_runtime::Chain for TestChain { type Nonce = u32; type Signature = sp_runtime::testing::TestSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { 100000 } @@ -100,6 +102,8 @@ impl bp_runtime::Chain for TestParachainBase { type Nonce = u32; type Signature = sp_runtime::testing::TestSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { unreachable!() } diff --git a/bridges/relays/finality/src/base.rs b/bridges/relays/finality/src/base.rs index 4253468eaace1ef2a2adc47790f7e16c38160200..8704bff95494a88274f0e78f5df53aa15708cccf 100644 --- a/bridges/relays/finality/src/base.rs +++ b/bridges/relays/finality/src/base.rs @@ -45,7 +45,3 @@ pub trait SourceClientBase<P: FinalityPipeline>: RelayClient { /// Subscribe to new finality proofs. async fn finality_proofs(&self) -> Result<Self::FinalityProofsStream, Self::Error>; } - -/// Target client used in finality related loops. -#[async_trait] -pub trait TargetClientBase<P: FinalityPipeline>: RelayClient {} diff --git a/bridges/relays/lib-substrate-relay/Cargo.toml b/bridges/relays/lib-substrate-relay/Cargo.toml index 28fee5b167ffab3249a5feb96ff04c991e2fc311..b0f93e5b5485f24b230b9b2868c6301b6ed64181 100644 --- a/bridges/relays/lib-substrate-relay/Cargo.toml +++ b/bridges/relays/lib-substrate-relay/Cargo.toml @@ -25,15 +25,12 @@ strum = { features = ["derive"], workspace = true, default-features = true } thiserror = { workspace = true } # Bridge dependencies - bp-header-chain = { workspace = true, default-features = true } bp-parachains = { workspace = true, default-features = true } bp-polkadot-core = { workspace = true, default-features = true } bp-relayers = { workspace = true, default-features = true } -bridge-runtime-common = { workspace = true, default-features = true } equivocation-detector = { workspace = true } -finality-grandpa = { workspace = true, default-features = true } finality-relay = { workspace = true } parachains-relay = { workspace = true } relay-utils = { workspace = true } @@ -48,7 +45,6 @@ bp-runtime = { workspace = true, default-features = true } bp-messages = { workspace = true, default-features = true } # Substrate Dependencies - frame-support = { workspace = true, default-features = true } frame-system = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } @@ -56,7 +52,9 @@ pallet-grandpa = { workspace = true, default-features = true } sp-core = { workspace = true, default-features = true } sp-consensus-grandpa = { workspace = true, default-features = true } sp-runtime = { workspace = true, default-features = true } +sp-trie = { workspace = true } [dev-dependencies] +scale-info = { features = ["derive"], workspace = true } pallet-transaction-payment = { workspace = true, default-features = true } relay-substrate-client = { features = ["test-helpers"], workspace = true } diff --git a/bridges/relays/lib-substrate-relay/src/cli/bridge.rs b/bridges/relays/lib-substrate-relay/src/cli/bridge.rs index 316f59a2b0c86e1bc78c1446bb69a90b0b0bf0f7..5631285b3c544de0e3caf85a6b74b7ee31601c56 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/bridge.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/bridge.rs @@ -19,7 +19,7 @@ use crate::{ equivocation::SubstrateEquivocationDetectionPipeline, finality::SubstrateFinalitySyncPipeline, - messages_lane::{MessagesRelayLimits, SubstrateMessageLane}, + messages::{MessagesRelayLimits, SubstrateMessageLane}, parachains::SubstrateParachainsPipeline, }; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; diff --git a/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs b/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs index 05a061c2ea606b79464908a6af46ed75af7d80ee..338dda3c63309acbefd2616d052ae5dc4bf1d1e0 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs @@ -38,7 +38,7 @@ use futures::{FutureExt, TryFutureExt}; use crate::{ cli::{bridge::MessagesCliBridge, DefaultClient, HexLaneId, PrometheusParams}, - messages_lane::{MessagesRelayLimits, MessagesRelayParams}, + messages::{MessagesRelayLimits, MessagesRelayParams}, on_demand::OnDemandRelay, HeadersToRelay, TaggedAccount, TransactionParams, }; @@ -298,14 +298,14 @@ where .collect::<Vec<_>>(); { let common = self.mut_base().mut_common(); - crate::messages_metrics::add_relay_balances_metrics::<_, Self::Right>( + crate::messages::metrics::add_relay_balances_metrics::<_, Self::Right>( common.left.client.clone(), &common.metrics_params, &common.left.accounts, &lanes, ) .await?; - crate::messages_metrics::add_relay_balances_metrics::<_, Self::Left>( + crate::messages::metrics::add_relay_balances_metrics::<_, Self::Left>( common.right.client.clone(), &common.metrics_params, &common.right.accounts, @@ -318,7 +318,7 @@ where let mut message_relays = Vec::with_capacity(lanes.len() * 2); for lane in lanes { let left_to_right_messages = - crate::messages_lane::run::<<Self::L2R as MessagesCliBridge>::MessagesLane, _, _>( + crate::messages::run::<<Self::L2R as MessagesCliBridge>::MessagesLane, _, _>( self.left_to_right().messages_relay_params( left_to_right_on_demand_headers.clone(), right_to_left_on_demand_headers.clone(), @@ -331,7 +331,7 @@ where message_relays.push(left_to_right_messages); let right_to_left_messages = - crate::messages_lane::run::<<Self::R2L as MessagesCliBridge>::MessagesLane, _, _>( + crate::messages::run::<<Self::R2L as MessagesCliBridge>::MessagesLane, _, _>( self.right_to_left().messages_relay_params( right_to_left_on_demand_headers.clone(), left_to_right_on_demand_headers.clone(), diff --git a/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs b/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs index a17ae7c0c01f9b828d8a534da8143a1d983892c2..68bbe71ae599c901bdf7a9b6e55cf93c020adbb6 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs @@ -18,7 +18,7 @@ use crate::{ cli::{bridge::*, chain_schema::*, HexLaneId, PrometheusParams}, - messages_lane::MessagesRelayParams, + messages::MessagesRelayParams, TransactionParams, }; @@ -117,7 +117,7 @@ where let target_sign = data.target_sign.to_keypair::<Self::Target>()?; let target_transactions_mortality = data.target_sign.transactions_mortality()?; - crate::messages_lane::run::<Self::MessagesLane, _, _>(MessagesRelayParams { + crate::messages::run::<Self::MessagesLane, _, _>(MessagesRelayParams { source_client, source_transaction_params: TransactionParams { signer: source_sign, @@ -161,7 +161,7 @@ where })? .id(); - crate::messages_lane::relay_messages_range::<Self::MessagesLane>( + crate::messages::relay_messages_range::<Self::MessagesLane>( source_client, target_client, TransactionParams { signer: source_sign, mortality: source_transactions_mortality }, @@ -197,7 +197,7 @@ where })? .id(); - crate::messages_lane::relay_messages_delivery_confirmation::<Self::MessagesLane>( + crate::messages::relay_messages_delivery_confirmation::<Self::MessagesLane>( source_client, target_client, TransactionParams { signer: source_sign, mortality: source_transactions_mortality }, diff --git a/bridges/relays/lib-substrate-relay/src/lib.rs b/bridges/relays/lib-substrate-relay/src/lib.rs index b3e8e7ed9a2059bb07134640aa4e0bc98494a6a1..c004540a9f4951f3aeeb43a91c74da68a3ff1064 100644 --- a/bridges/relays/lib-substrate-relay/src/lib.rs +++ b/bridges/relays/lib-substrate-relay/src/lib.rs @@ -30,10 +30,7 @@ pub mod equivocation; pub mod error; pub mod finality; pub mod finality_base; -pub mod messages_lane; -pub mod messages_metrics; -pub mod messages_source; -pub mod messages_target; +pub mod messages; pub mod on_demand; pub mod parachains; @@ -130,3 +127,17 @@ impl<Call> BatchCallBuilder<Call> for () { unreachable!("never called, because ()::new_builder() returns None; qed") } } + +/// Module for handling storage proofs compatibility. +pub mod proofs { + use bp_runtime::{HashOf, RawStorageProof}; + use relay_substrate_client::Chain; + use sp_trie::StorageProof; + + /// Converts proof to `RawStorageProof` type. + pub fn to_raw_storage_proof<SourceChain: Chain>( + proof: (StorageProof, HashOf<SourceChain>), + ) -> RawStorageProof { + proof.0.into_iter_nodes().collect() + } +} diff --git a/bridges/relays/lib-substrate-relay/src/messages_metrics.rs b/bridges/relays/lib-substrate-relay/src/messages/metrics.rs similarity index 100% rename from bridges/relays/lib-substrate-relay/src/messages_metrics.rs rename to bridges/relays/lib-substrate-relay/src/messages/metrics.rs diff --git a/bridges/relays/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs similarity index 63% rename from bridges/relays/lib-substrate-relay/src/messages_lane.rs rename to bridges/relays/lib-substrate-relay/src/messages/mod.rs index e3786dcdc5e31dad2cdf00ba2db073adb87f78b2..e52b7020666941c9a8d9937655496acf451c5379 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -17,20 +17,21 @@ //! Tools for supporting message lanes between two Substrate-based chains. use crate::{ - messages_source::{SubstrateMessagesProof, SubstrateMessagesSource}, - messages_target::{SubstrateMessagesDeliveryProof, SubstrateMessagesTarget}, + messages::{ + source::{SubstrateMessagesProof, SubstrateMessagesSource}, + target::{SubstrateMessagesDeliveryProof, SubstrateMessagesTarget}, + }, on_demand::OnDemandRelay, BatchCallBuilder, BatchCallBuilderConstructor, TransactionParams, }; use async_std::sync::Arc; -use bp_messages::{ChainWithMessages as _, LaneId, MessageNonce}; +use bp_messages::{ + target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, LaneId, MessageNonce, +}; use bp_runtime::{ AccountIdOf, Chain as _, EncodedOrDecodedCall, HeaderIdOf, TransactionEra, WeightExtraOps, }; -use bridge_runtime_common::messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, -}; use codec::Encode; use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction}; @@ -48,6 +49,10 @@ use sp_core::Pair; use sp_runtime::traits::Zero; use std::{fmt::Debug, marker::PhantomData, ops::RangeInclusive}; +pub mod metrics; +pub mod source; +pub mod target; + /// Substrate -> Substrate messages synchronization pipeline. pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync { /// Messages of this chain are relayed to the `TargetChain`. @@ -383,11 +388,10 @@ pub struct DirectReceiveMessagesProofCallBuilder<P, R, I> { impl<P, R, I> ReceiveMessagesProofCallBuilder<P> for DirectReceiveMessagesProofCallBuilder<P, R, I> where P: SubstrateMessageLane, - R: BridgeMessagesConfig<I, InboundRelayer = AccountIdOf<P::SourceChain>>, + R: BridgeMessagesConfig<I>, I: 'static, - R::SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof<HashOf<P::SourceChain>>, - >, + R::BridgedChain: + bp_runtime::Chain<AccountId = AccountIdOf<P::SourceChain>, Hash = HashOf<P::SourceChain>>, CallOf<P::TargetChain>: From<BridgeMessagesCall<R, I>> + GetDispatchInfo, { fn build_receive_messages_proof_call( @@ -399,7 +403,7 @@ where ) -> CallOf<P::TargetChain> { let call: CallOf<P::TargetChain> = BridgeMessagesCall::<R, I>::receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_source, - proof: proof.1, + proof: proof.1.into(), messages_count, dispatch_weight, } @@ -432,26 +436,26 @@ macro_rules! generate_receive_message_proof_call_builder { ($pipeline:ident, $mocked_builder:ident, $bridge_messages:path, $receive_messages_proof:path) => { pub struct $mocked_builder; - impl $crate::messages_lane::ReceiveMessagesProofCallBuilder<$pipeline> + impl $crate::messages::ReceiveMessagesProofCallBuilder<$pipeline> for $mocked_builder { fn build_receive_messages_proof_call( relayer_id_at_source: relay_substrate_client::AccountIdOf< - <$pipeline as $crate::messages_lane::SubstrateMessageLane>::SourceChain + <$pipeline as $crate::messages::SubstrateMessageLane>::SourceChain >, - proof: $crate::messages_source::SubstrateMessagesProof< - <$pipeline as $crate::messages_lane::SubstrateMessageLane>::SourceChain + proof: $crate::messages::source::SubstrateMessagesProof< + <$pipeline as $crate::messages::SubstrateMessageLane>::SourceChain >, messages_count: u32, dispatch_weight: bp_messages::Weight, _trace_call: bool, ) -> relay_substrate_client::CallOf< - <$pipeline as $crate::messages_lane::SubstrateMessageLane>::TargetChain + <$pipeline as $crate::messages::SubstrateMessageLane>::TargetChain > { bp_runtime::paste::item! { $bridge_messages($receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_source, - proof: proof.1, + proof: proof.1.into(), messages_count: messages_count, dispatch_weight: dispatch_weight, }) @@ -483,11 +487,7 @@ where P: SubstrateMessageLane, R: BridgeMessagesConfig<I>, I: 'static, - R::TargetHeaderChain: bp_messages::source_chain::TargetHeaderChain< - R::OutboundPayload, - R::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<HashOf<P::TargetChain>>, - >, + R::BridgedChain: bp_runtime::Chain<Hash = HashOf<P::TargetChain>>, CallOf<P::SourceChain>: From<BridgeMessagesCall<R, I>> + GetDispatchInfo, { fn build_receive_messages_delivery_proof_call( @@ -496,7 +496,7 @@ where ) -> CallOf<P::SourceChain> { let call: CallOf<P::SourceChain> = BridgeMessagesCall::<R, I>::receive_messages_delivery_proof { - proof: proof.1, + proof: proof.1.into(), relayers_state: proof.0, } .into(); @@ -528,16 +528,16 @@ macro_rules! generate_receive_message_delivery_proof_call_builder { ($pipeline:ident, $mocked_builder:ident, $bridge_messages:path, $receive_messages_delivery_proof:path) => { pub struct $mocked_builder; - impl $crate::messages_lane::ReceiveMessagesDeliveryProofCallBuilder<$pipeline> + impl $crate::messages::ReceiveMessagesDeliveryProofCallBuilder<$pipeline> for $mocked_builder { fn build_receive_messages_delivery_proof_call( - proof: $crate::messages_target::SubstrateMessagesDeliveryProof< - <$pipeline as $crate::messages_lane::SubstrateMessageLane>::TargetChain + proof: $crate::messages::target::SubstrateMessagesDeliveryProof< + <$pipeline as $crate::messages::SubstrateMessageLane>::TargetChain >, _trace_call: bool, ) -> relay_substrate_client::CallOf< - <$pipeline as $crate::messages_lane::SubstrateMessageLane>::SourceChain + <$pipeline as $crate::messages::SubstrateMessageLane>::SourceChain > { bp_runtime::paste::item! { $bridge_messages($receive_messages_delivery_proof { @@ -643,13 +643,7 @@ where Weight::zero(), FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - // we may use per-chain `EXTRA_STORAGE_PROOF_SIZE`, but since we don't need - // exact values, this global estimation is fine - storage_proof: vec![vec![ - 42u8; - pallet_bridge_messages::EXTRA_STORAGE_PROOF_SIZE - as usize - ]], + storage_proof: Default::default(), lane: Default::default(), nonces_start: 1, nonces_end: messages as u64, @@ -675,3 +669,362 @@ where ) .map_err(Into::into) } + +#[cfg(test)] +mod tests { + use super::*; + use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, UnrewardedRelayersState, + }; + use relay_substrate_client::calls::{UtilityCall as MockUtilityCall, UtilityCall}; + + #[derive(codec::Decode, codec::Encode, Clone, Debug, PartialEq)] + pub enum RuntimeCall { + #[codec(index = 53)] + BridgeMessages(CodegenBridgeMessagesCall), + #[codec(index = 123)] + Utility(UtilityCall<RuntimeCall>), + } + pub type CodegenBridgeMessagesCall = bp_messages::BridgeMessagesCall< + u64, + Box<FromBridgedChainMessagesProof<mock::BridgedHeaderHash>>, + FromBridgedChainMessagesDeliveryProof<mock::BridgedHeaderHash>, + >; + + impl From<MockUtilityCall<RuntimeCall>> for RuntimeCall { + fn from(value: MockUtilityCall<RuntimeCall>) -> RuntimeCall { + match value { + MockUtilityCall::batch_all(calls) => + RuntimeCall::Utility(UtilityCall::<RuntimeCall>::batch_all(calls)), + } + } + } + + #[test] + fn ensure_macro_compatibility_for_generate_receive_message_proof_call_builder() { + // data + let receive_messages_proof = FromBridgedChainMessagesProof { + bridged_header_hash: Default::default(), + storage_proof: Default::default(), + lane: LaneId([0, 0, 0, 0]), + nonces_start: 0, + nonces_end: 0, + }; + let account = 1234; + let messages_count = 0; + let dispatch_weight = Default::default(); + + // construct pallet Call directly + let pallet_receive_messages_proof = + pallet_bridge_messages::Call::<mock::TestRuntime>::receive_messages_proof { + relayer_id_at_bridged_chain: account, + proof: receive_messages_proof.clone().into(), + messages_count, + dispatch_weight, + }; + + // construct mock enum Call + let mock_enum_receive_messages_proof = CodegenBridgeMessagesCall::receive_messages_proof { + relayer_id_at_bridged_chain: account, + proof: receive_messages_proof.clone().into(), + messages_count, + dispatch_weight, + }; + + // now we should be able to use macro `generate_receive_message_proof_call_builder` + let relayer_call_builder_receive_messages_proof = relayer::ThisChainToBridgedChainMessageLaneReceiveMessagesProofCallBuilder::build_receive_messages_proof_call( + account, + (Default::default(), receive_messages_proof), + messages_count, + dispatch_weight, + false, + ); + + // ensure they are all equal + assert_eq!( + pallet_receive_messages_proof.encode(), + mock_enum_receive_messages_proof.encode() + ); + match relayer_call_builder_receive_messages_proof { + RuntimeCall::BridgeMessages(call) => match call { + call @ CodegenBridgeMessagesCall::receive_messages_proof { .. } => + assert_eq!(pallet_receive_messages_proof.encode(), call.encode()), + _ => panic!("Unexpected CodegenBridgeMessagesCall type"), + }, + _ => panic!("Unexpected RuntimeCall type"), + }; + } + + #[test] + fn ensure_macro_compatibility_for_generate_receive_message_delivery_proof_call_builder() { + // data + let receive_messages_delivery_proof = FromBridgedChainMessagesDeliveryProof { + bridged_header_hash: Default::default(), + storage_proof: Default::default(), + lane: LaneId([0, 0, 0, 0]), + }; + let relayers_state = UnrewardedRelayersState { + unrewarded_relayer_entries: 0, + messages_in_oldest_entry: 0, + total_messages: 0, + last_delivered_nonce: 0, + }; + + // construct pallet Call directly + let pallet_receive_messages_delivery_proof = + pallet_bridge_messages::Call::<mock::TestRuntime>::receive_messages_delivery_proof { + proof: receive_messages_delivery_proof.clone(), + relayers_state: relayers_state.clone(), + }; + + // construct mock enum Call + let mock_enum_receive_messages_delivery_proof = + CodegenBridgeMessagesCall::receive_messages_delivery_proof { + proof: receive_messages_delivery_proof.clone(), + relayers_state: relayers_state.clone(), + }; + + // now we should be able to use macro `generate_receive_message_proof_call_builder` + let relayer_call_builder_receive_messages_delivery_proof = relayer::ThisChainToBridgedChainMessageLaneReceiveMessagesDeliveryProofCallBuilder::build_receive_messages_delivery_proof_call( + (relayers_state, receive_messages_delivery_proof), + false, + ); + + // ensure they are all equal + assert_eq!( + pallet_receive_messages_delivery_proof.encode(), + mock_enum_receive_messages_delivery_proof.encode() + ); + match relayer_call_builder_receive_messages_delivery_proof { + RuntimeCall::BridgeMessages(call) => match call { + call @ CodegenBridgeMessagesCall::receive_messages_delivery_proof { .. } => + assert_eq!(pallet_receive_messages_delivery_proof.encode(), call.encode()), + _ => panic!("Unexpected CodegenBridgeMessagesCall type"), + }, + _ => panic!("Unexpected RuntimeCall type"), + }; + } + + // mock runtime with `pallet_bridge_messages` + mod mock { + use super::super::*; + use bp_messages::target_chain::ForbidInboundMessages; + use bp_runtime::ChainId; + use frame_support::derive_impl; + use sp_core::H256; + use sp_runtime::{ + generic, testing::Header as SubstrateHeader, traits::BlakeTwo256, StateVersion, + }; + + type Block = frame_system::mocking::MockBlock<TestRuntime>; + pub type SignedBlock = generic::SignedBlock<Block>; + + frame_support::construct_runtime! { + pub enum TestRuntime + { + System: frame_system, + Messages: pallet_bridge_messages, + } + } + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] + impl frame_system::Config for TestRuntime { + type Block = Block; + } + + impl pallet_bridge_messages::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type ThisChain = ThisUnderlyingChain; + type BridgedChain = BridgedUnderlyingChain; + type BridgedHeaderChain = BridgedHeaderChain; + type ActiveOutboundLanes = (); + type OutboundPayload = Vec<u8>; + type InboundPayload = Vec<u8>; + type DeliveryPayments = (); + type DeliveryConfirmationPayments = (); + type OnMessagesDelivered = (); + type MessageDispatch = ForbidInboundMessages<Vec<u8>>; + } + + pub struct ThisUnderlyingChain; + + impl bp_runtime::Chain for ThisUnderlyingChain { + const ID: ChainId = *b"tuch"; + type BlockNumber = u64; + type Hash = H256; + type Hasher = BlakeTwo256; + type Header = SubstrateHeader; + type AccountId = u64; + type Balance = u64; + type Nonce = u64; + type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { + u32::MAX + } + fn max_extrinsic_weight() -> Weight { + Weight::MAX + } + } + + impl bp_messages::ChainWithMessages for ThisUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; + } + + pub struct BridgedUnderlyingChain; + + pub type BridgedHeaderHash = H256; + pub type BridgedChainHeader = SubstrateHeader; + + impl bp_runtime::Chain for BridgedUnderlyingChain { + const ID: ChainId = *b"bgdc"; + type BlockNumber = u64; + type Hash = BridgedHeaderHash; + type Hasher = BlakeTwo256; + type Header = BridgedChainHeader; + type AccountId = u64; + type Balance = u64; + type Nonce = u64; + type Signature = sp_runtime::MultiSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { + 4096 + } + fn max_extrinsic_weight() -> Weight { + Weight::MAX + } + } + + impl bp_messages::ChainWithMessages for BridgedUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; + } + + pub struct BridgedHeaderChain; + + impl bp_header_chain::HeaderChain<BridgedUnderlyingChain> for BridgedHeaderChain { + fn finalized_header_state_root( + _hash: HashOf<BridgedUnderlyingChain>, + ) -> Option<HashOf<BridgedUnderlyingChain>> { + unreachable!() + } + } + } + + // relayer configuration + mod relayer { + use super::*; + use crate::{ + messages::{ + tests::{mock, RuntimeCall}, + SubstrateMessageLane, + }, + UtilityPalletBatchCallBuilder, + }; + use bp_runtime::UnderlyingChainProvider; + use relay_substrate_client::{MockedRuntimeUtilityPallet, SignParam, UnsignedTransaction}; + use std::time::Duration; + + #[derive(Clone)] + pub struct ThisChain; + impl UnderlyingChainProvider for ThisChain { + type Chain = mock::ThisUnderlyingChain; + } + impl relay_substrate_client::Chain for ThisChain { + const NAME: &'static str = ""; + const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = ""; + const FREE_HEADERS_INTERVAL_METHOD: &'static str = ""; + const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_millis(0); + type SignedBlock = mock::SignedBlock; + type Call = RuntimeCall; + } + impl relay_substrate_client::ChainWithTransactions for ThisChain { + type AccountKeyPair = sp_core::sr25519::Pair; + type SignedTransaction = (); + + fn sign_transaction( + _: SignParam<Self>, + _: UnsignedTransaction<Self>, + ) -> Result<Self::SignedTransaction, SubstrateError> + where + Self: Sized, + { + todo!() + } + } + impl relay_substrate_client::ChainWithMessages for ThisChain { + const WITH_CHAIN_RELAYERS_PALLET_NAME: Option<&'static str> = None; + const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = ""; + const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = ""; + } + impl relay_substrate_client::ChainWithUtilityPallet for ThisChain { + type UtilityPallet = MockedRuntimeUtilityPallet<RuntimeCall>; + } + + #[derive(Clone)] + pub struct BridgedChain; + impl UnderlyingChainProvider for BridgedChain { + type Chain = mock::BridgedUnderlyingChain; + } + impl relay_substrate_client::Chain for BridgedChain { + const NAME: &'static str = ""; + const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = ""; + const FREE_HEADERS_INTERVAL_METHOD: &'static str = ""; + const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_millis(0); + type SignedBlock = mock::SignedBlock; + type Call = RuntimeCall; + } + impl relay_substrate_client::ChainWithTransactions for BridgedChain { + type AccountKeyPair = sp_core::sr25519::Pair; + type SignedTransaction = (); + + fn sign_transaction( + _: SignParam<Self>, + _: UnsignedTransaction<Self>, + ) -> Result<Self::SignedTransaction, SubstrateError> + where + Self: Sized, + { + todo!() + } + } + impl relay_substrate_client::ChainWithMessages for BridgedChain { + const WITH_CHAIN_RELAYERS_PALLET_NAME: Option<&'static str> = None; + const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = ""; + const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = ""; + } + impl relay_substrate_client::ChainWithUtilityPallet for BridgedChain { + type UtilityPallet = MockedRuntimeUtilityPallet<RuntimeCall>; + } + + #[derive(Clone, Debug)] + pub struct ThisChainToBridgedChainMessageLane; + impl SubstrateMessageLane for ThisChainToBridgedChainMessageLane { + type SourceChain = ThisChain; + type TargetChain = BridgedChain; + type ReceiveMessagesProofCallBuilder = + ThisChainToBridgedChainMessageLaneReceiveMessagesProofCallBuilder; + type ReceiveMessagesDeliveryProofCallBuilder = + ThisChainToBridgedChainMessageLaneReceiveMessagesDeliveryProofCallBuilder; + type SourceBatchCallBuilder = UtilityPalletBatchCallBuilder<ThisChain>; + type TargetBatchCallBuilder = UtilityPalletBatchCallBuilder<BridgedChain>; + } + + generate_receive_message_proof_call_builder!( + ThisChainToBridgedChainMessageLane, + ThisChainToBridgedChainMessageLaneReceiveMessagesProofCallBuilder, + RuntimeCall::BridgeMessages, + CodegenBridgeMessagesCall::receive_messages_proof + ); + generate_receive_message_delivery_proof_call_builder!( + ThisChainToBridgedChainMessageLane, + ThisChainToBridgedChainMessageLaneReceiveMessagesDeliveryProofCallBuilder, + RuntimeCall::BridgeMessages, + CodegenBridgeMessagesCall::receive_messages_delivery_proof + ); + } +} diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs similarity index 97% rename from bridges/relays/lib-substrate-relay/src/messages_source.rs rename to bridges/relays/lib-substrate-relay/src/messages/source.rs index 1f597e278da404a5c3d8d0dff0032030d96ed433..b75fc86d5eee20d247de3cbc26f324ed46e9ad2d 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -20,11 +20,12 @@ use crate::{ finality_base::best_synced_header_id, - messages_lane::{ + messages::{ BatchProofTransaction, MessageLaneAdapter, ReceiveMessagesDeliveryProofCallBuilder, SubstrateMessageLane, }, on_demand::OnDemandRelay, + proofs::to_raw_storage_proof, TransactionParams, }; @@ -32,11 +33,11 @@ use async_std::sync::Arc; use async_trait::async_trait; use bp_messages::{ storage_keys::{operating_mode_key, outbound_lane_data_key}, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, InboundMessageDetails, LaneId, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, }; -use bp_runtime::{BasicOperatingMode, HeaderIdProvider}; -use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; +use bp_runtime::{BasicOperatingMode, HeaderIdProvider, RangeInclusiveExt}; use codec::Encode; use frame_support::weights::Weight; use messages_relay::{ @@ -320,34 +321,27 @@ where ), SubstrateError, > { - let mut storage_keys = - Vec::with_capacity(nonces.end().saturating_sub(*nonces.start()) as usize + 1); - let mut message_nonce = *nonces.start(); - while message_nonce <= *nonces.end() { + let mut storage_keys = Vec::with_capacity(nonces.saturating_len() as usize); + for message_nonce in nonces.clone() { let message_key = bp_messages::storage_keys::message_key( P::TargetChain::WITH_CHAIN_MESSAGES_PALLET_NAME, &self.lane_id, message_nonce, ); storage_keys.push(message_key); - message_nonce += 1; } if proof_parameters.outbound_state_proof_required { - storage_keys.push(bp_messages::storage_keys::outbound_lane_data_key( + storage_keys.push(outbound_lane_data_key( P::TargetChain::WITH_CHAIN_MESSAGES_PALLET_NAME, &self.lane_id, )); } - let proof = self - .source_client - .prove_storage(id.1, storage_keys) - .await? - .into_iter_nodes() - .collect(); + let storage_proof = + self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesProof { bridged_header_hash: id.1, - storage_proof: proof, + storage_proof: to_raw_storage_proof::<P::SourceChain>(storage_proof), lane: self.lane_id, nonces_start: *nonces.start(), nonces_end: *nonces.end(), diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages/target.rs similarity index 94% rename from bridges/relays/lib-substrate-relay/src/messages_target.rs rename to bridges/relays/lib-substrate-relay/src/messages/target.rs index e1c7645eac6834ed8768ef6f416ce415c37653cf..a6bf169cffb67ae149d9d4c8c5a2348dc18f5b39 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/target.rs @@ -19,24 +19,25 @@ //! `<BridgedName>` chain. use crate::{ - messages_lane::{ + messages::{ + source::{ + ensure_messages_pallet_active, read_client_state_from_both_chains, + SubstrateMessagesProof, + }, BatchProofTransaction, MessageLaneAdapter, ReceiveMessagesProofCallBuilder, SubstrateMessageLane, }, - messages_source::{ - ensure_messages_pallet_active, read_client_state_from_both_chains, SubstrateMessagesProof, - }, on_demand::OnDemandRelay, + proofs::to_raw_storage_proof, TransactionParams, }; use async_std::sync::Arc; use async_trait::async_trait; use bp_messages::{ - storage_keys::inbound_lane_data_key, ChainWithMessages as _, InboundLaneData, LaneId, - MessageNonce, UnrewardedRelayersState, + source_chain::FromBridgedChainMessagesDeliveryProof, storage_keys::inbound_lane_data_key, + ChainWithMessages as _, InboundLaneData, LaneId, MessageNonce, UnrewardedRelayersState, }; -use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof; use messages_relay::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{NoncesSubmitArtifacts, TargetClient, TargetClientState}, @@ -47,7 +48,7 @@ use relay_substrate_client::{ }; use relay_utils::relay_loop::Client as RelayClient; use sp_core::Pair; -use std::ops::RangeInclusive; +use std::{convert::TryFrom, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. pub type SubstrateMessagesDeliveryProof<C> = @@ -231,19 +232,16 @@ where SubstrateError, > { let (id, relayers_state) = self.unrewarded_relayers_state(id).await?; - let inbound_data_key = bp_messages::storage_keys::inbound_lane_data_key( + let storage_keys = vec![inbound_lane_data_key( P::SourceChain::WITH_CHAIN_MESSAGES_PALLET_NAME, &self.lane_id, - ); - let proof = self - .target_client - .prove_storage(id.hash(), vec![inbound_data_key]) - .await? - .into_iter_nodes() - .collect(); + )]; + + let storage_proof = + self.target_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: id.1, - storage_proof: proof, + storage_proof: to_raw_storage_proof::<P::TargetChain>(storage_proof), lane: self.lane_id, }; Ok((id, (relayers_state, proof))) diff --git a/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs b/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs index 654cb6628d5f062d5790a2d14ffa1ae6fadb7475..4579222a2c681c49e076f67d2eacaeb1dc8b9fca 100644 --- a/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs +++ b/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs @@ -17,7 +17,7 @@ //! On-demand Substrate -> Substrate parachain finality relay. use crate::{ - messages_source::best_finalized_peer_header_at_self, + messages::source::best_finalized_peer_header_at_self, on_demand::OnDemandRelay, parachains::{ source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter, @@ -681,7 +681,7 @@ impl<'a, P: SubstrateParachainsPipeline, SourceRelayClnt, TargetClnt> async fn best_finalized_relay_block_at_target( &self, ) -> Result<HeaderIdOf<P::SourceRelayChain>, SubstrateError> { - Ok(crate::messages_source::read_client_state::<P::TargetChain, P::SourceRelayChain>( + Ok(crate::messages::source::read_client_state::<P::TargetChain, P::SourceRelayChain>( &self.0.target_client, ) .await? diff --git a/bridges/relays/lib-substrate-relay/src/parachains/source.rs b/bridges/relays/lib-substrate-relay/src/parachains/source.rs index 11b9d6dbf5bd3fe12a4249ac9c2f9864291392d7..1aa12d1c913d11e13e95908db44c6302942fa94a 100644 --- a/bridges/relays/lib-substrate-relay/src/parachains/source.rs +++ b/bridges/relays/lib-substrate-relay/src/parachains/source.rs @@ -16,8 +16,10 @@ //! Parachain heads source. -use crate::parachains::{ParachainsPipelineAdapter, SubstrateParachainsPipeline}; - +use crate::{ + parachains::{ParachainsPipelineAdapter, SubstrateParachainsPipeline}, + proofs::to_raw_storage_proof, +}; use async_std::sync::{Arc, Mutex}; use async_trait::async_trait; use bp_parachains::parachain_head_storage_key_at_source; @@ -153,12 +155,9 @@ where let parachain = ParaId(P::SourceParachain::PARACHAIN_ID); let storage_key = parachain_head_storage_key_at_source(P::SourceRelayChain::PARAS_PALLET_NAME, parachain); - let parachain_heads_proof = self - .client - .prove_storage(at_block.hash(), vec![storage_key.clone()]) - .await? - .into_iter_nodes() - .collect(); + + let storage_proof = + self.client.prove_storage(at_block.hash(), vec![storage_key.clone()]).await?; // why we're reading parachain head here once again (it has already been read at the // `parachain_head`)? that's because `parachain_head` sometimes returns obsolete parachain @@ -178,6 +177,11 @@ where })?; let parachain_head_hash = parachain_head.hash(); - Ok((ParaHeadsProof { storage_proof: parachain_heads_proof }, parachain_head_hash)) + Ok(( + ParaHeadsProof { + storage_proof: to_raw_storage_proof::<P::SourceRelayChain>(storage_proof), + }, + parachain_head_hash, + )) } } diff --git a/bridges/relays/messages/Cargo.toml b/bridges/relays/messages/Cargo.toml index 96e441fc6730e808065c86d83020ea36e29a2c1b..c7a132bb3bae7ebc34728de8c94c41fb39c89751 100644 --- a/bridges/relays/messages/Cargo.toml +++ b/bridges/relays/messages/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] async-std = { features = ["attributes"], workspace = true } async-trait = { workspace = true } -env_logger = { workspace = true } futures = { workspace = true } hex = { workspace = true, default-features = true } log = { workspace = true } diff --git a/bridges/relays/parachains/src/parachains_loop.rs b/bridges/relays/parachains/src/parachains_loop.rs index fd73ca2d46c00f8e05bb05a14a7fa4104ef898c4..0fd1d72c7075bc29632280615f203e0c0028359b 100644 --- a/bridges/relays/parachains/src/parachains_loop.rs +++ b/bridges/relays/parachains/src/parachains_loop.rs @@ -680,7 +680,6 @@ impl<P: ParachainsPipeline> SubmittedHeadsTracker<P> { mod tests { use super::*; use async_std::sync::{Arc, Mutex}; - use codec::Encode; use futures::{SinkExt, StreamExt}; use relay_substrate_client::test_chain::{TestChain, TestParachain}; use relay_utils::{HeaderId, MaybeConnectionError}; @@ -821,8 +820,7 @@ mod tests { let head_result = SourceClient::<TestParachainsPipeline>::parachain_head(self, at_block).await?; let head = head_result.as_available().unwrap(); - let storage_proof = vec![head.hash().encode()]; - let proof = (ParaHeadsProof { storage_proof }, head.hash()); + let proof = (ParaHeadsProof { storage_proof: Default::default() }, head.hash()); self.data.lock().await.source_proof.clone().map(|_| proof) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 775bc3bdb80f54a8db97d1c1fdbf5a837fdb95b1..0a86037391b42d71340d8d0665a9210d8b9a0281 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-itmxxexx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -49,32 +49,32 @@ use core::marker::PhantomData; pub struct WeightInfo<T>(PhantomData<T>); impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo<T> { /// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0) - /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ToWestendXcmRouter::Bridge` (r:1 w:1) /// Proof: `ToWestendXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) fn on_initialize_when_non_congested() -> Weight { // Proof Size summary in bytes: // Measured: `154` - // Estimated: `1639` - // Minimum execution time: 7_853_000 picoseconds. - Weight::from_parts(8_443_000, 0) - .saturating_add(Weight::from_parts(0, 1639)) + // Estimated: `5487` + // Minimum execution time: 8_078_000 picoseconds. + Weight::from_parts(8_455_000, 0) + .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0) - /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) fn on_initialize_when_congested() -> Weight { // Proof Size summary in bytes: // Measured: `144` - // Estimated: `1629` - // Minimum execution time: 4_333_000 picoseconds. - Weight::from_parts(4_501_000, 0) - .saturating_add(Weight::from_parts(0, 1629)) + // Estimated: `5487` + // Minimum execution time: 4_291_000 picoseconds. + Weight::from_parts(4_548_000, 0) + .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(2)) } /// Storage: `ToWestendXcmRouter::Bridge` (r:1 w:1) @@ -83,14 +83,12 @@ impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `150` // Estimated: `1502` - // Minimum execution time: 10_167_000 picoseconds. - Weight::from_parts(10_667_000, 0) + // Minimum execution time: 9_959_000 picoseconds. + Weight::from_parts(10_372_000, 0) .saturating_add(Weight::from_parts(0, 1502)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:2 w:0) - /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x3302afcb67e838a3f960251b417b9a4f` (r:1 w:0) @@ -100,7 +98,9 @@ impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Storage: `ToWestendXcmRouter::Bridge` (r:1 w:1) /// Proof: `ToWestendXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:2 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) @@ -108,17 +108,17 @@ impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0) /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0) - /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) - /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) fn send_message() -> Weight { // Proof Size summary in bytes: // Measured: `448` // Estimated: `6388` - // Minimum execution time: 60_584_000 picoseconds. - Weight::from_parts(62_467_000, 0) + // Minimum execution time: 45_888_000 picoseconds. + Weight::from_parts(47_022_000, 0) .saturating_add(Weight::from_parts(0, 6388)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index 84d717b0283c764cac14cce63ca34f81c9f58e8c..21d15c75af553da60ecf0648186a26255bb72890 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-itmxxexx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -49,48 +49,46 @@ use core::marker::PhantomData; pub struct WeightInfo<T>(PhantomData<T>); impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo<T> { /// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0) - /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ToRococoXcmRouter::Bridge` (r:1 w:1) /// Proof: `ToRococoXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) fn on_initialize_when_non_congested() -> Weight { // Proof Size summary in bytes: - // Measured: `193` - // Estimated: `1678` - // Minimum execution time: 8_095_000 picoseconds. - Weight::from_parts(8_393_000, 0) - .saturating_add(Weight::from_parts(0, 1678)) + // Measured: `226` + // Estimated: `5487` + // Minimum execution time: 8_363_000 picoseconds. + Weight::from_parts(8_620_000, 0) + .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0) - /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) fn on_initialize_when_congested() -> Weight { // Proof Size summary in bytes: // Measured: `111` - // Estimated: `1596` - // Minimum execution time: 3_417_000 picoseconds. - Weight::from_parts(3_583_000, 0) - .saturating_add(Weight::from_parts(0, 1596)) + // Estimated: `5487` + // Minimum execution time: 3_436_000 picoseconds. + Weight::from_parts(3_586_000, 0) + .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(2)) } /// Storage: `ToRococoXcmRouter::Bridge` (r:1 w:1) /// Proof: `ToRococoXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) fn report_bridge_status() -> Weight { // Proof Size summary in bytes: - // Measured: `117` + // Measured: `150` // Estimated: `1502` - // Minimum execution time: 10_280_000 picoseconds. - Weight::from_parts(10_703_000, 0) + // Minimum execution time: 9_706_000 picoseconds. + Weight::from_parts(10_139_000, 0) .saturating_add(Weight::from_parts(0, 1502)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:2 w:0) - /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x3302afcb67e838a3f960251b417b9a4f` (r:1 w:0) @@ -100,7 +98,9 @@ impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Storage: `ToRococoXcmRouter::Bridge` (r:1 w:1) /// Proof: `ToRococoXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:2 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) @@ -108,18 +108,18 @@ impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0) /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0) - /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) - /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) fn send_message() -> Weight { // Proof Size summary in bytes: - // Measured: `487` - // Estimated: `6427` - // Minimum execution time: 63_624_000 picoseconds. - Weight::from_parts(66_071_000, 0) - .saturating_add(Weight::from_parts(0, 6427)) + // Measured: `520` + // Estimated: `6460` + // Minimum execution time: 46_250_000 picoseconds. + Weight::from_parts(47_801_000, 0) + .saturating_add(Weight::from_parts(0, 6460)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 1ac31efaf912d7a115a704d37bb3d3e76a2db854..98737298468210671a6140fb119f504bd8f7f9e4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -96,7 +96,7 @@ bp-parachains = { workspace = true } bp-polkadot-bulletin = { workspace = true } bp-polkadot-core = { workspace = true } bp-relayers = { workspace = true } -bp-runtime = { workspace = true } +bp-runtime = { features = ["test-helpers"], workspace = true } bp-rococo = { workspace = true } bp-westend = { workspace = true } pallet-bridge-grandpa = { workspace = true } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs index 5551b05e202547c99501b279e8839611efcc7f66..779cc537ee96dcc2fadc38452dfcd01c4c320789 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs @@ -21,14 +21,9 @@ //! For example, the messaging pallet needs to know the sending and receiving chains, but the //! GRANDPA tracking pallet only needs to be aware of one chain. -use super::{ - weights, AccountId, Balance, Balances, BlockNumber, Runtime, RuntimeEvent, RuntimeOrigin, -}; +use super::{weights, AccountId, Balance, Balances, BlockNumber, Runtime, RuntimeEvent}; use bp_parachains::SingleParaStoredHeaderDataBuilder; -use bp_runtime::UnderlyingChainProvider; -use bridge_runtime_common::messages::ThisChainWithMessages; use frame_support::{parameter_types, traits::ConstU32}; -use sp_runtime::RuntimeDebug; parameter_types! { pub const RelayChainHeadersToKeep: u32 = 1024; @@ -103,15 +98,3 @@ impl pallet_bridge_grandpa::Config<BridgeGrandpaRococoBulletinInstance> for Runt // weights are also the same for both bridges. type WeightInfo = weights::pallet_bridge_grandpa::WeightInfo<Runtime>; } - -/// BridgeHubRococo chain from message lane point of view. -#[derive(RuntimeDebug, Clone, Copy)] -pub struct BridgeHubRococo; - -impl UnderlyingChainProvider for BridgeHubRococo { - type Chain = bp_bridge_hub_rococo::BridgeHubRococo; -} - -impl ThisChainWithMessages for BridgeHubRococo { - type RuntimeOrigin = RuntimeOrigin; -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 94b936889b77c4460f9921956d6f7abef1ecb52c..39ea636925528a402432168fdf1a2562c339c045 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -20,23 +20,20 @@ //! are reusing Polkadot Bulletin chain primitives everywhere here. use crate::{ - bridge_common_config::BridgeHubRococo, weights, xcm_config::UniversalLocation, AccountId, - BridgeRococoBulletinGrandpa, BridgeRococoBulletinMessages, PolkadotXcm, Runtime, RuntimeEvent, - XcmOverRococoBulletin, XcmRouter, + weights, xcm_config::UniversalLocation, BridgeRococoBulletinGrandpa, + BridgeRococoBulletinMessages, PolkadotXcm, Runtime, RuntimeEvent, XcmOverRococoBulletin, + XcmRouter, +}; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, LaneId, }; -use bp_messages::LaneId; use bp_runtime::Chain; use bridge_runtime_common::{ extensions::refund_relayer_extension::{ ActualFeeRefund, RefundBridgedMessages, RefundSignedExtensionAdapter, RefundableMessagesLane, }, - messages, - messages::{ - source::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChainAdapter}, - target::{FromBridgedChainMessagesProof, SourceHeaderChainAdapter}, - MessageBridge, UnderlyingChainProvider, - }, messages_xcm_extension::{ SenderAndLane, XcmAsPlainPayload, XcmBlobHauler, XcmBlobHaulerAdapter, XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, @@ -44,7 +41,6 @@ use bridge_runtime_common::{ }; use frame_support::{parameter_types, traits::PalletInfoAccess}; -use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, prelude::{InteriorLocation, NetworkId}, @@ -52,15 +48,6 @@ use xcm::{ use xcm_builder::BridgeBlobDispatcher; parameter_types! { - /// Maximal number of entries in the unrewarded relayers vector at the Rococo Bridge Hub. It matches the - /// maximal number of unrewarded relayers that the single confirmation transaction at Rococo Bulletin Chain - /// may process. - pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = - bp_polkadot_bulletin::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; - /// Maximal number of unconfirmed messages at the Rococo Bridge Hub. It matches the maximal number of - /// unconfirmed messages that the single confirmation transaction at Rococo Bulletin Chain may process. - pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = - bp_polkadot_bulletin::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. pub const RococoBulletinChainId: bp_runtime::ChainId = bp_polkadot_bulletin::PolkadotBulletin::ID; /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. @@ -142,31 +129,6 @@ impl XcmBlobHauler for ToRococoBulletinXcmBlobHauler { type OnMessagesDeliveredFromRococoBulletin = XcmBlobHaulerAdapter<ToRococoBulletinXcmBlobHauler, ActiveLanes>; -/// Messaging Bridge configuration for BridgeHubRococo -> Rococo Bulletin. -pub struct WithRococoBulletinMessageBridge; -impl MessageBridge for WithRococoBulletinMessageBridge { - // Bulletin chain assumes it is bridged with Polkadot Bridge Hub - const BRIDGED_MESSAGES_PALLET_NAME: &'static str = - bp_bridge_hub_polkadot::WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME; - type ThisChain = BridgeHubRococo; - type BridgedChain = RococoBulletin; - type BridgedHeaderChain = BridgeRococoBulletinGrandpa; -} - -/// Maximal outbound payload size of BridgeHubRococo -> RococoBulletin messages. -pub type ToRococoBulletinMaximalOutboundPayloadSize = - messages::source::FromThisChainMaximalOutboundPayloadSize<WithRococoBulletinMessageBridge>; - -/// RococoBulletin chain from message lane point of view. -#[derive(RuntimeDebug, Clone, Copy)] -pub struct RococoBulletin; - -impl UnderlyingChainProvider for RococoBulletin { - type Chain = bp_polkadot_bulletin::PolkadotBulletin; -} - -impl messages::BridgedChainWithMessages for RococoBulletin {} - /// Signed extension that refunds relayers that are delivering messages from the Rococo Bulletin /// chain. pub type OnBridgeHubRococoRefundRococoBulletinMessages = RefundSignedExtensionAdapter< @@ -189,22 +151,20 @@ impl pallet_bridge_messages::Config<WithRococoBulletinMessagesInstance> for Runt type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_bridge_messages_rococo_to_rococo_bulletin::WeightInfo<Runtime>; - type BridgedChainId = RococoBulletinChainId; + + type ThisChain = bp_bridge_hub_rococo::BridgeHubRococo; + type BridgedChain = bp_polkadot_bulletin::PolkadotBulletin; + type BridgedHeaderChain = BridgeRococoBulletinGrandpa; + type ActiveOutboundLanes = ActiveOutboundLanesToRococoBulletin; - type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; - type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; - type MaximalOutboundPayloadSize = ToRococoBulletinMaximalOutboundPayloadSize; type OutboundPayload = XcmAsPlainPayload; type InboundPayload = XcmAsPlainPayload; - type InboundRelayer = AccountId; type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter<WithRococoBulletinMessageBridge>; type DeliveryConfirmationPayments = (); - type SourceHeaderChain = SourceHeaderChainAdapter<WithRococoBulletinMessageBridge>; type MessageDispatch = XcmBlobMessageDispatch<FromRococoBulletinMessageBlobDispatcher, Self::WeightInfo, ()>; type OnMessagesDelivered = OnMessagesDeliveredFromRococoBulletin; @@ -267,8 +227,7 @@ mod tests { runtime: Runtime, with_bridged_chain_grandpa_instance: BridgeGrandpaRococoBulletinInstance, with_bridged_chain_messages_instance: WithRococoBulletinMessagesInstance, - bridge: WithRococoBulletinMessageBridge, - this_chain: bp_rococo::Rococo, + this_chain: bp_bridge_hub_rococo::BridgeHubRococo, bridged_chain: bp_polkadot_bulletin::PolkadotBulletin, ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 1681ac7f4687493c82c0a3233439b2a9d47a1ad0..07bb718bd13d60bb8eafd980a1fd642b52a97012 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -17,27 +17,21 @@ //! Bridge definitions used on BridgeHubRococo for bridging to BridgeHubWestend. use crate::{ - bridge_common_config::{ - BridgeHubRococo, BridgeParachainWestendInstance, DeliveryRewardInBalance, - }, + bridge_common_config::{BridgeParachainWestendInstance, DeliveryRewardInBalance}, weights, xcm_config::UniversalLocation, - AccountId, BridgeWestendMessages, PolkadotXcm, Runtime, RuntimeEvent, XcmOverBridgeHubWestend, - XcmRouter, + BridgeWestendMessages, PolkadotXcm, Runtime, RuntimeEvent, XcmOverBridgeHubWestend, XcmRouter, +}; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, LaneId, }; -use bp_messages::LaneId; use bp_runtime::Chain; use bridge_runtime_common::{ extensions::refund_relayer_extension::{ ActualFeeRefund, RefundBridgedMessages, RefundSignedExtensionAdapter, RefundableMessagesLane, }, - messages, - messages::{ - source::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChainAdapter}, - target::{FromBridgedChainMessagesProof, SourceHeaderChainAdapter}, - MessageBridge, UnderlyingChainProvider, - }, messages_xcm_extension::{ SenderAndLane, XcmAsPlainPayload, XcmBlobHauler, XcmBlobHaulerAdapter, XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, @@ -46,7 +40,6 @@ use bridge_runtime_common::{ use codec::Encode; use frame_support::{parameter_types, traits::PalletInfoAccess}; -use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, prelude::{InteriorLocation, NetworkId}, @@ -54,11 +47,7 @@ use xcm::{ use xcm_builder::BridgeBlobDispatcher; parameter_types! { - pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = - bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; - pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = - bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - pub const BridgeHubWestendChainId: bp_runtime::ChainId = BridgeHubWestend::ID; + pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_bridge_hub_westend::BridgeHubWestend::ID; pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(<BridgeWestendMessages as PalletInfoAccess>::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; pub WestendGlobalConsensusNetworkLocation: Location = Location::new( @@ -148,34 +137,6 @@ impl XcmBlobHauler for ToBridgeHubWestendXcmBlobHauler { type OnMessagesDeliveredFromWestend = XcmBlobHaulerAdapter<ToBridgeHubWestendXcmBlobHauler, ActiveLanes>; -/// Messaging Bridge configuration for BridgeHubRococo -> BridgeHubWestend -pub struct WithBridgeHubWestendMessageBridge; -impl MessageBridge for WithBridgeHubWestendMessageBridge { - const BRIDGED_MESSAGES_PALLET_NAME: &'static str = - bp_bridge_hub_rococo::WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME; - type ThisChain = BridgeHubRococo; - type BridgedChain = BridgeHubWestend; - type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< - Runtime, - BridgeParachainWestendInstance, - bp_bridge_hub_westend::BridgeHubWestend, - >; -} - -/// Maximal outbound payload size of BridgeHubRococo -> BridgeHubWestend messages. -pub type ToBridgeHubWestendMaximalOutboundPayloadSize = - messages::source::FromThisChainMaximalOutboundPayloadSize<WithBridgeHubWestendMessageBridge>; - -/// BridgeHubWestend chain from message lane point of view. -#[derive(RuntimeDebug, Clone, Copy)] -pub struct BridgeHubWestend; - -impl UnderlyingChainProvider for BridgeHubWestend { - type Chain = bp_bridge_hub_westend::BridgeHubWestend; -} - -impl messages::BridgedChainWithMessages for BridgeHubWestend {} - /// Signed extension that refunds relayers that are delivering messages from the Westend parachain. pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = RefundSignedExtensionAdapter< RefundBridgedMessages< @@ -196,26 +157,28 @@ pub type WithBridgeHubWestendMessagesInstance = pallet_bridge_messages::Instance impl pallet_bridge_messages::Config<WithBridgeHubWestendMessagesInstance> for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_bridge_messages_rococo_to_westend::WeightInfo<Runtime>; - type BridgedChainId = BridgeHubWestendChainId; + + type ThisChain = bp_bridge_hub_rococo::BridgeHubRococo; + type BridgedChain = bp_bridge_hub_westend::BridgeHubWestend; + type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< + Runtime, + BridgeParachainWestendInstance, + bp_bridge_hub_westend::BridgeHubWestend, + >; + type ActiveOutboundLanes = ActiveOutboundLanesToBridgeHubWestend; - type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; - type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; - type MaximalOutboundPayloadSize = ToBridgeHubWestendMaximalOutboundPayloadSize; type OutboundPayload = XcmAsPlainPayload; type InboundPayload = XcmAsPlainPayload; - type InboundRelayer = AccountId; type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter<WithBridgeHubWestendMessageBridge>; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubWestendMessagesInstance, DeliveryRewardInBalance, >; - type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubWestendMessageBridge>; type MessageDispatch = XcmBlobMessageDispatch< FromWestendMessageBlobDispatcher, Self::WeightInfo, @@ -248,9 +211,8 @@ mod tests { assert_complete_bridge_types, extensions::refund_relayer_extension::RefundableParachain, integrity::{ - assert_complete_bridge_constants, check_message_lane_weights, - AssertBridgeMessagesPalletConstants, AssertBridgePalletNames, AssertChainConstants, - AssertCompleteBridgeConstants, + assert_complete_with_parachain_bridge_constants, check_message_lane_weights, + AssertChainConstants, AssertCompleteBridgeConstants, }, }; use parachains_common::Balance; @@ -292,36 +254,20 @@ mod tests { runtime: Runtime, with_bridged_chain_grandpa_instance: BridgeGrandpaWestendInstance, with_bridged_chain_messages_instance: WithBridgeHubWestendMessagesInstance, - bridge: WithBridgeHubWestendMessageBridge, - this_chain: bp_rococo::Rococo, - bridged_chain: bp_westend::Westend, + this_chain: bp_bridge_hub_rococo::BridgeHubRococo, + bridged_chain: bp_bridge_hub_westend::BridgeHubWestend, ); - assert_complete_bridge_constants::< + assert_complete_with_parachain_bridge_constants::< Runtime, BridgeGrandpaWestendInstance, WithBridgeHubWestendMessagesInstance, - WithBridgeHubWestendMessageBridge, + bp_westend::Westend, >(AssertCompleteBridgeConstants { this_chain_constants: AssertChainConstants { block_length: bp_bridge_hub_rococo::BlockLength::get(), block_weights: bp_bridge_hub_rococo::BlockWeightsForAsyncBacking::get(), }, - messages_pallet_constants: AssertBridgeMessagesPalletConstants { - max_unrewarded_relayers_in_bridged_confirmation_tx: - bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, - max_unconfirmed_messages_in_bridged_confirmation_tx: - bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, - bridged_chain_id: BridgeHubWestend::ID, - }, - pallet_names: AssertBridgePalletNames { - with_this_chain_messages_pallet_name: - bp_bridge_hub_rococo::WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME, - with_bridged_chain_grandpa_pallet_name: - bp_westend::WITH_WESTEND_GRANDPA_PALLET_NAME, - with_bridged_chain_messages_pallet_name: - bp_bridge_hub_westend::WITH_BRIDGE_HUB_WESTEND_MESSAGES_PALLET_NAME, - }, }); bridge_runtime_common::extensions::priority_calculator::per_relay_header::ensure_priority_boost_is_sane::< @@ -332,7 +278,7 @@ mod tests { bridge_runtime_common::extensions::priority_calculator::per_parachain_header::ensure_priority_boost_is_sane::< Runtime, - RefundableParachain<WithBridgeHubWestendMessagesInstance, BridgeHubWestend>, + RefundableParachain<WithBridgeHubWestendMessagesInstance, bp_bridge_hub_westend::BridgeHubWestend>, PriorityBoostPerParachainHeader, >(FEE_BOOST_PER_PARACHAIN_HEADER); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 57ed5ec258d2c0a1df7f824c465ff53953d25835..8ca5898d1a104cfe6b1773ebca3b9ae0004167f5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1432,7 +1432,7 @@ impl_runtime_apis! { prepare_message_proof_from_parachain::< Runtime, bridge_common_config::BridgeGrandpaWestendInstance, - bridge_to_westend_config::WithBridgeHubWestendMessageBridge, + bridge_to_westend_config::WithBridgeHubWestendMessagesInstance, >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } @@ -1442,7 +1442,7 @@ impl_runtime_apis! { prepare_message_delivery_proof_from_parachain::< Runtime, bridge_common_config::BridgeGrandpaWestendInstance, - bridge_to_westend_config::WithBridgeHubWestendMessageBridge, + bridge_to_westend_config::WithBridgeHubWestendMessagesInstance, >(params) } @@ -1467,7 +1467,7 @@ impl_runtime_apis! { prepare_message_proof_from_grandpa_chain::< Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, - bridge_to_bulletin_config::WithRococoBulletinMessageBridge, + bridge_to_bulletin_config::WithRococoBulletinMessagesInstance, >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } @@ -1477,7 +1477,7 @@ impl_runtime_apis! { prepare_message_delivery_proof_from_grandpa_chain::< Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, - bridge_to_bulletin_config::WithRococoBulletinMessageBridge, + bridge_to_bulletin_config::WithRococoBulletinMessagesInstance, >(params) } @@ -1503,7 +1503,7 @@ impl_runtime_apis! { fn prepare_parachain_heads_proof( parachains: &[bp_polkadot_core::parachains::ParaId], parachain_head_size: u32, - proof_size: bp_runtime::StorageProofSize, + proof_params: bp_runtime::UnverifiedStorageProofParams, ) -> ( pallet_bridge_parachains::RelayBlockNumber, pallet_bridge_parachains::RelayBlockHash, @@ -1513,7 +1513,7 @@ impl_runtime_apis! { prepare_parachain_heads_proof::<Runtime, bridge_common_config::BridgeParachainWestendInstance>( parachains, parachain_head_size, - proof_size, + proof_params, ) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_grandpa.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_grandpa.rs index bbd27bbb1d7d95731f6274edc468a50beca449bf..4ce57b2e50161a812ddf17a9bbd20d5fc58682a7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_grandpa.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_grandpa.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_grandpa` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-yaoqqom-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -68,13 +68,13 @@ impl<T: frame_system::Config> pallet_bridge_grandpa::WeightInfo for WeightInfo<T // Proof Size summary in bytes: // Measured: `438 + p * (60 ±0)` // Estimated: `51735` - // Minimum execution time: 302_299_000 picoseconds. - Weight::from_parts(39_997_741, 0) + // Minimum execution time: 325_365_000 picoseconds. + Weight::from_parts(14_958_535, 0) .saturating_add(Weight::from_parts(0, 51735)) - // Standard Error: 22_953 - .saturating_add(Weight::from_parts(44_095_182, 0).saturating_mul(p.into())) - // Standard Error: 76_592 - .saturating_add(Weight::from_parts(2_262_037, 0).saturating_mul(v.into())) + // Standard Error: 15_085 + .saturating_add(Weight::from_parts(41_227_904, 0).saturating_mul(p.into())) + // Standard Error: 50_338 + .saturating_add(Weight::from_parts(2_664_555, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -92,8 +92,8 @@ impl<T: frame_system::Config> pallet_bridge_grandpa::WeightInfo for WeightInfo<T // Proof Size summary in bytes: // Measured: `452` // Estimated: `51735` - // Minimum execution time: 82_597_000 picoseconds. - Weight::from_parts(88_310_000, 0) + // Minimum execution time: 79_562_000 picoseconds. + Weight::from_parts(82_479_000, 0) .saturating_add(Weight::from_parts(0, 51735)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(6)) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs index 814716c08b6feef1a0cc995e9c536cff384f68f7..5522a325f192e1258e3aadcb7cb273430508eb48 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 @@ -60,8 +60,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 37_405_000 picoseconds. - Weight::from_parts(38_397_000, 0) + // Minimum execution time: 37_206_000 picoseconds. + Weight::from_parts(38_545_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -74,13 +74,17 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn receive_two_messages_proof() -> Weight { + /// The range of component `n` is `[1, 4076]`. + /// The range of component `n` is `[1, 4076]`. + fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 48_076_000 picoseconds. - Weight::from_parts(49_374_000, 0) + // Minimum execution time: 37_075_000 picoseconds. + Weight::from_parts(37_757_000, 0) .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 5_776 + .saturating_add(Weight::from_parts(11_586_768, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -96,8 +100,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 42_529_000 picoseconds. - Weight::from_parts(44_536_000, 0) + // Minimum execution time: 42_087_000 picoseconds. + Weight::from_parts(42_970_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -108,30 +112,20 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) - fn receive_single_message_proof_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `622` - // Estimated: `52645` - // Minimum execution time: 36_101_000 picoseconds. - Weight::from_parts(37_356_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) - /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) - /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) - fn receive_single_message_proof_16_kb() -> Weight { + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 16384]`. + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `622` + // Measured: `654` // Estimated: `52645` - // Minimum execution time: 70_370_000 picoseconds. - Weight::from_parts(72_054_000, 0) + // Minimum execution time: 35_055_000 picoseconds. + Weight::from_parts(36_987_740, 0) .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(3)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(2_316, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) @@ -144,8 +138,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_144_000 picoseconds. - Weight::from_parts(25_876_000, 0) + // Minimum execution time: 24_326_000 picoseconds. + Weight::from_parts(25_169_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -160,8 +154,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_085_000 picoseconds. - Weight::from_parts(25_872_000, 0) + // Minimum execution time: 24_484_000 picoseconds. + Weight::from_parts(25_130_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -176,8 +170,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_181_000 picoseconds. - Weight::from_parts(25_920_000, 0) + // Minimum execution time: 24_450_000 picoseconds. + Weight::from_parts(25_164_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -204,17 +198,17 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) - /// The range of component `i` is `[128, 2048]`. - /// The range of component `i` is `[128, 2048]`. - fn receive_single_message_proof_with_dispatch(i: u32, ) -> Weight { + /// The range of component `n` is `[1, 16384]`. + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `813` // Estimated: `52645` - // Minimum execution time: 57_941_000 picoseconds. - Weight::from_parts(59_000_115, 0) + // Minimum execution time: 54_317_000 picoseconds. + Weight::from_parts(59_171_547, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 46 - .saturating_add(Weight::from_parts(8_660, 0).saturating_mul(i.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(7_566, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs index e096c40d284e357a56df807a28bf6e05fbfedffc..9c05dae979daa0107e7754cc7107f80c3f753b7e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 @@ -62,8 +62,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 41_848_000 picoseconds. - Weight::from_parts(43_363_000, 0) + // Minimum execution time: 41_396_000 picoseconds. + Weight::from_parts(43_141_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,13 +78,17 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn receive_two_messages_proof() -> Weight { + /// The range of component `n` is `[1, 4076]`. + /// The range of component `n` is `[1, 4076]`. + fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 52_674_000 picoseconds. - Weight::from_parts(55_080_000, 0) + // Minimum execution time: 41_095_000 picoseconds. + Weight::from_parts(42_030_000, 0) .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 5_702 + .saturating_add(Weight::from_parts(11_627_951, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -102,8 +106,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 46_892_000 picoseconds. - Weight::from_parts(49_441_000, 0) + // Minimum execution time: 45_912_000 picoseconds. + Weight::from_parts(47_564_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,32 +120,20 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) - fn receive_single_message_proof_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `626` - // Estimated: `52645` - // Minimum execution time: 41_262_000 picoseconds. - Weight::from_parts(42_734_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) - /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) - /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) - fn receive_single_message_proof_16_kb() -> Weight { + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 16384]`. + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `626` + // Measured: `658` // Estimated: `52645` - // Minimum execution time: 75_654_000 picoseconds. - Weight::from_parts(76_866_000, 0) + // Minimum execution time: 39_175_000 picoseconds. + Weight::from_parts(41_674_095, 0) .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(2_305, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) @@ -158,8 +150,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 32_911_000 picoseconds. - Weight::from_parts(33_644_000, 0) + // Minimum execution time: 32_033_000 picoseconds. + Weight::from_parts(33_131_000, 0) .saturating_add(Weight::from_parts(0, 3966)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -178,8 +170,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 32_830_000 picoseconds. - Weight::from_parts(33_675_000, 0) + // Minimum execution time: 32_153_000 picoseconds. + Weight::from_parts(33_126_000, 0) .saturating_add(Weight::from_parts(0, 3966)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -198,8 +190,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `501` // Estimated: `6086` - // Minimum execution time: 37_024_000 picoseconds. - Weight::from_parts(38_112_000, 0) + // Minimum execution time: 36_387_000 picoseconds. + Weight::from_parts(37_396_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -226,17 +218,17 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) - /// The range of component `i` is `[128, 2048]`. - /// The range of component `i` is `[128, 2048]`. - fn receive_single_message_proof_with_dispatch(i: u32, ) -> Weight { + /// The range of component `n` is `[1, 16384]`. + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `789` // Estimated: `52645` - // Minimum execution time: 60_653_000 picoseconds. - Weight::from_parts(62_358_212, 0) + // Minimum execution time: 56_562_000 picoseconds. + Weight::from_parts(61_452_871, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 57 - .saturating_add(Weight::from_parts(8_660, 0).saturating_mul(i.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(7_587, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_parachains.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_parachains.rs index af216cd997c8160a06a60ecd979fda5a9003a095..8eb291ea14523b15d6c44b8ee72d637fcbe11166 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_parachains.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_parachains.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 @@ -61,13 +61,15 @@ impl<T: frame_system::Config> pallet_bridge_parachains::WeightInfo for WeightInf /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:0 w:1) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 2]`. - fn submit_parachain_heads_with_n_parachains(_p: u32, ) -> Weight { + fn submit_parachain_heads_with_n_parachains(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `558` // Estimated: `2543` - // Minimum execution time: 35_711_000 picoseconds. - Weight::from_parts(37_344_514, 0) + // Minimum execution time: 34_889_000 picoseconds. + Weight::from_parts(36_100_759, 0) .saturating_add(Weight::from_parts(0, 2543)) + // Standard Error: 102_466 + .saturating_add(Weight::from_parts(178_820, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -87,8 +89,8 @@ impl<T: frame_system::Config> pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `558` // Estimated: `2543` - // Minimum execution time: 37_717_000 picoseconds. - Weight::from_parts(38_374_000, 0) + // Minimum execution time: 36_501_000 picoseconds. + Weight::from_parts(37_266_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -109,8 +111,8 @@ impl<T: frame_system::Config> pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `558` // Estimated: `2543` - // Minimum execution time: 70_203_000 picoseconds. - Weight::from_parts(70_994_000, 0) + // Minimum execution time: 66_059_000 picoseconds. + Weight::from_parts(67_139_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_relayers.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_relayers.rs index a66a7fb08aaf1ae33b2336364bc836253305bda1..f8bb983e80aa776ae7fe8c9a756935096956e7dd 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_relayers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_relayers.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 @@ -56,8 +56,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `278` // Estimated: `3593` - // Minimum execution time: 43_669_000 picoseconds. - Weight::from_parts(44_907_000, 0) + // Minimum execution time: 44_224_000 picoseconds. + Weight::from_parts(44_905_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -72,8 +72,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `131` // Estimated: `4714` - // Minimum execution time: 24_024_000 picoseconds. - Weight::from_parts(24_582_000, 0) + // Minimum execution time: 23_902_000 picoseconds. + Weight::from_parts(24_702_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -86,8 +86,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `231` // Estimated: `4714` - // Minimum execution time: 24_522_000 picoseconds. - Weight::from_parts(25_362_000, 0) + // Minimum execution time: 24_469_000 picoseconds. + Weight::from_parts(25_176_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `334` // Estimated: `4714` - // Minimum execution time: 26_963_000 picoseconds. - Weight::from_parts(27_686_000, 0) + // Minimum execution time: 27_518_000 picoseconds. + Weight::from_parts(28_068_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `76` // Estimated: `3538` - // Minimum execution time: 5_401_000 picoseconds. - Weight::from_parts(5_563_000, 0) + // Minimum execution time: 5_484_000 picoseconds. + Weight::from_parts(5_718_000, 0) .saturating_add(Weight::from_parts(0, 3538)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index abd84f8e89b07799758c36b002c30db742305927..bafc973bdac444def7058de4a1a2c3feceb1abfc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-itmxxexx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-rococo-dev"), DB CACHE: 1024 // Executed Command: @@ -68,8 +68,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 61_813_000 picoseconds. - Weight::from_parts(62_996_000, 6196) + // Minimum execution time: 60_119_000 picoseconds. + Weight::from_parts(61_871_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -77,8 +77,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_044_000 picoseconds. - Weight::from_parts(2_112_000, 0) + // Minimum execution time: 998_000 picoseconds. + Weight::from_parts(1_038_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -86,58 +86,58 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 7_472_000 picoseconds. - Weight::from_parts(7_723_000, 3497) + // Minimum execution time: 6_327_000 picoseconds. + Weight::from_parts(6_520_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_414_000 picoseconds. - Weight::from_parts(8_765_000, 0) + // Minimum execution time: 6_783_000 picoseconds. + Weight::from_parts(7_117_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_192_000 picoseconds. - Weight::from_parts(2_243_000, 0) + // Minimum execution time: 1_589_000 picoseconds. + Weight::from_parts(1_655_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_866_000 picoseconds. - Weight::from_parts(1_931_000, 0) + // Minimum execution time: 1_013_000 picoseconds. + Weight::from_parts(1_045_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_847_000 picoseconds. - Weight::from_parts(1_921_000, 0) + // Minimum execution time: 1_005_000 picoseconds. + Weight::from_parts(1_044_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_797_000 picoseconds. - Weight::from_parts(1_880_000, 0) + // Minimum execution time: 964_000 picoseconds. + Weight::from_parts(1_011_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_458_000 picoseconds. - Weight::from_parts(2_523_000, 0) + // Minimum execution time: 1_005_000 picoseconds. + Weight::from_parts(1_027_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_833_000 picoseconds. - Weight::from_parts(1_906_000, 0) + // Minimum execution time: 980_000 picoseconds. + Weight::from_parts(1_009_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -159,8 +159,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 54_659_000 picoseconds. - Weight::from_parts(56_025_000, 6196) + // Minimum execution time: 56_726_000 picoseconds. + Weight::from_parts(59_300_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -170,8 +170,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 10_953_000 picoseconds. - Weight::from_parts(11_220_000, 3555) + // Minimum execution time: 8_962_000 picoseconds. + Weight::from_parts(9_519_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -179,8 +179,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_834_000 picoseconds. - Weight::from_parts(1_892_000, 0) + // Minimum execution time: 999_000 picoseconds. + Weight::from_parts(1_035_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -200,8 +200,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 22_238_000 picoseconds. - Weight::from_parts(22_690_000, 3503) + // Minimum execution time: 20_313_000 picoseconds. + Weight::from_parts(21_000_000, 3503) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -211,44 +211,44 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_798_000 picoseconds. - Weight::from_parts(3_936_000, 0) + // Minimum execution time: 2_820_000 picoseconds. + Weight::from_parts(2_949_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_985_000 picoseconds. - Weight::from_parts(3_099_000, 0) + // Minimum execution time: 1_293_000 picoseconds. + Weight::from_parts(1_354_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_955_000 picoseconds. - Weight::from_parts(2_050_000, 0) + // Minimum execution time: 1_076_000 picoseconds. + Weight::from_parts(1_114_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_939_000 picoseconds. - Weight::from_parts(1_990_000, 0) + // Minimum execution time: 1_014_000 picoseconds. + Weight::from_parts(1_055_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_841_000 picoseconds. - Weight::from_parts(1_900_000, 0) + // Minimum execution time: 979_000 picoseconds. + Weight::from_parts(1_019_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_081_000 picoseconds. - Weight::from_parts(2_145_000, 0) + // Minimum execution time: 1_161_000 picoseconds. + Weight::from_parts(1_208_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -270,8 +270,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 59_600_000 picoseconds. - Weight::from_parts(61_572_000, 6196) + // Minimum execution time: 62_250_000 picoseconds. + Weight::from_parts(64_477_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -279,8 +279,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_390_000 picoseconds. - Weight::from_parts(4_517_000, 0) + // Minimum execution time: 4_286_000 picoseconds. + Weight::from_parts(4_476_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -302,8 +302,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 53_864_000 picoseconds. - Weight::from_parts(55_527_000, 6196) + // Minimum execution time: 58_253_000 picoseconds. + Weight::from_parts(59_360_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -311,22 +311,22 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_879_000 picoseconds. - Weight::from_parts(1_947_000, 0) + // Minimum execution time: 1_026_000 picoseconds. + Weight::from_parts(1_065_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_827_000 picoseconds. - Weight::from_parts(1_900_000, 0) + // Minimum execution time: 993_000 picoseconds. + Weight::from_parts(1_015_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_824_000 picoseconds. - Weight::from_parts(1_898_000, 0) + // Minimum execution time: 966_000 picoseconds. + Weight::from_parts(999_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -339,16 +339,16 @@ impl<T: frame_system::Config> WeightInfo<T> { // Storage: `BridgeWestendMessages::OutboundLanesCongestedSignals` (r:1 w:0) // Proof: `BridgeWestendMessages::OutboundLanesCongestedSignals` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) // Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) - // Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(2621472), added: 2623947, mode: `MaxEncodedLen`) + // Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 1000]`. pub fn export_message(x: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `190` // Estimated: `6130` - // Minimum execution time: 41_598_000 picoseconds. - Weight::from_parts(42_219_173, 6130) - // Standard Error: 426 - .saturating_add(Weight::from_parts(452_460, 0).saturating_mul(x.into())) + // Minimum execution time: 37_014_000 picoseconds. + Weight::from_parts(38_096_655, 6130) + // Standard Error: 61 + .saturating_add(Weight::from_parts(45_146, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -356,14 +356,14 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_812_000 picoseconds. - Weight::from_parts(1_898_000, 0) + // Minimum execution time: 996_000 picoseconds. + Weight::from_parts(1_025_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_915_000 picoseconds. - Weight::from_parts(1_976_000, 0) + // Minimum execution time: 1_001_000 picoseconds. + Weight::from_parts(1_044_000, 0) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index b309232825db3aa964b2fa1a1d8d739f06ec3153..1d3d9e55f7eeb99bb46c23aba0bf9940515c69d4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -148,8 +148,7 @@ mod bridge_hub_westend_tests { use bridge_hub_test_utils::test_cases::from_parachain; use bridge_to_westend_config::{ BridgeHubWestendChainId, BridgeHubWestendLocation, WestendGlobalConsensusNetwork, - WithBridgeHubWestendMessageBridge, WithBridgeHubWestendMessagesInstance, - XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, + WithBridgeHubWestendMessagesInstance, XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, }; // Para id of sibling chain used in tests. @@ -162,7 +161,6 @@ mod bridge_hub_westend_tests { BridgeGrandpaWestendInstance, BridgeParachainWestendInstance, WithBridgeHubWestendMessagesInstance, - WithBridgeHubWestendMessageBridge, >; #[test] @@ -457,8 +455,8 @@ mod bridge_hub_bulletin_tests { use bridge_hub_test_utils::test_cases::from_grandpa_chain; use bridge_to_bulletin_config::{ RococoBulletinChainId, RococoBulletinGlobalConsensusNetwork, - RococoBulletinGlobalConsensusNetworkLocation, WithRococoBulletinMessageBridge, - WithRococoBulletinMessagesInstance, XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN, + RococoBulletinGlobalConsensusNetworkLocation, WithRococoBulletinMessagesInstance, + XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN, }; // Para id of sibling chain used in tests. @@ -470,7 +468,6 @@ mod bridge_hub_bulletin_tests { AllPalletsWithoutSystem, BridgeGrandpaRococoBulletinInstance, WithRococoBulletinMessagesInstance, - WithRococoBulletinMessageBridge, >; #[test] @@ -594,44 +591,4 @@ mod bridge_hub_bulletin_tests { construct_and_apply_extrinsic, ) } - - #[test] - pub fn can_calculate_fee_for_standalone_message_delivery_transaction() { - bridge_hub_test_utils::check_sane_fees_values( - "bp_bridge_hub_rococo::BridgeHubRococoBaseDeliveryFeeInRocs", - bp_bridge_hub_rococo::BridgeHubRococoBaseDeliveryFeeInRocs::get(), - || { - from_grandpa_chain::can_calculate_fee_for_standalone_message_delivery_transaction::< - RuntimeTestsAdapter, - >(collator_session_keys(), construct_and_estimate_extrinsic_fee) - }, - Perbill::from_percent(33), - None, /* we don't want lowering according to the Bulletin setup, because - * `from_grandpa_chain` is cheaper then `from_parachain_chain` */ - &format!( - "Estimate fee for `single message delivery` for runtime: {:?}", - <Runtime as frame_system::Config>::Version::get() - ), - ) - } - - #[test] - pub fn can_calculate_fee_for_standalone_message_confirmation_transaction() { - bridge_hub_test_utils::check_sane_fees_values( - "bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs", - bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs::get(), - || { - from_grandpa_chain::can_calculate_fee_for_standalone_message_confirmation_transaction::< - RuntimeTestsAdapter, - >(collator_session_keys(), construct_and_estimate_extrinsic_fee) - }, - Perbill::from_percent(33), - None, /* we don't want lowering according to the Bulletin setup, because - * `from_grandpa_chain` is cheaper then `from_parachain_chain` */ - &format!( - "Estimate fee for `single message confirmation` for runtime: {:?}", - <Runtime as frame_system::Config>::Version::get() - ), - ) - } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index c18d5036e06ad5772b24d4d53b8618bf054ef66a..e2671d3d606d1e993a38de2eeacf8a9675bb3b82 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -89,7 +89,7 @@ bp-messages = { workspace = true } bp-parachains = { workspace = true } bp-polkadot-core = { workspace = true } bp-relayers = { workspace = true } -bp-runtime = { workspace = true } +bp-runtime = { features = ["test-helpers"], workspace = true } bp-rococo = { workspace = true } bp-westend = { workspace = true } pallet-bridge-grandpa = { workspace = true } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 425b53da30fc8a176fcddfe145fab66a41b60f8a..09d55f4323ab5aa92be471758264e688e7d45e05 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -18,10 +18,12 @@ use crate::{ bridge_common_config::DeliveryRewardInBalance, weights, xcm_config::UniversalLocation, - AccountId, BridgeRococoMessages, PolkadotXcm, Runtime, RuntimeEvent, RuntimeOrigin, - XcmOverBridgeHubRococo, XcmRouter, + BridgeRococoMessages, PolkadotXcm, Runtime, RuntimeEvent, XcmOverBridgeHubRococo, XcmRouter, +}; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, LaneId, }; -use bp_messages::LaneId; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_runtime::Chain; use bridge_runtime_common::{ @@ -29,12 +31,6 @@ use bridge_runtime_common::{ ActualFeeRefund, RefundBridgedMessages, RefundSignedExtensionAdapter, RefundableMessagesLane, }, - messages, - messages::{ - source::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChainAdapter}, - target::{FromBridgedChainMessagesProof, SourceHeaderChainAdapter}, - MessageBridge, ThisChainWithMessages, UnderlyingChainProvider, - }, messages_xcm_extension::{ SenderAndLane, XcmAsPlainPayload, XcmBlobHauler, XcmBlobHaulerAdapter, XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, @@ -45,7 +41,6 @@ use frame_support::{ parameter_types, traits::{ConstU32, PalletInfoAccess}, }; -use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, prelude::{InteriorLocation, NetworkId}, @@ -59,11 +54,7 @@ parameter_types! { pub const RococoBridgeParachainPalletName: &'static str = "Paras"; pub const MaxRococoParaHeadDataSize: u32 = bp_rococo::MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE; - pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = - bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; - pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = - bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - pub const BridgeHubRococoChainId: bp_runtime::ChainId = BridgeHubRococo::ID; + pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_bridge_hub_rococo::BridgeHubRococo::ID; pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(<BridgeRococoMessages as PalletInfoAccess>::index() as u8)].into(); pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; pub RococoGlobalConsensusNetworkLocation: Location = Location::new( @@ -153,46 +144,6 @@ impl XcmBlobHauler for ToBridgeHubRococoXcmBlobHauler { /// On messages delivered callback. type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubRococoXcmBlobHauler, ActiveLanes>; -/// Messaging Bridge configuration for BridgeHubWestend -> BridgeHubRococo -pub struct WithBridgeHubRococoMessageBridge; -impl MessageBridge for WithBridgeHubRococoMessageBridge { - const BRIDGED_MESSAGES_PALLET_NAME: &'static str = - bp_bridge_hub_westend::WITH_BRIDGE_HUB_WESTEND_MESSAGES_PALLET_NAME; - type ThisChain = BridgeHubWestend; - type BridgedChain = BridgeHubRococo; - type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< - Runtime, - BridgeParachainRococoInstance, - bp_bridge_hub_rococo::BridgeHubRococo, - >; -} - -/// Maximal outbound payload size of BridgeHubWestend -> BridgeHubRococo messages. -type ToBridgeHubRococoMaximalOutboundPayloadSize = - messages::source::FromThisChainMaximalOutboundPayloadSize<WithBridgeHubRococoMessageBridge>; - -/// BridgeHubRococo chain from message lane point of view. -#[derive(RuntimeDebug, Clone, Copy)] -pub struct BridgeHubRococo; - -impl UnderlyingChainProvider for BridgeHubRococo { - type Chain = bp_bridge_hub_rococo::BridgeHubRococo; -} - -impl messages::BridgedChainWithMessages for BridgeHubRococo {} - -/// BridgeHubWestend chain from message lane point of view. -#[derive(RuntimeDebug, Clone, Copy)] -pub struct BridgeHubWestend; - -impl UnderlyingChainProvider for BridgeHubWestend { - type Chain = bp_bridge_hub_westend::BridgeHubWestend; -} - -impl ThisChainWithMessages for BridgeHubWestend { - type RuntimeOrigin = RuntimeOrigin; -} - /// Signed extension that refunds relayers that are delivering messages from the Rococo parachain. pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = RefundSignedExtensionAdapter< RefundBridgedMessages< @@ -237,26 +188,28 @@ pub type WithBridgeHubRococoMessagesInstance = pallet_bridge_messages::Instance1 impl pallet_bridge_messages::Config<WithBridgeHubRococoMessagesInstance> for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_bridge_messages::WeightInfo<Runtime>; - type BridgedChainId = BridgeHubRococoChainId; + + type ThisChain = bp_bridge_hub_westend::BridgeHubWestend; + type BridgedChain = bp_bridge_hub_rococo::BridgeHubRococo; + type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< + Runtime, + BridgeParachainRococoInstance, + bp_bridge_hub_rococo::BridgeHubRococo, + >; + type ActiveOutboundLanes = ActiveOutboundLanesToBridgeHubRococo; - type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; - type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; - type MaximalOutboundPayloadSize = ToBridgeHubRococoMaximalOutboundPayloadSize; type OutboundPayload = XcmAsPlainPayload; type InboundPayload = XcmAsPlainPayload; - type InboundRelayer = AccountId; type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter<WithBridgeHubRococoMessageBridge>; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubRococoMessagesInstance, DeliveryRewardInBalance, >; - type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubRococoMessageBridge>; type MessageDispatch = XcmBlobMessageDispatch< FromRococoMessageBlobDispatcher, Self::WeightInfo, @@ -287,9 +240,8 @@ mod tests { assert_complete_bridge_types, extensions::refund_relayer_extension::RefundableParachain, integrity::{ - assert_complete_bridge_constants, check_message_lane_weights, - AssertBridgeMessagesPalletConstants, AssertBridgePalletNames, AssertChainConstants, - AssertCompleteBridgeConstants, + assert_complete_with_parachain_bridge_constants, check_message_lane_weights, + AssertChainConstants, AssertCompleteBridgeConstants, }, }; use parachains_common::Balance; @@ -331,35 +283,20 @@ mod tests { runtime: Runtime, with_bridged_chain_grandpa_instance: BridgeGrandpaRococoInstance, with_bridged_chain_messages_instance: WithBridgeHubRococoMessagesInstance, - bridge: WithBridgeHubRococoMessageBridge, - this_chain: bp_westend::Westend, - bridged_chain: bp_rococo::Rococo, + this_chain: bp_bridge_hub_westend::BridgeHubWestend, + bridged_chain: bp_bridge_hub_rococo::BridgeHubRococo, ); - assert_complete_bridge_constants::< + assert_complete_with_parachain_bridge_constants::< Runtime, BridgeGrandpaRococoInstance, WithBridgeHubRococoMessagesInstance, - WithBridgeHubRococoMessageBridge, + bp_rococo::Rococo, >(AssertCompleteBridgeConstants { this_chain_constants: AssertChainConstants { block_length: bp_bridge_hub_westend::BlockLength::get(), block_weights: bp_bridge_hub_westend::BlockWeightsForAsyncBacking::get(), }, - messages_pallet_constants: AssertBridgeMessagesPalletConstants { - max_unrewarded_relayers_in_bridged_confirmation_tx: - bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, - max_unconfirmed_messages_in_bridged_confirmation_tx: - bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, - bridged_chain_id: BridgeHubRococo::ID, - }, - pallet_names: AssertBridgePalletNames { - with_this_chain_messages_pallet_name: - bp_bridge_hub_westend::WITH_BRIDGE_HUB_WESTEND_MESSAGES_PALLET_NAME, - with_bridged_chain_grandpa_pallet_name: bp_rococo::WITH_ROCOCO_GRANDPA_PALLET_NAME, - with_bridged_chain_messages_pallet_name: - bp_bridge_hub_rococo::WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME, - }, }); bridge_runtime_common::extensions::priority_calculator::per_relay_header::ensure_priority_boost_is_sane::< @@ -370,7 +307,7 @@ mod tests { bridge_runtime_common::extensions::priority_calculator::per_parachain_header::ensure_priority_boost_is_sane::< Runtime, - RefundableParachain<WithBridgeHubRococoMessagesInstance, BridgeHubRococo>, + RefundableParachain<WithBridgeHubRococoMessagesInstance, bp_bridge_hub_rococo::BridgeHubRococo>, PriorityBoostPerParachainHeader, >(FEE_BOOST_PER_PARACHAIN_HEADER); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 05d6cdfd691e6220f7d539ec800eaff45dd19287..993f60432458739834d9a7c4384243fa597d60fe 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -1118,7 +1118,7 @@ impl_runtime_apis! { prepare_message_proof_from_parachain::< Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, - bridge_to_rococo_config::WithBridgeHubRococoMessageBridge, + bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance, >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Westend), Parachain(42)].into())) } @@ -1128,7 +1128,7 @@ impl_runtime_apis! { prepare_message_delivery_proof_from_parachain::< Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, - bridge_to_rococo_config::WithBridgeHubRococoMessageBridge, + bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance, >(params) } @@ -1154,7 +1154,7 @@ impl_runtime_apis! { fn prepare_parachain_heads_proof( parachains: &[bp_polkadot_core::parachains::ParaId], parachain_head_size: u32, - proof_size: bp_runtime::StorageProofSize, + proof_params: bp_runtime::UnverifiedStorageProofParams, ) -> ( pallet_bridge_parachains::RelayBlockNumber, pallet_bridge_parachains::RelayBlockHash, @@ -1164,7 +1164,7 @@ impl_runtime_apis! { prepare_parachain_heads_proof::<Runtime, bridge_to_rococo_config::BridgeParachainRococoInstance>( parachains, parachain_head_size, - proof_size, + proof_params, ) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_grandpa.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_grandpa.rs index a9ccb00b1a1c84376878781bb0a8f9acb2580b9e..fa7efc260489bead50ba63969571e018248ddefe 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_grandpa.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_grandpa.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_grandpa` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-yaoqqom-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -68,13 +68,13 @@ impl<T: frame_system::Config> pallet_bridge_grandpa::WeightInfo for WeightInfo<T // Proof Size summary in bytes: // Measured: `268 + p * (60 ±0)` // Estimated: `51735` - // Minimum execution time: 290_999_000 picoseconds. - Weight::from_parts(8_417_887, 0) + // Minimum execution time: 294_381_000 picoseconds. + Weight::from_parts(21_868_057, 0) .saturating_add(Weight::from_parts(0, 51735)) - // Standard Error: 15_256 - .saturating_add(Weight::from_parts(41_159_168, 0).saturating_mul(p.into())) - // Standard Error: 50_907 - .saturating_add(Weight::from_parts(2_560_033, 0).saturating_mul(v.into())) + // Standard Error: 14_649 + .saturating_add(Weight::from_parts(40_681_012, 0).saturating_mul(p.into())) + // Standard Error: 48_883 + .saturating_add(Weight::from_parts(2_466_672, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -92,8 +92,8 @@ impl<T: frame_system::Config> pallet_bridge_grandpa::WeightInfo for WeightInfo<T // Proof Size summary in bytes: // Measured: `282` // Estimated: `51735` - // Minimum execution time: 116_445_000 picoseconds. - Weight::from_parts(129_204_000, 0) + // Minimum execution time: 96_441_000 picoseconds. + Weight::from_parts(110_957_000, 0) .saturating_add(Weight::from_parts(0, 51735)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(6)) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs index 2fbce4231f33262645e45df8e5ed3694df8985cf..386342d7ea5d863e89df13027291350c182d2012 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 @@ -62,8 +62,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 41_095_000 picoseconds. - Weight::from_parts(42_438_000, 0) + // Minimum execution time: 40_748_000 picoseconds. + Weight::from_parts(41_836_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,13 +78,16 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn receive_two_messages_proof() -> Weight { + /// The range of component `n` is `[1, 4076]`. + fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 51_974_000 picoseconds. - Weight::from_parts(53_444_000, 0) + // Minimum execution time: 40_923_000 picoseconds. + Weight::from_parts(41_287_000, 0) .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 9_774 + .saturating_add(Weight::from_parts(11_469_207, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -102,8 +105,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 45_949_000 picoseconds. - Weight::from_parts(47_912_000, 0) + // Minimum execution time: 45_946_000 picoseconds. + Weight::from_parts(47_547_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,32 +119,19 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) - fn receive_single_message_proof_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `453` - // Estimated: `52645` - // Minimum execution time: 39_349_000 picoseconds. - Weight::from_parts(40_723_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) - /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) - /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) - fn receive_single_message_proof_16_kb() -> Weight { + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `453` + // Measured: `522` // Estimated: `52645` - // Minimum execution time: 70_566_000 picoseconds. - Weight::from_parts(73_240_000, 0) + // Minimum execution time: 39_668_000 picoseconds. + Weight::from_parts(41_908_980, 0) .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(2_209, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) @@ -158,8 +148,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 31_381_000 picoseconds. - Weight::from_parts(31_980_000, 0) + // Minimum execution time: 30_544_000 picoseconds. + Weight::from_parts(31_171_000, 0) .saturating_add(Weight::from_parts(0, 3822)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -178,8 +168,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 31_479_000 picoseconds. - Weight::from_parts(32_220_000, 0) + // Minimum execution time: 30_593_000 picoseconds. + Weight::from_parts(31_261_000, 0) .saturating_add(Weight::from_parts(0, 3822)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -198,8 +188,8 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `357` // Estimated: `6086` - // Minimum execution time: 35_724_000 picoseconds. - Weight::from_parts(36_460_000, 0) + // Minimum execution time: 34_682_000 picoseconds. + Weight::from_parts(35_277_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -226,16 +216,16 @@ impl<T: frame_system::Config> pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) - /// The range of component `i` is `[128, 2048]`. - fn receive_single_message_proof_with_dispatch(i: u32, ) -> Weight { + /// The range of component `n` is `[1, 16384]`. + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `653` // Estimated: `52645` - // Minimum execution time: 60_476_000 picoseconds. - Weight::from_parts(61_832_928, 0) + // Minimum execution time: 56_465_000 picoseconds. + Weight::from_parts(61_575_775, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 73 - .saturating_add(Weight::from_parts(7_951, 0).saturating_mul(i.into())) + // Standard Error: 15 + .saturating_add(Weight::from_parts(7_197, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_parachains.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_parachains.rs index 82764a48b48092dd1b263db33110d45897ee2cef..b4748f1417059e91e482c650f5046ef09b76a7af 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_parachains.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_parachains.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 @@ -61,15 +61,13 @@ impl<T: frame_system::Config> pallet_bridge_parachains::WeightInfo for WeightInf /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:0 w:1) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 2]`. - fn submit_parachain_heads_with_n_parachains(p: u32, ) -> Weight { + fn submit_parachain_heads_with_n_parachains(_p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `2543` - // Minimum execution time: 34_408_000 picoseconds. - Weight::from_parts(35_467_881, 0) + // Minimum execution time: 34_177_000 picoseconds. + Weight::from_parts(35_662_308, 0) .saturating_add(Weight::from_parts(0, 2543)) - // Standard Error: 100_493 - .saturating_add(Weight::from_parts(63_859, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -89,8 +87,8 @@ impl<T: frame_system::Config> pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `315` // Estimated: `2543` - // Minimum execution time: 36_125_000 picoseconds. - Weight::from_parts(36_703_000, 0) + // Minimum execution time: 35_975_000 picoseconds. + Weight::from_parts(36_510_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -111,8 +109,8 @@ impl<T: frame_system::Config> pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `315` // Estimated: `2543` - // Minimum execution time: 64_697_000 picoseconds. - Weight::from_parts(68_015_000, 0) + // Minimum execution time: 62_837_000 picoseconds. + Weight::from_parts(63_562_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_relayers.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_relayers.rs index 7e3f3f3d7230afbc71188e529956011d9181f463..60d81dc3082a86ea3cea3951d4ed59cf9be8ed56 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_relayers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_relayers.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 @@ -56,8 +56,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `207` // Estimated: `3593` - // Minimum execution time: 43_291_000 picoseconds. - Weight::from_parts(44_118_000, 0) + // Minimum execution time: 43_132_000 picoseconds. + Weight::from_parts(43_923_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -72,8 +72,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `61` // Estimated: `4714` - // Minimum execution time: 23_286_000 picoseconds. - Weight::from_parts(23_823_000, 0) + // Minimum execution time: 22_765_000 picoseconds. + Weight::from_parts(23_576_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -86,8 +86,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `160` // Estimated: `4714` - // Minimum execution time: 24_145_000 picoseconds. - Weight::from_parts(24_541_000, 0) + // Minimum execution time: 24_013_000 picoseconds. + Weight::from_parts(24_460_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `263` // Estimated: `4714` - // Minimum execution time: 26_707_000 picoseconds. - Weight::from_parts(27_266_000, 0) + // Minimum execution time: 26_946_000 picoseconds. + Weight::from_parts(27_485_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `6` // Estimated: `3538` - // Minimum execution time: 4_850_000 picoseconds. - Weight::from_parts(5_116_000, 0) + // Minimum execution time: 4_658_000 picoseconds. + Weight::from_parts(4_902_000, 0) .saturating_add(Weight::from_parts(0, 3538)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 9281a880c7e1266d65d29436ca88e51e896c0363..73bea66bf7107f0c73696713c293b9fd9a714380 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-itmxxexx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-7wrmsoux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-westend-dev"), DB CACHE: 1024 // Executed Command: @@ -68,8 +68,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 61_577_000 picoseconds. - Weight::from_parts(63_216_000, 6196) + // Minimum execution time: 58_505_000 picoseconds. + Weight::from_parts(60_437_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -77,8 +77,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_019_000 picoseconds. - Weight::from_parts(2_146_000, 0) + // Minimum execution time: 510_000 picoseconds. + Weight::from_parts(569_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -86,58 +86,58 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 7_473_000 picoseconds. - Weight::from_parts(7_784_000, 3497) + // Minimum execution time: 5_597_000 picoseconds. + Weight::from_parts(5_884_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_385_000 picoseconds. - Weight::from_parts(8_768_000, 0) + // Minimum execution time: 5_320_000 picoseconds. + Weight::from_parts(5_594_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_181_000 picoseconds. - Weight::from_parts(2_304_000, 0) + // Minimum execution time: 1_164_000 picoseconds. + Weight::from_parts(1_227_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_858_000 picoseconds. - Weight::from_parts(1_919_000, 0) + // Minimum execution time: 528_000 picoseconds. + Weight::from_parts(586_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_855_000 picoseconds. - Weight::from_parts(1_979_000, 0) + // Minimum execution time: 509_000 picoseconds. + Weight::from_parts(571_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_823_000 picoseconds. - Weight::from_parts(1_890_000, 0) + // Minimum execution time: 511_000 picoseconds. + Weight::from_parts(546_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_407_000 picoseconds. - Weight::from_parts(2_507_000, 0) + // Minimum execution time: 560_000 picoseconds. + Weight::from_parts(600_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_838_000 picoseconds. - Weight::from_parts(1_894_000, 0) + // Minimum execution time: 514_000 picoseconds. + Weight::from_parts(558_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -159,8 +159,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 54_847_000 picoseconds. - Weight::from_parts(55_742_000, 6196) + // Minimum execution time: 55_871_000 picoseconds. + Weight::from_parts(57_172_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -170,8 +170,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 10_614_000 picoseconds. - Weight::from_parts(11_344_000, 3555) + // Minimum execution time: 8_487_000 picoseconds. + Weight::from_parts(8_800_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -179,8 +179,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_826_000 picoseconds. - Weight::from_parts(1_899_000, 0) + // Minimum execution time: 528_000 picoseconds. + Weight::from_parts(569_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -200,8 +200,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 22_312_000 picoseconds. - Weight::from_parts(22_607_000, 3503) + // Minimum execution time: 19_803_000 picoseconds. + Weight::from_parts(20_368_000, 3503) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -211,44 +211,44 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_728_000 picoseconds. - Weight::from_parts(3_914_000, 0) + // Minimum execution time: 2_185_000 picoseconds. + Weight::from_parts(2_332_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_054_000 picoseconds. - Weight::from_parts(3_140_000, 0) + // Minimum execution time: 822_000 picoseconds. + Weight::from_parts(928_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_996_000 picoseconds. - Weight::from_parts(2_148_000, 0) + // Minimum execution time: 603_000 picoseconds. + Weight::from_parts(643_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_008_000 picoseconds. - Weight::from_parts(2_077_000, 0) + // Minimum execution time: 503_000 picoseconds. + Weight::from_parts(580_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_837_000 picoseconds. - Weight::from_parts(1_913_000, 0) + // Minimum execution time: 534_000 picoseconds. + Weight::from_parts(577_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_052_000 picoseconds. - Weight::from_parts(2_120_000, 0) + // Minimum execution time: 694_000 picoseconds. + Weight::from_parts(745_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -270,8 +270,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 58_725_000 picoseconds. - Weight::from_parts(60_271_000, 6196) + // Minimum execution time: 61_083_000 picoseconds. + Weight::from_parts(62_214_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -279,8 +279,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_570_000 picoseconds. - Weight::from_parts(4_707_000, 0) + // Minimum execution time: 3_261_000 picoseconds. + Weight::from_parts(3_483_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -302,8 +302,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 54_903_000 picoseconds. - Weight::from_parts(55_711_000, 6196) + // Minimum execution time: 56_270_000 picoseconds. + Weight::from_parts(57_443_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -311,22 +311,22 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_872_000 picoseconds. - Weight::from_parts(1_938_000, 0) + // Minimum execution time: 565_000 picoseconds. + Weight::from_parts(628_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_836_000 picoseconds. - Weight::from_parts(1_903_000, 0) + // Minimum execution time: 496_000 picoseconds. + Weight::from_parts(563_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_847_000 picoseconds. - Weight::from_parts(1_900_000, 0) + // Minimum execution time: 518_000 picoseconds. + Weight::from_parts(557_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -339,16 +339,16 @@ impl<T: frame_system::Config> WeightInfo<T> { // Storage: `BridgeRococoMessages::OutboundLanesCongestedSignals` (r:1 w:0) // Proof: `BridgeRococoMessages::OutboundLanesCongestedSignals` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) // Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) - // Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(2621472), added: 2623947, mode: `MaxEncodedLen`) + // Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 1000]`. pub fn export_message(x: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `225` // Estimated: `6165` - // Minimum execution time: 41_750_000 picoseconds. - Weight::from_parts(43_496_915, 6165) - // Standard Error: 623 - .saturating_add(Weight::from_parts(457_907, 0).saturating_mul(x.into())) + // Minimum execution time: 36_288_000 picoseconds. + Weight::from_parts(37_707_751, 6165) + // Standard Error: 124 + .saturating_add(Weight::from_parts(51_290, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -356,14 +356,14 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_826_000 picoseconds. - Weight::from_parts(1_911_000, 0) + // Minimum execution time: 485_000 picoseconds. + Weight::from_parts(540_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_967_000 picoseconds. - Weight::from_parts(2_096_000, 0) + // Minimum execution time: 542_000 picoseconds. + Weight::from_parts(586_000, 0) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 836594140b2328081ff6c0de8cac40ea82dfb6f7..763271fd7af0e69ae8de2aa4fe507083f5d09d9e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -28,8 +28,8 @@ use bridge_hub_westend_runtime::{ }; use bridge_to_rococo_config::{ BridgeGrandpaRococoInstance, BridgeHubRococoChainId, BridgeHubRococoLocation, - BridgeParachainRococoInstance, WithBridgeHubRococoMessageBridge, - WithBridgeHubRococoMessagesInstance, XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, + BridgeParachainRococoInstance, WithBridgeHubRococoMessagesInstance, + XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, }; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; @@ -53,7 +53,6 @@ type RuntimeTestsAdapter = from_parachain::WithRemoteParachainHelperAdapter< BridgeGrandpaRococoInstance, BridgeParachainRococoInstance, WithBridgeHubRococoMessagesInstance, - WithBridgeHubRococoMessageBridge, >; parameter_types! { diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml index 90af4dd8f3ed80708cde59e66aed557042e3da39..fb96d29a497a37084ae83a461f5a2ff2bb6a7af0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml @@ -48,7 +48,7 @@ bp-runtime = { workspace = true } bp-test-utils = { workspace = true } pallet-bridge-grandpa = { workspace = true } pallet-bridge-parachains = { workspace = true } -pallet-bridge-messages = { workspace = true } +pallet-bridge-messages = { features = ["test-helpers"], workspace = true } pallet-bridge-relayers = { workspace = true } bridge-runtime-common = { workspace = true } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index bfa2f0f50f94ca3ba2f663f9646be3165dd48220..8f3c7de61f8402d7b28231325a9ddc3ab3bac052 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -23,21 +23,12 @@ use crate::{ }; use bp_header_chain::ChainWithGrandpa; -use bp_messages::{ - source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, LaneId, - UnrewardedRelayersState, -}; +use bp_messages::{LaneId, UnrewardedRelayersState}; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; -use bp_runtime::{HashOf, UnderlyingChainOf}; -use bridge_runtime_common::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - BridgedChain as MessageBridgedChain, MessageBridge, ThisChain as MessageThisChain, - }, - messages_xcm_extension::XcmAsPlainPayload, -}; +use bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload; use frame_support::traits::{OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; +use pallet_bridge_messages::{BridgedChainOf, ThisChainOf}; use parachains_runtimes_test_utils::{ AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; @@ -53,13 +44,10 @@ pub trait WithRemoteGrandpaChainHelper { /// This chain runtime. type Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config - + BridgeGrandpaConfig< - Self::GPI, - BridgedChain = UnderlyingChainOf<MessageBridgedChain<Self::MB>>, - > + BridgeMessagesConfig< + + BridgeGrandpaConfig<Self::GPI, BridgedChain = BridgedChainOf<Self::Runtime, Self::MPI>> + + BridgeMessagesConfig< Self::MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf<MessageBridgedChain<Self::MB>>, OutboundPayload = XcmAsPlainPayload, > + pallet_bridge_relayers::Config; /// All pallets of this chain, excluding system pallet. @@ -69,38 +57,33 @@ pub trait WithRemoteGrandpaChainHelper { type GPI: 'static; /// Instance of the `pallet-bridge-messages`, used to bridge with remote GRANDPA chain. type MPI: 'static; - /// Messages bridge definition. - type MB: MessageBridge; } /// Adapter struct that implements [`WithRemoteGrandpaChainHelper`]. -pub struct WithRemoteGrandpaChainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, MPI, MB>( - sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, MPI, MB)>, +pub struct WithRemoteGrandpaChainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, MPI>( + sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, MPI)>, ); -impl<Runtime, AllPalletsWithoutSystem, GPI, MPI, MB> WithRemoteGrandpaChainHelper - for WithRemoteGrandpaChainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, MPI, MB> +impl<Runtime, AllPalletsWithoutSystem, GPI, MPI> WithRemoteGrandpaChainHelper + for WithRemoteGrandpaChainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, MPI> where Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config - + BridgeGrandpaConfig<GPI, BridgedChain = UnderlyingChainOf<MessageBridgedChain<MB>>> + + BridgeGrandpaConfig<GPI, BridgedChain = BridgedChainOf<Runtime, MPI>> + BridgeMessagesConfig< MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf<MessageBridgedChain<MB>>, OutboundPayload = XcmAsPlainPayload, > + pallet_bridge_relayers::Config, AllPalletsWithoutSystem: OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>, GPI: 'static, MPI: 'static, - MB: MessageBridge, { type Runtime = Runtime; type AllPalletsWithoutSystem = AllPalletsWithoutSystem; type GPI = GPI; type MPI = MPI; - type MB = MB; } /// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer, @@ -124,13 +107,7 @@ pub fn relayed_incoming_message_works<RuntimeHelper>( AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -161,7 +138,8 @@ pub fn relayed_incoming_message_works<RuntimeHelper>( // to be submitted by relayer to this chain. let (relay_chain_header, grandpa_justification, message_proof) = test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( lane_id, @@ -186,7 +164,7 @@ pub fn relayed_incoming_message_works<RuntimeHelper>( ( BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), @@ -233,13 +211,7 @@ pub fn free_relay_extrinsic_works<RuntimeHelper>( AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { // ensure that the runtime allows free header submissions let free_headers_interval = <RuntimeHelper::Runtime as BridgeGrandpaConfig< @@ -291,7 +263,8 @@ pub fn free_relay_extrinsic_works<RuntimeHelper>( // to be submitted by relayer to this chain. let (relay_chain_header, grandpa_justification, message_proof) = test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( lane_id, @@ -322,7 +295,7 @@ pub fn free_relay_extrinsic_works<RuntimeHelper>( ( BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), @@ -370,13 +343,7 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>( RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>> + From<pallet_utility::Call<RuntimeHelper::Runtime>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -407,7 +374,8 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>( // to be submitted by relayer to this chain. let (relay_chain_header, grandpa_justification, message_proof) = test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( lane_id, @@ -428,7 +396,7 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>( }.into(), BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), @@ -470,13 +438,7 @@ where pallet_utility::Config<RuntimeCall = RuntimeCallOf<RuntimeHelper::Runtime>>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -487,7 +449,8 @@ where // the message additionally let (relay_chain_header, grandpa_justification, message_proof) = test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), @@ -526,19 +489,11 @@ where AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>, RuntimeHelper::Runtime: pallet_utility::Config<RuntimeCall = RuntimeCallOf<RuntimeHelper::Runtime>>, - MessageThisChain<RuntimeHelper::MB>: + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: bp_runtime::Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf<RuntimeHelper::Runtime>, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf<UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -550,7 +505,8 @@ where }; let (relay_chain_header, grandpa_justification, message_delivery_proof) = test_data::from_grandpa_chain::make_complex_relayer_confirmation_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), @@ -587,13 +543,7 @@ where RuntimeHelper: WithRemoteGrandpaChainHelper, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -604,7 +554,8 @@ where // the message additionally let (_, _, message_proof) = test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), @@ -639,19 +590,11 @@ pub fn can_calculate_fee_for_standalone_message_confirmation_transaction<Runtime where RuntimeHelper: WithRemoteGrandpaChainHelper, AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>, - MessageThisChain<RuntimeHelper::MB>: + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: bp_runtime::Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf<RuntimeHelper::Runtime>, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf<UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>>, - >, - >, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: ChainWithGrandpa, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -663,7 +606,8 @@ where }; let (_, _, message_delivery_proof) = test_data::from_grandpa_chain::make_complex_relayer_confirmation_proofs::< - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 12ab382d9e0f6518afb93f118199170acb5f8cc6..6580648e66063fdd2aff3f8c802cda6efe8e07f3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -23,22 +23,14 @@ use crate::{ }; use bp_header_chain::ChainWithGrandpa; -use bp_messages::{ - source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, LaneId, - UnrewardedRelayersState, -}; +use bp_messages::{LaneId, UnrewardedRelayersState}; use bp_polkadot_core::parachains::ParaHash; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; -use bp_runtime::{HashOf, Parachain, UnderlyingChainOf}; -use bridge_runtime_common::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - BridgedChain as MessageBridgedChain, MessageBridge, ThisChain as MessageThisChain, - }, - messages_xcm_extension::XcmAsPlainPayload, -}; +use bp_runtime::{Chain, Parachain}; +use bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload; use frame_support::traits::{OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; +use pallet_bridge_messages::{BridgedChainOf, ThisChainOf}; use parachains_runtimes_test_utils::{ AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; @@ -59,7 +51,6 @@ pub trait WithRemoteParachainHelper { + BridgeMessagesConfig< Self::MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf<MessageBridgedChain<Self::MB>>, OutboundPayload = XcmAsPlainPayload, > + pallet_bridge_relayers::Config; /// All pallets of this chain, excluding system pallet. @@ -71,17 +62,15 @@ pub trait WithRemoteParachainHelper { type PPI: 'static; /// Instance of the `pallet-bridge-messages`, used to bridge with remote parachain. type MPI: 'static; - /// Messages bridge definition. - type MB: MessageBridge; } /// Adapter struct that implements `WithRemoteParachainHelper`. -pub struct WithRemoteParachainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, MB>( - sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, MB)>, +pub struct WithRemoteParachainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI>( + sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI)>, ); -impl<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, MB> WithRemoteParachainHelper - for WithRemoteParachainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, MB> +impl<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI> WithRemoteParachainHelper + for WithRemoteParachainHelperAdapter<Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI> where Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config @@ -90,7 +79,6 @@ where + BridgeMessagesConfig< MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf<MessageBridgedChain<MB>>, OutboundPayload = XcmAsPlainPayload, > + pallet_bridge_relayers::Config, AllPalletsWithoutSystem: @@ -98,14 +86,13 @@ where GPI: 'static, PPI: 'static, MPI: 'static, - MB: MessageBridge, + // MB: MessageBridge, { type Runtime = Runtime; type AllPalletsWithoutSystem = AllPalletsWithoutSystem; type GPI = GPI; type PPI = PPI; type MPI = MPI; - type MB = MB; } /// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer, @@ -131,16 +118,9 @@ pub fn relayed_incoming_message_works<RuntimeHelper>( RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -179,7 +159,8 @@ pub fn relayed_incoming_message_works<RuntimeHelper>( message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( lane_id, @@ -219,7 +200,7 @@ pub fn relayed_incoming_message_works<RuntimeHelper>( ( BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), @@ -268,16 +249,9 @@ pub fn free_relay_extrinsic_works<RuntimeHelper>( RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, { // ensure that the runtime allows free header submissions let free_headers_interval = <RuntimeHelper::Runtime as BridgeGrandpaConfig< @@ -338,7 +312,8 @@ pub fn free_relay_extrinsic_works<RuntimeHelper>( message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( lane_id, @@ -390,7 +365,7 @@ pub fn free_relay_extrinsic_works<RuntimeHelper>( ( BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), @@ -440,16 +415,9 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>( + From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>> + From<pallet_utility::Call<RuntimeHelper::Runtime>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -488,7 +456,8 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>( message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( lane_id, @@ -518,7 +487,7 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>( }.into(), BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), @@ -565,16 +534,9 @@ where RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -592,7 +554,8 @@ where message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< <RuntimeHelper::Runtime as pallet_bridge_grandpa::Config<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), @@ -612,7 +575,6 @@ where RuntimeHelper::GPI, RuntimeHelper::PPI, RuntimeHelper::MPI, - _, >( relay_chain_header, grandpa_justification, @@ -637,23 +599,14 @@ where AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>, RuntimeHelper::Runtime: pallet_utility::Config<RuntimeCall = RuntimeCallOf<RuntimeHelper::Runtime>>, - MessageThisChain<RuntimeHelper::MB>: - bp_runtime::Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: + Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>> + From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>> + From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf<RuntimeHelper::Runtime>, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf<UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>>, - >, - >, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -672,7 +625,8 @@ where message_delivery_proof, ) = test_data::from_parachain::make_complex_relayer_confirmation_proofs::< <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), @@ -714,16 +668,9 @@ where RuntimeHelper: WithRemoteParachainHelper, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf<MessageBridgedChain<RuntimeHelper::MB>>, - >, - >, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -741,7 +688,8 @@ where message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< <RuntimeHelper::Runtime as pallet_bridge_grandpa::Config<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), @@ -757,7 +705,6 @@ where let call = test_data::from_parachain::make_standalone_relayer_delivery_call::< RuntimeHelper::Runtime, RuntimeHelper::MPI, - _, >( message_proof, helpers::relayer_id_at_bridged_chain::<RuntimeHelper::Runtime, RuntimeHelper::MPI>(), @@ -778,22 +725,13 @@ pub fn can_calculate_fee_for_standalone_message_confirmation_transaction<Runtime where RuntimeHelper: WithRemoteParachainHelper, AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>, - MessageThisChain<RuntimeHelper::MB>: - bp_runtime::Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: + Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>, RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>, - UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: - bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>: Chain<Hash = ParaHash> + Parachain, <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf<RuntimeHelper::Runtime>, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf<UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>>, - >, - >, { run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || { // generate bridged relay chain finality, parachain heads and message proofs, @@ -806,7 +744,8 @@ where let (_, _, _, _, _, message_delivery_proof) = test_data::from_parachain::make_complex_relayer_confirmation_proofs::< <RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, + ThisChainOf<RuntimeHelper::Runtime, RuntimeHelper::MPI>, (), >( LaneId::default(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index 0ce049cd1c4630c55c244afbc8a72213cb83d6b9..c990c6e5307cb3f1c390fcb28e1261e2713f899f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -29,6 +29,7 @@ use frame_support::{ }; use frame_system::pallet_prelude::BlockNumberFor; use pallet_bridge_grandpa::{BridgedBlockHash, BridgedHeader}; +use pallet_bridge_messages::BridgedChainOf; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, SlotDurations, @@ -240,10 +241,12 @@ pub(crate) fn initialize_bridge_grandpa_pallet<Runtime, GPI>( pub type CallsAndVerifiers<Runtime> = Vec<(RuntimeCallOf<Runtime>, Box<dyn VerifyTransactionOutcome>)>; +pub type InboundRelayerId<Runtime, MPI> = bp_runtime::AccountIdOf<BridgedChainOf<Runtime, MPI>>; + /// Returns relayer id at the bridged chain. pub fn relayer_id_at_bridged_chain<Runtime: pallet_bridge_messages::Config<MPI>, MPI>( -) -> Runtime::InboundRelayer { - Runtime::InboundRelayer::decode(&mut TrailingZeroInput::zeroes()).unwrap() +) -> InboundRelayerId<Runtime, MPI> { + Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap() } /// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer, @@ -260,7 +263,7 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, MPI>( ) -> sp_runtime::DispatchOutcome, prepare_message_proof_import: impl FnOnce( Runtime::AccountId, - Runtime::InboundRelayer, + InboundRelayerId<Runtime, MPI>, InteriorLocation, MessageNonce, Xcm<()>, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs index e5d5e7cac96ba14f6abfdae792908352f40d3e31..c61a31e5454ba75429929a0c7b879f6baaa72e15 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs @@ -19,30 +19,29 @@ use crate::test_data::prepare_inbound_xcm; use bp_messages::{ - source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, LaneId, MessageNonce, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneId, MessageNonce, UnrewardedRelayersState, }; -use bp_runtime::{AccountIdOf, BlockNumberOf, HeaderOf, StorageProofSize, UnderlyingChainOf}; +use bp_runtime::{AccountIdOf, BlockNumberOf, Chain, HeaderOf, UnverifiedStorageProofParams}; use bp_test_utils::make_default_justification; -use bridge_runtime_common::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - BridgedChain as MessageBridgedChain, MessageBridge, ThisChain as MessageThisChain, - }, - messages_generation::{ - encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, - prepare_messages_storage_proof, - }, - messages_xcm_extension::XcmAsPlainPayload, -}; +use bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload; use codec::Encode; use pallet_bridge_grandpa::{BridgedChain, BridgedHeader}; use sp_runtime::traits::Header as HeaderT; use xcm::latest::prelude::*; +use crate::test_cases::helpers::InboundRelayerId; use bp_header_chain::{justification::GrandpaJustification, ChainWithGrandpa}; use bp_messages::{DeliveredMessages, InboundLaneData, UnrewardedRelayer}; use bp_runtime::HashOf; +use pallet_bridge_messages::{ + messages_generation::{ + encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, + prepare_messages_storage_proof, + }, + BridgedChainOf, +}; use sp_runtime::DigestItem; /// Prepare a batch call with bridged GRANDPA finality and message proof. @@ -50,22 +49,17 @@ pub fn make_complex_relayer_delivery_batch<Runtime, GPI, MPI>( bridged_header: BridgedHeader<Runtime, GPI>, bridged_justification: GrandpaJustification<BridgedHeader<Runtime, GPI>>, message_proof: FromBridgedChainMessagesProof<HashOf<BridgedChain<Runtime, GPI>>>, - relayer_id_at_bridged_chain: AccountIdOf<BridgedChain<Runtime, GPI>>, + relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>, ) -> pallet_utility::Call<Runtime> where Runtime: pallet_bridge_grandpa::Config<GPI> - + pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = AccountIdOf<BridgedChain<Runtime, GPI>>, - > + pallet_utility::Config, + + pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload> + + pallet_utility::Config, GPI: 'static, MPI: 'static, - <Runtime as pallet_bridge_messages::Config<MPI>>::SourceHeaderChain: SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof<HashOf<BridgedChain<Runtime, GPI>>>, - >, <Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>> + From<pallet_bridge_messages::Call<Runtime, MPI>>, + BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>, { let submit_grandpa = pallet_bridge_grandpa::Call::<Runtime, GPI>::submit_finality_proof { finality_target: Box::new(bridged_header), @@ -73,7 +67,7 @@ where }; let submit_message = pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }; @@ -97,15 +91,9 @@ where + pallet_utility::Config, GPI: 'static, MPI: 'static, - <Runtime as pallet_bridge_messages::Config<MPI>>::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf<BridgedChain<Runtime, GPI>>, - >, - >, <Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>> + From<pallet_bridge_messages::Call<Runtime, MPI>>, + BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>, { let submit_grandpa = pallet_bridge_grandpa::Call::<Runtime, GPI>::submit_finality_proof { finality_target: Box::new(bridged_header), @@ -124,24 +112,18 @@ where /// Prepare a call with message proof. pub fn make_standalone_relayer_delivery_call<Runtime, GPI, MPI>( message_proof: FromBridgedChainMessagesProof<HashOf<BridgedChain<Runtime, GPI>>>, - relayer_id_at_bridged_chain: AccountIdOf<BridgedChain<Runtime, GPI>>, + relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>, ) -> Runtime::RuntimeCall where Runtime: pallet_bridge_grandpa::Config<GPI> - + pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = AccountIdOf<BridgedChain<Runtime, GPI>>, - >, + + pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload>, MPI: 'static, - <Runtime as pallet_bridge_messages::Config<MPI>>::SourceHeaderChain: SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof<HashOf<BridgedChain<Runtime, GPI>>>, - >, Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>, + BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>, { pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof { relayer_id_at_bridged_chain, - proof: message_proof, + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), } @@ -159,14 +141,8 @@ where Runtime: pallet_bridge_grandpa::Config<GPI> + pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>, MPI: 'static, - <Runtime as pallet_bridge_messages::Config<MPI>>::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf<BridgedChain<Runtime, GPI>>, - >, - >, Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>, + BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>, { pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof { proof: message_delivery_proof, @@ -176,39 +152,47 @@ where } /// Prepare storage proofs of messages, stored at the (bridged) source GRANDPA chain. -pub fn make_complex_relayer_delivery_proofs<MB, InnerXcmRuntimeCall>( +pub fn make_complex_relayer_delivery_proofs< + BridgedChain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, xcm_message: Xcm<InnerXcmRuntimeCall>, message_nonce: MessageNonce, message_destination: Junctions, - header_number: BlockNumberOf<MessageBridgedChain<MB>>, + header_number: BlockNumberOf<BridgedChain>, is_minimal_call: bool, ) -> ( - HeaderOf<MessageBridgedChain<MB>>, - GrandpaJustification<HeaderOf<MessageBridgedChain<MB>>>, - FromBridgedChainMessagesProof<HashOf<MessageBridgedChain<MB>>>, + HeaderOf<BridgedChain>, + GrandpaJustification<HeaderOf<BridgedChain>>, + FromBridgedChainMessagesProof<HashOf<BridgedChain>>, ) where - MB: MessageBridge, - MessageBridgedChain<MB>: Send + Sync + 'static, - UnderlyingChainOf<MessageBridgedChain<MB>>: ChainWithGrandpa, + BridgedChain: ChainWithGrandpa, + ThisChainWithMessages: ChainWithMessages, { + // prepare message let message_payload = prepare_inbound_xcm(xcm_message, message_destination); - let message_size = StorageProofSize::Minimal(message_payload.len() as u32); - // prepare para storage proof containing message - let (state_root, storage_proof) = prepare_messages_storage_proof::<MB>( - lane_id, - message_nonce..=message_nonce, - None, - message_size, - message_payload, - encode_all_messages, - encode_lane_data, - ); + // prepare storage proof containing message + let (state_root, storage_proof) = + prepare_messages_storage_proof::<BridgedChain, ThisChainWithMessages>( + lane_id, + message_nonce..=message_nonce, + None, + UnverifiedStorageProofParams::from_db_size(message_payload.len() as u32), + |_| message_payload.clone(), + encode_all_messages, + encode_lane_data, + false, + false, + ); - let (header, justification) = make_complex_bridged_grandpa_header_proof::< - MessageBridgedChain<MB>, - >(state_root, header_number, is_minimal_call); + let (header, justification) = make_complex_bridged_grandpa_header_proof::<BridgedChain>( + state_root, + header_number, + is_minimal_call, + ); let message_proof = FromBridgedChainMessagesProof { bridged_header_hash: header.hash(), @@ -222,44 +206,44 @@ where } /// Prepare storage proofs of message confirmations, stored at the (bridged) target GRANDPA chain. -pub fn make_complex_relayer_confirmation_proofs<MB, InnerXcmRuntimeCall>( +pub fn make_complex_relayer_confirmation_proofs< + BridgedChain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, - header_number: BlockNumberOf<MessageBridgedChain<MB>>, - relayer_id_at_this_chain: AccountIdOf<MessageThisChain<MB>>, + header_number: BlockNumberOf<BridgedChain>, + relayer_id_at_this_chain: AccountIdOf<ThisChainWithMessages>, relayers_state: UnrewardedRelayersState, ) -> ( - HeaderOf<MessageBridgedChain<MB>>, - GrandpaJustification<HeaderOf<MessageBridgedChain<MB>>>, - FromBridgedChainMessagesDeliveryProof<HashOf<MessageBridgedChain<MB>>>, + HeaderOf<BridgedChain>, + GrandpaJustification<HeaderOf<BridgedChain>>, + FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain>>, ) where - MB: MessageBridge, - MessageBridgedChain<MB>: Send + Sync + 'static, - MessageThisChain<MB>: Send + Sync + 'static, - UnderlyingChainOf<MessageBridgedChain<MB>>: ChainWithGrandpa, + BridgedChain: ChainWithGrandpa, + ThisChainWithMessages: ChainWithMessages, { // prepare storage proof containing message delivery proof - let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<MB>( - lane_id, - InboundLaneData { - relayers: vec![ - UnrewardedRelayer { - relayer: relayer_id_at_this_chain, - messages: DeliveredMessages::new(1) - }; - relayers_state.unrewarded_relayer_entries as usize - ] - .into(), - last_confirmed_nonce: 1, - }, - StorageProofSize::Minimal(0), - ); + let (state_root, storage_proof) = + prepare_message_delivery_storage_proof::<BridgedChain, ThisChainWithMessages>( + lane_id, + InboundLaneData { + relayers: vec![ + UnrewardedRelayer { + relayer: relayer_id_at_this_chain, + messages: DeliveredMessages::new(1) + }; + relayers_state.unrewarded_relayer_entries as usize + ] + .into(), + last_confirmed_nonce: 1, + }, + UnverifiedStorageProofParams::default(), + ); - let (header, justification) = make_complex_bridged_grandpa_header_proof::<MB::BridgedChain>( - state_root, - header_number, - false, - ); + let (header, justification) = + make_complex_bridged_grandpa_header_proof::<BridgedChain>(state_root, header_number, false); let message_delivery_proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: header.hash(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs index 5d3cba4e53b5ec7ec9cd2e6141e6e95aa8928970..897fe0d0b0f17729e8bbcd8c941d08ec868ac087 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs @@ -19,61 +19,58 @@ use super::{from_grandpa_chain::make_complex_bridged_grandpa_header_proof, prepare_inbound_xcm}; use bp_messages::{ - source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, LaneId, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneId, UnrewardedRelayersState, Weight, }; use bp_runtime::{ - AccountIdOf, BlockNumberOf, HeaderOf, Parachain, StorageProofSize, UnderlyingChainOf, + AccountIdOf, BlockNumberOf, Chain, HeaderOf, Parachain, UnverifiedStorageProofParams, }; use bp_test_utils::prepare_parachain_heads_proof; -use bridge_runtime_common::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - BridgedChain as MessageBridgedChain, MessageBridge, ThisChain as MessageThisChain, - }, - messages_generation::{ - encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, - prepare_messages_storage_proof, - }, - messages_xcm_extension::XcmAsPlainPayload, -}; +use bridge_runtime_common::messages_xcm_extension::XcmAsPlainPayload; use codec::Encode; use pallet_bridge_grandpa::BridgedHeader; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockNumber}; use sp_runtime::traits::Header as HeaderT; use xcm::latest::prelude::*; +use crate::test_cases::helpers::InboundRelayerId; use bp_header_chain::{justification::GrandpaJustification, ChainWithGrandpa}; use bp_messages::{DeliveredMessages, InboundLaneData, MessageNonce, UnrewardedRelayer}; use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId}; +use pallet_bridge_messages::{ + messages_generation::{ + encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, + prepare_messages_storage_proof, + }, + BridgedChainOf, +}; use sp_runtime::SaturatedConversion; /// Prepare a batch call with relay finality proof, parachain head proof and message proof. -pub fn make_complex_relayer_delivery_batch<Runtime, GPI, PPI, MPI, InboundRelayer>( +pub fn make_complex_relayer_delivery_batch<Runtime, GPI, PPI, MPI>( relay_chain_header: BridgedHeader<Runtime, GPI>, grandpa_justification: GrandpaJustification<BridgedHeader<Runtime, GPI>>, parachain_heads: Vec<(ParaId, ParaHash)>, para_heads_proof: ParaHeadsProof, message_proof: FromBridgedChainMessagesProof<ParaHash>, - relayer_id_at_bridged_chain: InboundRelayer, -) -> pallet_utility::Call<Runtime> where - Runtime:pallet_bridge_grandpa::Config<GPI> + relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>, +) -> pallet_utility::Call<Runtime> +where + Runtime: pallet_bridge_grandpa::Config<GPI> + pallet_bridge_parachains::Config<PPI> - + pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = InboundRelayer, - > + + pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload> + pallet_utility::Config, GPI: 'static, PPI: 'static, MPI: 'static, - ParaHash: From<<<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash>, - <<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash: From<ParaHash>, - <<Runtime as pallet_bridge_messages::Config<MPI>>::SourceHeaderChain as SourceHeaderChain>::MessagesProof: - From<FromBridgedChainMessagesProof<ParaHash>>, - <Runtime as pallet_utility::Config>::RuntimeCall: - From<pallet_bridge_grandpa::Call<Runtime, GPI>> + ParaHash: From< + <<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash, + >, + <<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash: + From<ParaHash>, + BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain, + <Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>> + From<pallet_bridge_parachains::Call<Runtime, PPI>> + From<pallet_bridge_messages::Call<Runtime, MPI>>, { @@ -93,7 +90,7 @@ pub fn make_complex_relayer_delivery_batch<Runtime, GPI, PPI, MPI, InboundRelaye }; let submit_message = pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_bridged_chain.into(), - proof: message_proof.into(), + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), }; @@ -122,11 +119,7 @@ where MPI: 'static, <Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - <Runtime as pallet_bridge_messages::Config<MPI>>::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<ParaHash>, - >, + BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain, <Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>> + From<pallet_bridge_parachains::Call<Runtime, PPI>> + From<pallet_bridge_messages::Call<Runtime, MPI>>, @@ -160,23 +153,19 @@ where } /// Prepare a call with message proof. -pub fn make_standalone_relayer_delivery_call<Runtime, MPI, InboundRelayer>( +pub fn make_standalone_relayer_delivery_call<Runtime, MPI>( message_proof: FromBridgedChainMessagesProof<ParaHash>, - relayer_id_at_bridged_chain: InboundRelayer, -) -> Runtime::RuntimeCall where - Runtime: pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = InboundRelayer, - >, + relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>, +) -> Runtime::RuntimeCall +where + Runtime: pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload>, MPI: 'static, - Runtime::RuntimeCall: From<pallet_bridge_messages::Call::<Runtime, MPI>>, - <<Runtime as pallet_bridge_messages::Config<MPI>>::SourceHeaderChain as SourceHeaderChain>::MessagesProof: - From<FromBridgedChainMessagesProof<ParaHash>>, + Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>, + BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain, { pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_bridged_chain.into(), - proof: message_proof.into(), + proof: Box::new(message_proof), messages_count: 1, dispatch_weight: Weight::from_parts(1000000000, 0), } @@ -192,11 +181,7 @@ where Runtime: pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>, MPI: 'static, Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>, - <Runtime as pallet_bridge_messages::Config<MPI>>::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<ParaHash>, - >, + BridgedChainOf<Runtime, MPI>: Chain<Hash = ParaHash> + Parachain, { pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof { proof: message_delivery_proof, @@ -206,7 +191,12 @@ where } /// Prepare storage proofs of messages, stored at the source chain. -pub fn make_complex_relayer_delivery_proofs<BridgedRelayChain, MB, InnerXcmRuntimeCall>( +pub fn make_complex_relayer_delivery_proofs< + BridgedRelayChain, + BridgedParachain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, xcm_message: Xcm<InnerXcmRuntimeCall>, message_nonce: MessageNonce, @@ -226,24 +216,27 @@ pub fn make_complex_relayer_delivery_proofs<BridgedRelayChain, MB, InnerXcmRunti where BridgedRelayChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - MB: MessageBridge, - UnderlyingChainOf<MessageBridgedChain<MB>>: bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedParachain: bp_runtime::Chain<Hash = ParaHash> + Parachain, + ThisChainWithMessages: ChainWithMessages, { + // prepare message let message_payload = prepare_inbound_xcm(xcm_message, message_destination); - let message_size = StorageProofSize::Minimal(message_payload.len() as u32); // prepare para storage proof containing message - let (para_state_root, para_storage_proof) = prepare_messages_storage_proof::<MB>( - lane_id, - message_nonce..=message_nonce, - None, - message_size, - message_payload, - encode_all_messages, - encode_lane_data, - ); + let (para_state_root, para_storage_proof) = + prepare_messages_storage_proof::<BridgedParachain, ThisChainWithMessages>( + lane_id, + message_nonce..=message_nonce, + None, + UnverifiedStorageProofParams::from_db_size(message_payload.len() as u32), + |_| message_payload.clone(), + encode_all_messages, + encode_lane_data, + false, + false, + ); let (relay_chain_header, justification, bridged_para_head, parachain_heads, para_heads_proof) = - make_complex_bridged_parachain_heads_proof::<BridgedRelayChain, MB>( + make_complex_bridged_parachain_heads_proof::<BridgedRelayChain, BridgedParachain>( para_state_root, para_header_number, relay_header_number, @@ -270,12 +263,17 @@ where } /// Prepare storage proofs of message confirmations, stored at the target parachain. -pub fn make_complex_relayer_confirmation_proofs<BridgedRelayChain, MB, InnerXcmRuntimeCall>( +pub fn make_complex_relayer_confirmation_proofs< + BridgedRelayChain, + BridgedParachain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, para_header_number: u32, relay_header_number: u32, bridged_para_id: u32, - relayer_id_at_this_chain: AccountIdOf<MessageThisChain<MB>>, + relayer_id_at_this_chain: AccountIdOf<ThisChainWithMessages>, relayers_state: UnrewardedRelayersState, ) -> ( HeaderOf<BridgedRelayChain>, @@ -288,28 +286,29 @@ pub fn make_complex_relayer_confirmation_proofs<BridgedRelayChain, MB, InnerXcmR where BridgedRelayChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - MB: MessageBridge, - UnderlyingChainOf<MessageBridgedChain<MB>>: bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedParachain: bp_runtime::Chain<Hash = ParaHash> + Parachain, + ThisChainWithMessages: ChainWithMessages, { // prepare para storage proof containing message delivery proof - let (para_state_root, para_storage_proof) = prepare_message_delivery_storage_proof::<MB>( - lane_id, - InboundLaneData { - relayers: vec![ - UnrewardedRelayer { - relayer: relayer_id_at_this_chain.into(), - messages: DeliveredMessages::new(1) - }; - relayers_state.unrewarded_relayer_entries as usize - ] - .into(), - last_confirmed_nonce: 1, - }, - StorageProofSize::Minimal(0), - ); + let (para_state_root, para_storage_proof) = + prepare_message_delivery_storage_proof::<BridgedParachain, ThisChainWithMessages>( + lane_id, + InboundLaneData { + relayers: vec![ + UnrewardedRelayer { + relayer: relayer_id_at_this_chain.into(), + messages: DeliveredMessages::new(1) + }; + relayers_state.unrewarded_relayer_entries as usize + ] + .into(), + last_confirmed_nonce: 1, + }, + UnverifiedStorageProofParams::default(), + ); let (relay_chain_header, justification, bridged_para_head, parachain_heads, para_heads_proof) = - make_complex_bridged_parachain_heads_proof::<BridgedRelayChain, MB>( + make_complex_bridged_parachain_heads_proof::<BridgedRelayChain, BridgedParachain>( para_state_root, para_header_number, relay_header_number, @@ -334,7 +333,7 @@ where } /// Make bridged parachain header with given state root and relay header that is finalizing it. -pub fn make_complex_bridged_parachain_heads_proof<BridgedRelayChain, MB>( +pub fn make_complex_bridged_parachain_heads_proof<BridgedRelayChain, BridgedParachain>( para_state_root: ParaHash, para_header_number: u32, relay_header_number: BlockNumberOf<BridgedRelayChain>, @@ -350,20 +349,17 @@ pub fn make_complex_bridged_parachain_heads_proof<BridgedRelayChain, MB>( where BridgedRelayChain: bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa, - MB: MessageBridge, - <MB as MessageBridge>::BridgedChain: Send + Sync + 'static, - <MB as MessageBridge>::ThisChain: Send + Sync + 'static, - UnderlyingChainOf<MessageBridgedChain<MB>>: bp_runtime::Chain<Hash = ParaHash> + Parachain, + BridgedParachain: bp_runtime::Chain<Hash = ParaHash> + Parachain, { let bridged_para_head = ParaHead( - bp_test_utils::test_header_with_root::<HeaderOf<MB::BridgedChain>>( + bp_test_utils::test_header_with_root::<HeaderOf<BridgedParachain>>( para_header_number.into(), para_state_root, ) .encode(), ); let (relay_state_root, para_heads_proof, parachain_heads) = - prepare_parachain_heads_proof::<HeaderOf<MB::BridgedChain>>(vec![( + prepare_parachain_heads_proof::<HeaderOf<BridgedParachain>>(vec![( bridged_para_id, bridged_para_head.clone(), )]); diff --git a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile index e17952ccee804d5ff82339c1770f96f28c1cdab8..634b9f1882917bbb0f776893242344fe9977b0ef 100644 --- a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile +++ b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile @@ -1,7 +1,7 @@ # this image is built on top of existing Zombienet image ARG ZOMBIENET_IMAGE # this image uses substrate-relay image built elsewhere -ARG SUBSTRATE_RELAY_IMAGE=docker.io/paritytech/substrate-relay:v1.6.4 +ARG SUBSTRATE_RELAY_IMAGE=docker.io/paritytech/substrate-relay:v1.6.5 # metadata ARG VCS_REF diff --git a/prdoc/pr_4935.prdoc b/prdoc/pr_4935.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..2b06899b63398353209eb38ad5410e24fc3e4f6d --- /dev/null +++ b/prdoc/pr_4935.prdoc @@ -0,0 +1,75 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Bridges V2 refactoring backport and `pallet_bridge_messages` simplifications" + +doc: + - audience: Runtime Dev + description: | + This introduces several simplifications to the pallet_bridge_messages::Config configuration. + Types like `BridgedChainId`, `MaxUnrewardedRelayerEntriesAtInboundLane`, `MaxUnconfirmedMessagesAtInboundLane`, `MaximalOutboundPayloadSize`, + `InboundRelayer`, `TargetHeaderChain`, and `SourceHeaderChain` were removed. + Now, you only need to provide specific bridging chain configurations for `ThisChain`, `BridgedChain`, and `BridgedHeaderChain`. + + If you previously specified implementations for the bp_runtime::Chain* traits, those will fit here exactly, for example: + ``` + type ThisChain = bp_bridge_hub_rococo::BridgeHubRococo; + type BridgedChain = bp_bridge_hub_westend::BridgeHubWestend; + type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< + Runtime, + BridgeParachainWestendInstance, + bp_bridge_hub_westend::BridgeHubWestend, + >; + ``` + +crates: + - name: pallet-bridge-messages + bump: major + - name: bridge-runtime-common + bump: major + - name: bp-header-chain + bump: major + - name: bp-runtime + bump: major + - name: bp-messages + bump: major + - name: bp-polkadot-core + bump: patch + - name: bp-bridge-hub-kusama + bump: minor + - name: bp-bridge-hub-polkadot + bump: minor + - name: bp-bridge-hub-rococo + bump: minor + - name: bp-bridge-hub-westend + bump: minor + - name: bp-kusama + bump: minor + - name: bp-polkadot + bump: minor + - name: bp-polkadot-bulletin + bump: minor + - name: bp-rococo + bump: minor + - name: bp-test-utils + bump: patch + - name: bp-westend + bump: minor + - name: bridge-hub-test-utils + bump: major + - name: pallet-bridge-grandpa + bump: patch + - name: pallet-bridge-parachains + bump: patch + - name: pallet-bridge-relayers + bump: patch + - name: pallet-xcm-bridge-hub + bump: patch + - name: asset-hub-rococo-runtime + bump: patch + - name: asset-hub-westend-runtime + bump: patch + - name: bridge-hub-rococo-runtime + bump: major + - name: bridge-hub-westend-runtime + bump: major