From bc0f814f7ffddddd31b0f5aafafb9e3055c15ab0 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Tue, 30 May 2023 14:19:25 +0300 Subject: [PATCH 01/58] Use compact proofs for messages delivery (#2155) * Define Chain::STATE_VERSION * Add vec_db module * Use VecDb instead of StorageProof for message delivery * Make sure that the TrustedVecDb is sorted * Address review comments * Run benchmarks on parent commit * Run benchmarks with new code * Fix test * Fix code review comments --- .../extensions/refund_relayer_extension.rs | 2 +- bridges/bin/runtime-common/src/messages.rs | 225 +++++++----- .../src/messages_benchmarking.rs | 12 +- .../runtime-common/src/messages_call_ext.rs | 2 +- .../runtime-common/src/messages_generation.rs | 90 ++++- bridges/bin/runtime-common/src/mock.rs | 8 +- .../chains/chain-bridge-hub-kusama/src/lib.rs | 4 +- .../chain-bridge-hub-polkadot/src/lib.rs | 4 +- .../chains/chain-bridge-hub-rococo/src/lib.rs | 8 +- .../chain-bridge-hub-westend/src/lib.rs | 4 +- bridges/chains/chain-kusama/src/lib.rs | 4 +- .../chains/chain-polkadot-bulletin/src/lib.rs | 6 +- bridges/chains/chain-polkadot/src/lib.rs | 4 +- bridges/chains/chain-rococo/src/lib.rs | 4 +- bridges/chains/chain-westend/src/lib.rs | 4 +- bridges/modules/beefy/src/mock.rs | 3 + bridges/modules/grandpa/src/mock.rs | 5 +- bridges/modules/messages/src/weights.rs | 156 ++++---- bridges/modules/parachains/src/mock.rs | 14 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 6 +- bridges/primitives/header-chain/src/lib.rs | 21 +- bridges/primitives/messages/src/lib.rs | 12 +- bridges/primitives/runtime/src/chain.rs | 8 +- bridges/primitives/runtime/src/lib.rs | 2 + bridges/primitives/runtime/src/vec_db.rs | 332 ++++++++++++++++++ .../relays/client-substrate/src/test_chain.rs | 6 +- .../lib-substrate-relay/src/messages_lane.rs | 8 +- .../src/messages_source.rs | 30 +- 28 files changed, 762 insertions(+), 222 deletions(-) create mode 100644 bridges/primitives/runtime/src/vec_db.rs 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 5aa7f1c095d5..aab3280a3493 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -1146,7 +1146,7 @@ pub(crate) mod tests { relayer_id_at_bridged_chain: relayer_account_at_bridged_chain(), proof: FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage_proof: vec![], + storage: Default::default(), lane: TestLaneId::get(), nonces_start: pallet_bridge_messages::InboundLanes::::get( TEST_LANE_ID, diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index 0fe9935dbdb6..b86ab45fdeea 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -20,8 +20,6 @@ //! 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, @@ -29,10 +27,12 @@ use bp_messages::{ InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, }; -use bp_runtime::{Chain, RawStorageProof, Size, StorageProofChecker}; +pub use bp_runtime::{ + Chain, RangeInclusiveExt, RawStorageProof, Size, TrustedVecDb, UnderlyingChainOf, + UnderlyingChainProvider, UntrustedVecDb, +}; 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}; @@ -226,8 +226,8 @@ pub mod target { pub struct FromBridgedChainMessagesProof { /// 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, + /// The proved storage containing the messages being delivered. + pub storage: UntrustedVecDb, /// Messages in this proof are sent over this lane. pub lane: LaneId, /// Nonce of the first message being delivered. @@ -238,12 +238,7 @@ pub mod target { impl Size for FromBridgedChainMessagesProof { fn size(&self) -> u32 { - u32::try_from( - self.storage_proof - .iter() - .fold(0usize, |sum, node| sum.saturating_add(node.len())), - ) - .unwrap_or(u32::MAX) + self.storage.size() } } @@ -285,15 +280,14 @@ pub mod target { ) -> Result, VerificationError> { let FromBridgedChainMessagesProof { bridged_header_hash, - storage_proof, + storage, 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 storage = B::BridgedHeaderChain::verify_vec_db_storage(bridged_header_hash, storage) + .map_err(VerificationError::HeaderChain)?; + let mut parser = StorageAdapter:: { storage, _dummy: Default::default() }; let nonces_range = nonces_start..=nonces_end; // receiving proofs where end < begin is ok (if proof includes outbound lane state) @@ -325,11 +319,8 @@ pub mod target { 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)?; + // Check that the `VecDb` doesn't have any untouched keys. + parser.storage.ensure_no_unused_keys().map_err(VerificationError::VecDb)?; // We only support single lane messages in this generated_schema let mut proved_messages = ProvedMessages::new(); @@ -338,12 +329,12 @@ pub mod target { Ok(proved_messages) } - struct StorageProofCheckerAdapter { - storage: StorageProofChecker, + struct StorageAdapter { + storage: TrustedVecDb, _dummy: sp_std::marker::PhantomData, } - impl StorageProofCheckerAdapter { + impl StorageAdapter { fn read_and_decode_outbound_lane_data( &mut self, lane_id: &LaneId, @@ -354,7 +345,7 @@ pub mod target { ); self.storage - .read_and_decode_opt_value(storage_outbound_lane_data_key.0.as_ref()) + .get_and_decode_optional(&storage_outbound_lane_data_key) .map_err(VerificationError::OutboundLaneStorage) } @@ -368,7 +359,7 @@ pub mod target { message_key.nonce, ); self.storage - .read_and_decode_mandatory_value(storage_message_key.0.as_ref()) + .get_and_decode_mandatory(&storage_message_key) .map_err(VerificationError::MessageStorage) } } @@ -391,7 +382,7 @@ mod tests { mock::*, }; use bp_header_chain::{HeaderChainError, StoredHeaderDataBuilder}; - use bp_runtime::{HeaderId, StorageProofError}; + use bp_runtime::{HeaderId, VecDbError}; use codec::Encode; use sp_core::H256; use sp_runtime::traits::Header as _; @@ -433,9 +424,11 @@ mod tests { outbound_lane_data: Option, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, + add_duplicate_key: bool, + add_unused_key: bool, test: impl Fn(target::FromBridgedChainMessagesProof) -> R, ) -> R { - let (state_root, storage_proof) = prepare_messages_storage_proof::( + let (state_root, storage) = prepare_messages_storage_proof::( TEST_LANE_ID, 1..=nonces_end, outbound_lane_data, @@ -443,6 +436,8 @@ mod tests { vec![42], encode_message, encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, ); sp_io::TestExternalities::new(Default::default()).execute_with(move || { @@ -465,7 +460,7 @@ mod tests { ); test(target::FromBridgedChainMessagesProof { bridged_header_hash, - storage_proof, + storage, lane: TEST_LANE_ID, nonces_start: 1, nonces_end, @@ -476,9 +471,15 @@ mod tests { #[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::(proof, 5) - }), + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { target::verify_messages_proof::(proof, 5) } + ), Err(VerificationError::MessagesCountMismatch), ); } @@ -486,9 +487,15 @@ mod tests { #[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::(proof, 15) - }), + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { target::verify_messages_proof::(proof, 15) } + ), Err(VerificationError::MessagesCountMismatch), ); } @@ -496,12 +503,22 @@ mod tests { #[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::::get().unwrap().1; - pallet_bridge_grandpa::ImportedHeaders::::remove(bridged_header_hash); - target::verify_messages_proof::(proof, 10) - }), + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { + let bridged_header_hash = + pallet_bridge_grandpa::BestFinalized::::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::::remove( + bridged_header_hash, + ); + target::verify_messages_proof::(proof, 10) + } + ), Err(VerificationError::HeaderChain(HeaderChainError::UnknownHeader)), ); } @@ -509,51 +526,63 @@ mod tests { #[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::::get().unwrap().1; - pallet_bridge_grandpa::ImportedHeaders::::insert( - bridged_header_hash, - BridgedChainHeader::new( - 0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ) - .build(), - ); - target::verify_messages_proof::(proof, 10) - }), - Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( - StorageProofError::StorageRootMismatch - ))), + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { + let bridged_header_hash = + pallet_bridge_grandpa::BestFinalized::::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::::insert( + bridged_header_hash, + BridgedChainHeader::new( + 0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ) + .build(), + ); + target::verify_messages_proof::(proof, 10) + } + ), + Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), ); } #[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::(proof, 10) - },), - Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( - StorageProofError::DuplicateNodesInProof - ))), + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + true, + false, + |proof| { target::verify_messages_proof::(proof, 10) }, + ), + Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), ); } #[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::(proof, 10) - },), - Err(VerificationError::StorageProof(StorageProofError::UnusedNodesInTheProof)), + using_messages_proof( + 10, + None, + encode_all_messages, + encode_lane_data, + false, + true, + |proof| { target::verify_messages_proof::(proof, 10) }, + ), + Err(VerificationError::VecDb(VecDbError::UnusedKey)), ); } @@ -565,9 +594,11 @@ mod tests { None, |n, m| if n != 5 { Some(m.encode()) } else { None }, encode_lane_data, + false, + false, |proof| target::verify_messages_proof::(proof, 10) ), - Err(VerificationError::MessageStorage(StorageProofError::StorageValueEmpty)), + Err(VerificationError::MessageStorage(VecDbError::EmptyVal)), ); } @@ -585,9 +616,11 @@ mod tests { Some(m) }, encode_lane_data, + false, + false, |proof| target::verify_messages_proof::(proof, 10), ), - Err(VerificationError::MessageStorage(StorageProofError::StorageValueDecodeFailed(_))), + Err(VerificationError::MessageStorage(VecDbError::DecodeError)), ); } @@ -607,20 +640,26 @@ mod tests { d.truncate(1); d }, + false, + false, |proof| target::verify_messages_proof::(proof, 10), ), - Err(VerificationError::OutboundLaneStorage( - StorageProofError::StorageValueDecodeFailed(_) - )), + Err(VerificationError::OutboundLaneStorage(VecDbError::DecodeError)), ); } #[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::(proof, 0) - },), + using_messages_proof( + 0, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |proof| { target::verify_messages_proof::(proof, 0) }, + ), Err(VerificationError::EmptyMessageProof), ); } @@ -637,6 +676,8 @@ mod tests { }), encode_all_messages, encode_lane_data, + false, + false, |proof| target::verify_messages_proof::(proof, 0), ), Ok(vec![( @@ -667,6 +708,8 @@ mod tests { }), encode_all_messages, encode_lane_data, + false, + false, |proof| target::verify_messages_proof::(proof, 1), ), Ok(vec![( @@ -691,10 +734,18 @@ mod tests { #[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::(proof, u32::MAX) - },), + using_messages_proof( + 1, + None, + encode_all_messages, + encode_lane_data, + false, + false, + |mut proof| { + proof.nonces_end = u64::MAX; + target::verify_messages_proof::(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 74494f790804..5d92e9e68711 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -85,7 +85,7 @@ where B: MessageBridge, { // prepare storage proof - let (state_root, storage_proof) = prepare_messages_storage_proof::( + let (state_root, storage) = prepare_messages_storage_proof::( params.lane, params.message_nonces.clone(), params.outbound_lane_data.clone(), @@ -93,6 +93,8 @@ where prepare_inbound_message(¶ms, message_generator), encode_all_messages, encode_lane_data, + false, + false, ); // update runtime storage @@ -101,7 +103,7 @@ where ( FromBridgedChainMessagesProof { bridged_header_hash, - storage_proof, + storage, lane: params.lane, nonces_start: *params.message_nonces.start(), nonces_end: *params.message_nonces.end(), @@ -129,7 +131,7 @@ where UnderlyingChainOf>: Chain + Parachain, { // prepare storage proof - let (state_root, storage_proof) = prepare_messages_storage_proof::( + let (state_root, storage) = prepare_messages_storage_proof::( params.lane, params.message_nonces.clone(), params.outbound_lane_data.clone(), @@ -137,6 +139,8 @@ where prepare_inbound_message(¶ms, message_generator), encode_all_messages, encode_lane_data, + false, + false, ); // update runtime storage @@ -146,7 +150,7 @@ where ( FromBridgedChainMessagesProof { bridged_header_hash, - storage_proof, + storage, lane: params.lane, nonces_start: *params.message_nonces.start(), nonces_end: *params.message_nonces.end(), diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index fb07f7b6dd69..a29e9b80a50d 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -420,7 +420,7 @@ mod tests { dispatch_weight: frame_support::weights::Weight::zero(), proof: FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage_proof: vec![], + storage: Default::default(), lane: LaneId([0, 0, 0, 0]), nonces_start, nonces_end, diff --git a/bridges/bin/runtime-common/src/messages_generation.rs b/bridges/bin/runtime-common/src/messages_generation.rs index c37aaa5d4d53..be7c0458d09a 100644 --- a/bridges/bin/runtime-common/src/messages_generation.rs +++ b/bridges/bin/runtime-common/src/messages_generation.rs @@ -22,10 +22,17 @@ use bp_messages::{ storage_keys, InboundLaneData, LaneId, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, }; -use bp_runtime::{record_all_trie_keys, RawStorageProof, StorageProofSize}; +use bp_runtime::{ + record_all_trie_keys, Chain, RawStorageProof, StorageProofSize, UnderlyingChainOf, + UntrustedVecDb, +}; use codec::Encode; +use frame_support::sp_runtime::StateVersion; use sp_std::{ops::RangeInclusive, prelude::*}; -use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; +use sp_trie::{ + trie_types::TrieDBMutBuilderV1, LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, + TrieDBMutBuilder, TrieMut, +}; /// Simple and correct message data encode function. pub fn encode_all_messages(_: MessageNonce, m: &MessagePayload) -> Option> { @@ -40,6 +47,7 @@ pub fn encode_lane_data(d: &OutboundLaneData) -> Vec { /// Prepare storage proof of given messages. /// /// Returns state trie root and nodes with prepared messages. +#[allow(clippy::too_many_arguments)] pub fn prepare_messages_storage_proof( lane: LaneId, message_nonces: RangeInclusive, @@ -48,10 +56,60 @@ pub fn prepare_messages_storage_proof( message_payload: MessagePayload, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, -) -> (HashOf>, RawStorageProof) + add_duplicate_key: bool, + add_unused_key: bool, +) -> (HashOf>, UntrustedVecDb) where B: MessageBridge, HashOf>: Copy + Default, +{ + match >>::STATE_VERSION { + StateVersion::V0 => + do_prepare_messages_storage_proof::>>>( + lane, + message_nonces, + outbound_lane_data, + size, + message_payload, + encode_message, + encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, + ), + StateVersion::V1 => + do_prepare_messages_storage_proof::>>>( + lane, + message_nonces, + outbound_lane_data, + size, + message_payload, + encode_message, + encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, + ), + } +} + +/// Prepare storage proof of given messages. +/// +/// Returns state trie root and nodes with prepared messages. +#[allow(clippy::too_many_arguments)] +pub fn do_prepare_messages_storage_proof( + lane: LaneId, + message_nonces: RangeInclusive, + outbound_lane_data: Option, + size: StorageProofSize, + message_payload: MessagePayload, + encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, + encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, + add_duplicate_key: bool, + add_unused_key: bool, +) -> (HashOf>, UntrustedVecDb) +where + B: MessageBridge, + L: TrieConfiguration>>, + HashOf>: 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; @@ -59,8 +117,7 @@ where let mut root = Default::default(); let mut mdb = MemoryDB::default(); { - let mut trie = - TrieDBMutBuilderV1::>>::new(&mut mdb, &mut root).build(); + let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut root).build(); // insert messages for (i, nonce) in message_nonces.into_iter().enumerate() { @@ -96,13 +153,32 @@ where .expect("TrieMut::insert should not fail in benchmarks"); storage_keys.push(storage_key); } + + if add_duplicate_key { + let duplicate_key = storage_keys.last().unwrap().clone(); + storage_keys.push(duplicate_key); + } + + if add_unused_key { + let storage_key = b"unused_key".to_vec(); + trie.insert(&storage_key, b"unused_value") + .map_err(|_| "TrieMut::insert has failed") + .expect("TrieMut::insert should not fail in benchmarks"); + storage_keys.push(storage_key); + } } // generate storage proof to be delivered to This chain - let storage_proof = record_all_trie_keys::>>, _>(&mdb, &root) + let read_proof = record_all_trie_keys::(&mdb, &root) .map_err(|_| "record_all_trie_keys has failed") .expect("record_all_trie_keys should not fail in benchmarks"); - (root, storage_proof) + let storage = UntrustedVecDb::try_new::>>( + StorageProof::new(read_proof), + root, + storage_keys, + ) + .unwrap(); + (root, storage) } /// Prepare storage proof of given messages delivery. diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index f49474667896..f287aea8de6b 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -46,7 +46,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`. @@ -326,6 +326,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 } @@ -368,6 +370,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 } @@ -396,6 +400,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 } diff --git a/bridges/chains/chain-bridge-hub-kusama/src/lib.rs b/bridges/chains/chain-bridge-hub-kusama/src/lib.rs index ef3ef4ab7b7a..c990e8a12f36 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 9db71af928e5..7379b8863b1d 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 d7097f01c531..b37a61f7de5c 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) } diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index 800f290d7bfa..17ff2c858a1d 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 fd7172c5869d..dcd0b23abbbe 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 f3d300567f2b..88980a957501 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 a8cac0467d57..f4b262d40735 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 b290fe71c829..bfcafdf41ea2 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 ef451f7de0a9..2a247e03e59d 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 53efd57c29a0..3b751ddf066c 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/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index 27df9d9c78f5..71af6182e057 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/src/weights.rs b/bridges/modules/messages/src/weights.rs index 5bf7d5675607..51152b83d9bc 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-05-26, 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: @@ -82,10 +82,10 @@ impl WeightInfo for BridgeWeight { /// 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: `428` + // Estimated: `52645` + // Minimum execution time: 34_049 nanoseconds. + Weight::from_parts(39_460_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -105,10 +105,10 @@ impl WeightInfo for BridgeWeight { /// 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) + // Measured: `428` + // Estimated: `52645` + // Minimum execution time: 44_030 nanoseconds. + Weight::from_parts(48_036_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -128,10 +128,10 @@ impl WeightInfo for BridgeWeight { /// 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: `428` + // Estimated: `52645` + // Minimum execution time: 42_839 nanoseconds. + Weight::from_parts(45_052_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -151,10 +151,10 @@ impl WeightInfo for BridgeWeight { /// 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) + // Measured: `428` + // Estimated: `52645` + // Minimum execution time: 33_925 nanoseconds. + Weight::from_parts(36_321_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -174,10 +174,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_16_kb() -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 78_269 nanoseconds. - Weight::from_parts(81_748_000, 57170) + // Measured: `428` + // Estimated: `52645` + // Minimum execution time: 50_591 nanoseconds. + Weight::from_parts(56_245_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -202,10 +202,10 @@ impl WeightInfo for BridgeWeight { /// 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: `453` + // Estimated: `3530` + // Minimum execution time: 33_199 nanoseconds. + Weight::from_parts(34_349_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -230,10 +230,10 @@ impl WeightInfo for BridgeWeight { /// 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: `470` + // Estimated: `3530` + // Minimum execution time: 32_221 nanoseconds. + Weight::from_parts(33_944_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -258,10 +258,10 @@ impl WeightInfo for BridgeWeight { /// 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: `470` + // Estimated: `6070` + // Minimum execution time: 34_880 nanoseconds. + Weight::from_parts(36_087_000, 6070) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -283,12 +283,12 @@ impl WeightInfo for BridgeWeight { /// The range of component `i` is `[128, 2048]`. fn receive_single_message_proof_with_dispatch(i: 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: `428` + // Estimated: `52645` + // Minimum execution time: 73_740 nanoseconds. + Weight::from_parts(74_788_229, 52645) + // Standard Error: 1_392 + .saturating_add(Weight::from_parts(302_332, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -312,10 +312,10 @@ 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: `428` + // Estimated: `52645` + // Minimum execution time: 34_049 nanoseconds. + Weight::from_parts(39_460_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -335,10 +335,10 @@ impl WeightInfo for () { /// 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) + // Measured: `428` + // Estimated: `52645` + // Minimum execution time: 44_030 nanoseconds. + Weight::from_parts(48_036_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -358,10 +358,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: `428` + // Estimated: `52645` + // Minimum execution time: 42_839 nanoseconds. + Weight::from_parts(45_052_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -381,10 +381,10 @@ impl WeightInfo for () { /// 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) + // Measured: `428` + // Estimated: `52645` + // Minimum execution time: 33_925 nanoseconds. + Weight::from_parts(36_321_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -404,10 +404,10 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_16_kb() -> Weight { // Proof Size summary in bytes: - // Measured: `618` - // Estimated: `57170` - // Minimum execution time: 78_269 nanoseconds. - Weight::from_parts(81_748_000, 57170) + // Measured: `428` + // Estimated: `52645` + // Minimum execution time: 50_591 nanoseconds. + Weight::from_parts(56_245_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -432,10 +432,10 @@ impl WeightInfo for () { /// 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: `453` + // Estimated: `3530` + // Minimum execution time: 33_199 nanoseconds. + Weight::from_parts(34_349_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -460,10 +460,10 @@ impl WeightInfo for () { /// 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: `470` + // Estimated: `3530` + // Minimum execution time: 32_221 nanoseconds. + Weight::from_parts(33_944_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -488,10 +488,10 @@ impl WeightInfo for () { /// 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: `470` + // Estimated: `6070` + // Minimum execution time: 34_880 nanoseconds. + Weight::from_parts(36_087_000, 6070) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -513,12 +513,12 @@ impl WeightInfo for () { /// The range of component `i` is `[128, 2048]`. fn receive_single_message_proof_with_dispatch(i: 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: `428` + // Estimated: `52645` + // Minimum execution time: 73_740 nanoseconds. + Weight::from_parts(74_788_229, 52645) + // Standard Error: 1_392 + .saturating_add(Weight::from_parts(302_332, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index dbb62845392d..d5fdf37e36fd 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 } @@ -256,6 +264,8 @@ impl Chain for TestBridgedChain { type Nonce = u32; type Signature = sp_runtime::testing::TestSignature; + const STATE_VERSION: StateVersion = StateVersion::V1; + fn max_extrinsic_size() -> u32 { unreachable!() } @@ -289,6 +299,8 @@ impl Chain for OtherBridgedChain { 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/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 4c09bce56d73..fb47fc694392 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -36,7 +36,7 @@ use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, traits::{BlakeTwo256, IdentityLookup}, - AccountId32, BuildStorage, + AccountId32, BuildStorage, StateVersion, }; use xcm::prelude::*; @@ -211,6 +211,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 } @@ -235,6 +237,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 } diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index af2afb65a26a..22b70d40c1d5 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -25,7 +25,8 @@ use crate::justification::{ }; use bp_runtime::{ BasicOperatingMode, BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, RawStorageProof, - StorageProofChecker, StorageProofError, UnderlyingChainProvider, + StorageProofChecker, StorageProofError, TrustedVecDb, UnderlyingChainProvider, UntrustedVecDb, + VecDbError, }; use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug}; @@ -48,6 +49,8 @@ pub enum HeaderChainError { UnknownHeader, /// Storage proof related error. StorageProof(StorageProofError), + /// Error generated by the `vec_db` module. + VecDb(VecDbError), } /// Header data that we're storing on-chain. @@ -78,6 +81,16 @@ impl StoredHeaderDataBuilder for H { pub trait HeaderChain { /// Returns state (storage) root of given finalized header. fn finalized_header_state_root(header_hash: HashOf) -> Option>; + /// Get a `TrustedVecDb` starting from an `UntrustedVecDb`. + fn verify_vec_db_storage( + header_hash: HashOf, + db: UntrustedVecDb, + ) -> Result { + let state_root = Self::finalized_header_state_root(header_hash) + .ok_or(HeaderChainError::UnknownHeader)?; + db.verify::>(C::STATE_VERSION, &state_root) + .map_err(HeaderChainError::VecDb) + } /// Get storage proof checker using finalized header. fn storage_proof_checker( header_hash: HashOf, @@ -409,7 +422,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 +440,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 c3f79b3ee388..6914b42b6596 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -22,7 +22,7 @@ use bp_header_chain::HeaderChainError; use bp_runtime::{ messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt, - StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, + StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, VecDbError, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::PalletError; @@ -486,14 +486,16 @@ pub enum VerificationError { InvalidMessageWeight, /// Declared messages count doesn't match actual value. MessagesCountMismatch, - /// Error returned while reading/decoding message data from the storage proof. - MessageStorage(StorageProofError), + /// Error returned while reading/decoding message data from the `VecDb`. + MessageStorage(VecDbError), /// The message is too large. MessageTooLarge, - /// Error returned while reading/decoding outbound lane data from the storage proof. - OutboundLaneStorage(StorageProofError), + /// Error returned while reading/decoding outbound lane data from the `VecDb`. + OutboundLaneStorage(VecDbError), /// Storage proof related error. StorageProof(StorageProofError), + /// `VecDb` related error. + VecDb(VecDbError), /// Custom error Other(#[codec(skip)] &'static str), } diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 369386e41b0c..0db4eac79a75 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 = ::Nonce; type Signature = ::Signature; + const STATE_VERSION: StateVersion = ::STATE_VERSION; + fn max_extrinsic_size() -> u32 { ::max_extrinsic_size() } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index d13c9b40efa0..a5477f002470 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -45,6 +45,7 @@ pub use storage_proof::{ ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker, }; pub use storage_types::BoundedStorageValue; +pub use vec_db::{TrustedVecDb, UntrustedVecDb, VecDbError}; #[cfg(feature = "std")] pub use storage_proof::craft_valid_storage_proof; @@ -55,6 +56,7 @@ pub mod messages; mod chain; mod storage_proof; mod storage_types; +mod vec_db; // Re-export macro to avoid include paste dependency everywhere pub use sp_runtime::paste; diff --git a/bridges/primitives/runtime/src/vec_db.rs b/bridges/primitives/runtime/src/vec_db.rs new file mode 100644 index 000000000000..6034e102bd30 --- /dev/null +++ b/bridges/primitives/runtime/src/vec_db.rs @@ -0,0 +1,332 @@ +// Copyright 2019-2023 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 . + +//! Logic for working with more efficient storage proofs. + +use frame_support::PalletError; +use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; +use sp_runtime::{SaturatedConversion, StateVersion}; +use sp_std::{default::Default, vec, vec::Vec}; +use sp_trie::{ + generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, StorageProof, TrieDBBuilder, + TrieHash, +}; + +use codec::{Decode, Encode}; +use hash_db::Hasher; +use scale_info::TypeInfo; +use trie_db::{DBValue, Trie}; + +use crate::{storage_proof::RawStorageProof, Size}; + +pub type RawStorageKey = Vec; + +/// Errors that can occur when interacting with `UntrustedVecDb` and `TrustedVecDb`. +#[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] +pub enum VecDbError { + /// 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 in the `VecDb` wasn't read. + UnusedKey, +} + +/// Structure representing a key-value database stored as a sorted `Vec` of tuples. +/// +/// The structure also contains a proof of the fact that the key-value tuples are actually present +/// in the chain storage. +#[derive(Clone, Default, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct UntrustedVecDb { + proof: RawStorageProof, + db: Vec<(RawStorageKey, Option)>, +} + +impl UntrustedVecDb { + /// Creates a new instance of `UntrustedVecDb`. + pub fn try_new( + read_proof: StorageProof, + root: TrieHash>, + mut keys: Vec + Ord>, + ) -> Result { + // It's ok to use `LayoutV1` in this function, no matter the actual underlying layout, + // because we only perform read operations. When reading `LayoutV0` and `LayoutV1` lead to + // the same result. + let mem_db = read_proof.into_memory_db(); + let trie_db = TrieDBBuilder::>::new(&mem_db, &root).build(); + + let trie_proof = generate_trie_proof::, _, _, _>(&mem_db, root, &keys) + .map_err(|_| VecDbError::UnableToGenerateTrieProof)?; + + let mut entries = Vec::with_capacity(keys.len()); + keys.sort(); + for key in keys { + let val = trie_db.get(key.as_ref()).map_err(|_| VecDbError::UnavailableKey)?; + entries.push((key.as_ref().to_vec(), val)); + } + + Ok(Self { proof: trie_proof, db: entries }) + } + + /// Validates the contained `db` against the contained proof. If the `db` is valid, converts it + /// into a `TrustedVecDb`. + pub fn verify( + mut self, + state_version: StateVersion, + state_root: &TrieHash>, + ) -> Result { + // First we verify the proof for the `UntrustedVecDb`. + // Note that `verify_trie_proof()` also checks for duplicate keys and unused nodes. + match state_version { + StateVersion::V0 => + verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), + StateVersion::V1 => + verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), + } + .map_err(|_| VecDbError::InvalidProof)?; + + // Fill the `TrustedVecDb` + let mut trusted_db = Vec::with_capacity(self.db.len()); + let mut iter = self.db.drain(..).peekable(); + while let Some((key, val)) = iter.next() { + // Let's also make sure that the db is actually sorted. + if let Some((next_key, _)) = iter.peek() { + if next_key <= &key { + return Err(VecDbError::UnsortedEntries) + } + } + trusted_db.push((TrackedStorageKey::new(key), val)) + } + Ok(TrustedVecDb { db: trusted_db }) + } +} + +impl Size for UntrustedVecDb { + fn size(&self) -> u32 { + let proof_size = self.proof.iter().fold(0usize, |sum, node| sum.saturating_add(node.len())); + let entries_size = self.db.iter().fold(0usize, |sum, (key, value)| { + sum.saturating_add(key.len()) + .saturating_add(value.as_ref().unwrap_or(&vec![]).len()) + }); + + proof_size.saturating_add(entries_size).saturated_into() + } +} + +/// Structure representing a key-value database stored as a sorted `Vec` of tuples. +pub struct TrustedVecDb { + db: Vec<(TrackedStorageKey, Option)>, +} + +impl TrustedVecDb { + /// Returns a reference to the value corresponding to the key. + /// + /// Returns an error if the key doesn't exist. + pub fn get(&mut self, key: &impl AsRef<[u8]>) -> Result<&Option, VecDbError> { + let idx = self + .db + .binary_search_by(|(db_key, _)| db_key.key.as_slice().cmp(key.as_ref())) + .map_err(|_| VecDbError::UnavailableKey)?; + let (db_key, db_val) = self.db.get_mut(idx).ok_or(VecDbError::UnavailableKey)?; + db_key.add_read(); + Ok(db_val) + } + + /// Returns a reference to the value corresponding to the key. + /// + /// Returns an error if the key doesn't exist or if the value associated to it is `None`. + pub fn get_and_decode_mandatory( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result { + let val = self.get(key)?.as_ref().ok_or(VecDbError::EmptyVal)?; + D::decode(&mut &val[..]).map_err(|_| VecDbError::DecodeError) + } + + /// Returns a reference to the value corresponding to the key. + /// + /// Returns `None` if the key doesn't exist or if the value associated to it is `None`. + pub fn get_and_decode_optional( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, VecDbError> { + match self.get_and_decode_mandatory(key) { + Ok(val) => Ok(Some(val)), + Err(VecDbError::UnavailableKey | VecDbError::EmptyVal) => Ok(None), + Err(e) => Err(e), + } + } + + /// Checks if each key was read. + pub fn ensure_no_unused_keys(&self) -> Result<(), VecDbError> { + for (key, _) in &self.db { + if !key.has_been_read() { + return Err(VecDbError::UnusedKey) + } + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::H256; + + use sp_state_machine::{prove_read, InMemoryBackend}; + + type Hasher = sp_core::Blake2Hasher; + + fn generate_untrusted_vec_db( + entries: Vec<(RawStorageKey, Option)>, + ) -> (H256, Result) { + let keys: Vec<_> = entries.iter().map(|(key, _)| key.clone()).collect(); + let entries: Vec<_> = + entries.iter().cloned().map(|(key, val)| (None, vec![(key, val)])).collect(); + let backend = InMemoryBackend::::from((entries, StateVersion::V1)); + let root = *backend.root(); + let read_proof = prove_read(backend, &keys).unwrap(); + + (root, UntrustedVecDb::try_new::(read_proof, root, keys)) + } + + #[test] + fn verify_succeeds_when_used_correctly() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![ + (b"key1".to_vec(), None), + (b"key2".to_vec(), Some(b"val2".to_vec())), + ]); + let db = maybe_db.unwrap(); + + assert!(db.verify::(StateVersion::V1, &root).is_ok()); + } + + #[test] + fn verify_fails_when_proof_contains_unneeded_nodes() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![ + (b"key1".to_vec(), Some(b"val1".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + ]); + let mut db = maybe_db.unwrap(); + assert!(db.db.pop().is_some()); + + assert!(matches!( + db.verify::(StateVersion::V1, &root), + Err(VecDbError::InvalidProof) + )); + } + + #[test] + fn verify_fails_when_db_contains_duplicate_nodes() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![(b"key".to_vec(), None)]); + let mut db = maybe_db.unwrap(); + db.db.push((b"key".to_vec(), None)); + + assert!(matches!( + db.verify::(StateVersion::V1, &root), + Err(VecDbError::InvalidProof) + )); + } + + #[test] + fn verify_fails_when_entries_are_not_sorted() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![ + (b"key1".to_vec(), Some(b"val1".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + ]); + let mut db = maybe_db.unwrap(); + db.db.reverse(); + + assert!(matches!( + db.verify::(StateVersion::V1, &root), + Err(VecDbError::UnsortedEntries) + )); + } + + #[test] + fn get_and_decode_mandatory_works() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![ + (b"key11".to_vec(), Some(b"val11".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + (b"key1".to_vec(), None), + (b"key15".to_vec(), Some(b"val15".to_vec())), + ]); + let db = maybe_db.unwrap(); + let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); + + assert!( + matches!(trusted_db.get_and_decode_mandatory::>(b"key11"), Ok(val) if val == b"val11".to_vec()) + ); + assert!( + matches!(trusted_db.get_and_decode_mandatory::>(b"key2"), Ok(val) if val == b"val2".to_vec()) + ); + assert!(matches!( + trusted_db.get_and_decode_mandatory::>(b"key1"), + Err(VecDbError::EmptyVal) + )); + assert!(matches!( + trusted_db.get_and_decode_mandatory::>(b"key15"), + Err(VecDbError::DecodeError) + )); + } + + #[test] + fn get_and_decode_optional_works() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![ + (b"key11".to_vec(), Some(b"val11".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + (b"key1".to_vec(), None), + (b"key15".to_vec(), Some(b"val15".to_vec())), + ]); + let db = maybe_db.unwrap(); + let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); + + assert!( + matches!(trusted_db.get_and_decode_optional::>(b"key11"), Ok(Some(val)) if val == + b"val11".to_vec()) + ); + assert!( + matches!(trusted_db.get_and_decode_optional::>(b"key2"), Ok(Some(val)) if val == b"val2".to_vec()) + ); + assert!(matches!(trusted_db.get_and_decode_optional::>(b"key1"), Ok(None))); + assert!(matches!( + trusted_db.get_and_decode_optional::>(b"key15"), + Err(VecDbError::DecodeError) + )); + } + + #[test] + fn ensure_no_unused_keys_works_correctly() { + let (root, maybe_db) = generate_untrusted_vec_db(vec![ + (b"key1".to_vec(), None), + (b"key2".to_vec(), Some(b"val2".to_vec())), + ]); + let db = maybe_db.unwrap(); + let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); + assert!(trusted_db.get(b"key1").is_ok()); + + assert!(matches!(trusted_db.ensure_no_unused_keys(), Err(VecDbError::UnusedKey))); + } +} diff --git a/bridges/relays/client-substrate/src/test_chain.rs b/bridges/relays/client-substrate/src/test_chain.rs index cfd241c022a2..991202e9874c 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/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs index e3786dcdc5e3..909fa6b148a2 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs @@ -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: Default::default(), lane: Default::default(), nonces_start: 1, nonces_end: messages as u64, diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs index 1f597e278da4..b8f51cd5c932 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -35,7 +35,9 @@ use bp_messages::{ ChainWithMessages as _, InboundMessageDetails, LaneId, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, }; -use bp_runtime::{BasicOperatingMode, HeaderIdProvider}; +use bp_runtime::{ + BasicOperatingMode, HasherOf, HeaderIdProvider, RangeInclusiveExt, UntrustedVecDb, +}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use codec::Encode; use frame_support::weights::Weight; @@ -54,6 +56,7 @@ use relay_substrate_client::{ }; use relay_utils::relay_loop::Client as RelayClient; use sp_core::Pair; +use sp_runtime::traits::Header; use std::ops::RangeInclusive; /// Intermediate message proof returned by the source Substrate node. Includes everything @@ -320,34 +323,33 @@ 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 root = *self.source_client.header_by_hash(id.hash()).await?.state_root(); + let storage_proof = + self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; + let storage = + UntrustedVecDb::try_new::>(storage_proof, root, storage_keys) + .map_err(|e| { + SubstrateError::Custom(format!("Error generating messages storage: {:?}", e)) + })?; let proof = FromBridgedChainMessagesProof { bridged_header_hash: id.1, - storage_proof: proof, + storage, lane: self.lane_id, nonces_start: *nonces.start(), nonces_end: *nonces.end(), From 18b5b22f98bc072dd7c9aed11f573179e1806da2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 1 Jun 2023 10:18:30 +0300 Subject: [PATCH 02/58] Moved FromBridgedChainMessagesDeliveryProof to bp-messages (#2169) * moved FromBridgedChainMessagesDeliveryProof to bp-messages * spelling * fix benchmarks compilation --- bridges/bin/runtime-common/src/messages.rs | 30 +-------------- .../src/messages_benchmarking.rs | 6 +-- .../runtime-common/src/messages_call_ext.rs | 16 ++++---- .../primitives/messages/src/source_chain.rs | 38 +++++++++++++++++-- .../lib-substrate-relay/src/messages_lane.rs | 9 +++-- .../src/messages_target.rs | 5 +-- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index b86ab45fdeea..efc3de7ecb83 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -22,7 +22,7 @@ use bp_header_chain::HeaderChain; use bp_messages::{ - source_chain::TargetHeaderChain, + source_chain::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChain}, target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, @@ -90,32 +90,6 @@ pub mod source { } } - /// 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 { - /// 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 Size for FromBridgedChainMessagesDeliveryProof { - 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 = (LaneId, InboundLaneData>>); @@ -369,7 +343,7 @@ pub mod target { pub type BridgeMessagesCallOf = bp_messages::BridgeMessagesCall< bp_runtime::AccountIdOf, target::FromBridgedChainMessagesProof>, - source::FromBridgedChainMessagesDeliveryProof>, + bp_messages::source_chain::FromBridgedChainMessagesDeliveryProof>, >; #[cfg(test)] diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index 5d92e9e68711..c630386339c7 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -21,8 +21,8 @@ use crate::{ messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - AccountIdOf, BridgedChain, HashOf, MessageBridge, ThisChain, + target::FromBridgedChainMessagesProof, AccountIdOf, BridgedChain, HashOf, MessageBridge, + ThisChain, }, messages_generation::{ encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, @@ -30,7 +30,7 @@ use crate::{ }, }; -use bp_messages::MessagePayload; +use bp_messages::{source_chain::FromBridgedChainMessagesDeliveryProof, MessagePayload}; use bp_polkadot_core::parachains::ParaHash; use bp_runtime::{Chain, Parachain, StorageProofSize, UnderlyingChainOf}; use codec::Encode; diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index a29e9b80a50d..c16c4ca40f3a 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -17,10 +17,11 @@ //! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete //! (and some other invalid) transactions. -use crate::messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, +use crate::messages::target::FromBridgedChainMessagesProof; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::MessageDispatch, + InboundLaneData, LaneId, MessageNonce, }; -use bp_messages::{target_chain::MessageDispatch, InboundLaneData, LaneId, MessageNonce}; use bp_runtime::OwnedBridgeModule; use frame_support::{ dispatch::CallableCallFor, @@ -358,16 +359,17 @@ fn unrewarded_relayers_occupation, I: 'static>( mod tests { use super::*; use crate::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - }, + messages::target::FromBridgedChainMessagesProof, messages_call_ext::MessagesCallSubType, mock::{ DummyMessageDispatch, MaxUnconfirmedMessagesAtInboundLane, MaxUnrewardedRelayerEntriesAtInboundLane, TestRuntime, ThisChainRuntimeCall, }, }; - use bp_messages::{DeliveredMessages, UnrewardedRelayer, UnrewardedRelayersState}; + use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, DeliveredMessages, UnrewardedRelayer, + UnrewardedRelayersState, + }; use sp_std::ops::RangeInclusive; fn fill_unrewarded_relayers() { diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index f4aefd973558..eb2e14159abc 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -16,11 +16,12 @@ //! Primitives of messages module, that are used on the source chain. -use crate::{InboundLaneData, LaneId, MessageNonce, VerificationError}; +use crate::{InboundLaneData, LaneId, MessageNonce, UnrewardedRelayer, VerificationError}; -use crate::UnrewardedRelayer; -use bp_runtime::Size; +use bp_runtime::{RawStorageProof, Size}; +use codec::{Decode, Encode}; use frame_support::Parameter; +use scale_info::TypeInfo; use sp_core::RuntimeDebug; use sp_std::{ collections::{btree_map::BTreeMap, vec_deque::VecDeque}, @@ -28,6 +29,37 @@ use sp_std::{ ops::RangeInclusive, }; +/// Messages delivery proof from the bridged chain. +/// +/// It contains everything required to prove that our (this chain) messages have been +/// delivered to the bridged (target) chain: +/// +/// - hash of finalized header; +/// +/// - storage proof of the inbound lane state; +/// +/// - lane id. +#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct FromBridgedChainMessagesDeliveryProof { + /// 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 Size for FromBridgedChainMessagesDeliveryProof { + fn size(&self) -> u32 { + u32::try_from( + self.storage_proof + .iter() + .fold(0usize, |sum, node| sum.saturating_add(node.len())), + ) + .unwrap_or(u32::MAX) + } +} + /// Number of messages, delivered by relayers. pub type RelayersRewards = BTreeMap; diff --git a/bridges/relays/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs index 909fa6b148a2..f34cc446939d 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs @@ -24,13 +24,14 @@ use crate::{ }; use async_std::sync::Arc; -use bp_messages::{ChainWithMessages as _, LaneId, MessageNonce}; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, ChainWithMessages as _, LaneId, + MessageNonce, +}; use bp_runtime::{ AccountIdOf, Chain as _, EncodedOrDecodedCall, HeaderIdOf, TransactionEra, WeightExtraOps, }; -use bridge_runtime_common::messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, -}; +use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use codec::Encode; use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction}; diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages_target.rs index e1c7645eac68..c8dab7fe90b9 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_target.rs @@ -33,10 +33,9 @@ use crate::{ 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}, From 379a600966ec9a6145469a20ac7b925a06796d40 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 1 Jun 2023 11:08:26 +0300 Subject: [PATCH 03/58] Moved FromBridgedChainMessagesProof to bp-messages (#2170) * moved FromBridgedChainMessagesProof to bp-messages * fmt --- .../extensions/refund_relayer_extension.rs | 9 ++--- bridges/bin/runtime-common/src/messages.rs | 39 +++---------------- .../src/messages_benchmarking.rs | 10 ++--- .../runtime-common/src/messages_call_ext.rs | 8 ++-- bridges/bin/runtime-common/src/mock.rs | 4 +- .../primitives/messages/src/target_chain.rs | 34 +++++++++++++++- .../lib-substrate-relay/src/messages_lane.rs | 5 +-- .../src/messages_source.rs | 2 +- 8 files changed, 57 insertions(+), 54 deletions(-) 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 aab3280a3493..252bb202649b 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -935,9 +935,6 @@ where pub(crate) mod tests { use super::*; use crate::{ - messages::{ - source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, - }, messages_call_ext::{ BaseMessagesProofInfo, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayerOccupation, @@ -946,8 +943,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}; diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index efc3de7ecb83..9f71d542937e 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -23,7 +23,9 @@ use bp_header_chain::HeaderChain; use bp_messages::{ source_chain::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChain}, - target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, + target_chain::{ + FromBridgedChainMessagesProof, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, + }, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, }; @@ -31,10 +33,7 @@ pub use bp_runtime::{ Chain, RangeInclusiveExt, RawStorageProof, Size, TrustedVecDb, UnderlyingChainOf, UnderlyingChainProvider, UntrustedVecDb, }; -use codec::{Decode, Encode}; use frame_support::{traits::Get, weights::Weight}; -use scale_info::TypeInfo; -use sp_runtime::RuntimeDebug; use sp_std::{marker::PhantomData, vec::Vec}; /// Bidirectional message bridge. @@ -190,32 +189,6 @@ pub mod target { /// 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 { - /// Hash of the finalized bridged header the proof is for. - pub bridged_header_hash: BridgedHeaderHash, - /// The proved storage containing the messages being delivered. - pub storage: UntrustedVecDb, - /// 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 Size for FromBridgedChainMessagesProof { - fn size(&self) -> u32 { - self.storage.size() - } - } - /// 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 @@ -342,7 +315,7 @@ pub mod target { /// The `BridgeMessagesCall` used by a chain. pub type BridgeMessagesCallOf = bp_messages::BridgeMessagesCall< bp_runtime::AccountIdOf, - target::FromBridgedChainMessagesProof>, + FromBridgedChainMessagesProof>, bp_messages::source_chain::FromBridgedChainMessagesDeliveryProof>, >; @@ -400,7 +373,7 @@ mod tests { encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, add_duplicate_key: bool, add_unused_key: bool, - test: impl Fn(target::FromBridgedChainMessagesProof) -> R, + test: impl Fn(FromBridgedChainMessagesProof) -> R, ) -> R { let (state_root, storage) = prepare_messages_storage_proof::( TEST_LANE_ID, @@ -432,7 +405,7 @@ mod tests { bridged_header_hash, bridged_header.build(), ); - test(target::FromBridgedChainMessagesProof { + test(FromBridgedChainMessagesProof { bridged_header_hash, storage, lane: TEST_LANE_ID, diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index c630386339c7..8b2051e7e910 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -20,17 +20,17 @@ #![cfg(feature = "runtime-benchmarks")] use crate::{ - messages::{ - target::FromBridgedChainMessagesProof, AccountIdOf, BridgedChain, HashOf, MessageBridge, - ThisChain, - }, + messages::{AccountIdOf, BridgedChain, HashOf, MessageBridge, ThisChain}, messages_generation::{ encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, prepare_messages_storage_proof, }, }; -use bp_messages::{source_chain::FromBridgedChainMessagesDeliveryProof, MessagePayload}; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, MessagePayload, +}; use bp_polkadot_core::parachains::ParaHash; use bp_runtime::{Chain, Parachain, StorageProofSize, UnderlyingChainOf}; use codec::Encode; diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index c16c4ca40f3a..aacf3190b78b 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -17,9 +17,9 @@ //! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete //! (and some other invalid) transactions. -use crate::messages::target::FromBridgedChainMessagesProof; use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::MessageDispatch, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::{FromBridgedChainMessagesProof, MessageDispatch}, InboundLaneData, LaneId, MessageNonce, }; use bp_runtime::OwnedBridgeModule; @@ -359,7 +359,6 @@ fn unrewarded_relayers_occupation, I: 'static>( mod tests { use super::*; use crate::{ - messages::target::FromBridgedChainMessagesProof, messages_call_ext::MessagesCallSubType, mock::{ DummyMessageDispatch, MaxUnconfirmedMessagesAtInboundLane, @@ -367,7 +366,8 @@ mod tests { }, }; use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, DeliveredMessages, UnrewardedRelayer, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, DeliveredMessages, UnrewardedRelayer, UnrewardedRelayersState, }; use sp_std::ops::RangeInclusive; diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index f287aea8de6b..aac693dfb352 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -23,7 +23,7 @@ use crate::messages::{ FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload, TargetHeaderChainAdapter, }, - target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, + target::SourceHeaderChainAdapter, BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, }; @@ -209,7 +209,7 @@ impl pallet_bridge_messages::Config for TestRuntime { type MaximalOutboundPayloadSize = FromThisChainMaximalOutboundPayloadSize; type OutboundPayload = FromThisChainMessagePayload; - type InboundPayload = FromBridgedChainMessagePayload; + type InboundPayload = Vec; type InboundRelayer = BridgedChainAccountId; type DeliveryPayments = (); diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index 388ce16ccdc0..1178f4e44ce7 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -20,13 +20,45 @@ use crate::{ LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, }; -use bp_runtime::{messages::MessageDispatchResult, Size}; +use bp_runtime::{messages::MessageDispatchResult, Size, UntrustedVecDb}; use codec::{Decode, Encode, Error as CodecError}; use frame_support::{weights::Weight, Parameter}; 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 { + /// Hash of the finalized bridged header the proof is for. + pub bridged_header_hash: BridgedHeaderHash, + /// The proved storage containing the messages being delivered. + pub storage: UntrustedVecDb, + /// 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 Size for FromBridgedChainMessagesProof { + fn size(&self) -> u32 { + self.storage.size() + } +} + /// Proved messages from the source chain. pub type ProvedMessages = BTreeMap>; diff --git a/bridges/relays/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs index f34cc446939d..271b5a384351 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs @@ -25,13 +25,12 @@ use crate::{ use async_std::sync::Arc; use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, ChainWithMessages as _, LaneId, - MessageNonce, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, LaneId, MessageNonce, }; use bp_runtime::{ AccountIdOf, Chain as _, EncodedOrDecodedCall, HeaderIdOf, TransactionEra, WeightExtraOps, }; -use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use codec::Encode; use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction}; diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs index b8f51cd5c932..8c2faf9fedaa 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -32,13 +32,13 @@ 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, HasherOf, HeaderIdProvider, RangeInclusiveExt, UntrustedVecDb, }; -use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use codec::Encode; use frame_support::weights::Weight; use messages_relay::{ From 7b5b01c43777b62882fad86ef346756788fea647 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 2 Jun 2023 12:47:41 +0300 Subject: [PATCH 04/58] Separate folder for messages in relay lib (#2173) * moved message files to separate folder * ...and fix paths in code * fmt rebase nit --- .../lib-substrate-relay/src/cli/bridge.rs | 2 +- .../src/cli/relay_headers_and_messages/mod.rs | 10 +++---- .../src/cli/relay_messages.rs | 6 ++-- bridges/relays/lib-substrate-relay/src/lib.rs | 5 +--- .../metrics.rs} | 0 .../src/{messages_lane.rs => messages/mod.rs} | 28 +++++++++++-------- .../source.rs} | 2 +- .../target.rs} | 9 +++--- .../src/on_demand/parachains.rs | 4 +-- 9 files changed, 35 insertions(+), 31 deletions(-) rename bridges/relays/lib-substrate-relay/src/{messages_metrics.rs => messages/metrics.rs} (100%) rename bridges/relays/lib-substrate-relay/src/{messages_lane.rs => messages/mod.rs} (96%) rename bridges/relays/lib-substrate-relay/src/{messages_source.rs => messages/source.rs} (99%) rename bridges/relays/lib-substrate-relay/src/{messages_target.rs => messages/target.rs} (98%) diff --git a/bridges/relays/lib-substrate-relay/src/cli/bridge.rs b/bridges/relays/lib-substrate-relay/src/cli/bridge.rs index 316f59a2b0c8..5631285b3c54 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 05a061c2ea60..338dda3c6330 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::>(); { 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::<::MessagesLane, _, _>( + crate::messages::run::<::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::<::MessagesLane, _, _>( + crate::messages::run::<::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 a17ae7c0c01f..8ce562da3442 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::()?; let target_transactions_mortality = data.target_sign.transactions_mortality()?; - crate::messages_lane::run::(MessagesRelayParams { + crate::messages::run::(MessagesRelayParams { source_client, source_transaction_params: TransactionParams { signer: source_sign, @@ -161,7 +161,7 @@ where })? .id(); - crate::messages_lane::relay_messages_range::( + crate::messages::relay_messages_range::( 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 b3e8e7ed9a20..002a58a66fe7 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; 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 96% rename from bridges/relays/lib-substrate-relay/src/messages_lane.rs rename to bridges/relays/lib-substrate-relay/src/messages/mod.rs index 271b5a384351..50246ea438df 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -17,8 +17,10 @@ //! 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, }; @@ -48,6 +50,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`. @@ -432,21 +438,21 @@ 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 { @@ -528,16 +534,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 { diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs similarity index 99% rename from bridges/relays/lib-substrate-relay/src/messages_source.rs rename to bridges/relays/lib-substrate-relay/src/messages/source.rs index 8c2faf9fedaa..877b0438323e 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -20,7 +20,7 @@ use crate::{ finality_base::best_synced_header_id, - messages_lane::{ + messages::{ BatchProofTransaction, MessageLaneAdapter, ReceiveMessagesDeliveryProofCallBuilder, SubstrateMessageLane, }, diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages/target.rs similarity index 98% rename from bridges/relays/lib-substrate-relay/src/messages_target.rs rename to bridges/relays/lib-substrate-relay/src/messages/target.rs index c8dab7fe90b9..a8395dc4fc74 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/target.rs @@ -19,13 +19,14 @@ //! `` 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, TransactionParams, }; 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 654cb6628d5f..4579222a2c68 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, SubstrateError> { - Ok(crate::messages_source::read_client_state::( + Ok(crate::messages::source::read_client_state::( &self.0.target_client, ) .await? From 0278a5473b82a879f3bab7a65014e3bf77e6b369 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Fri, 2 Jun 2023 13:32:00 +0300 Subject: [PATCH 05/58] Messages pallet benchmarks - cosmetics (#2175) --- .../runtime-common/src/messages_generation.rs | 6 +- bridges/modules/messages/src/benchmarking.rs | 373 ++++++++++-------- bridges/modules/messages/src/weights.rs | 149 +++---- bridges/modules/messages/src/weights_ext.rs | 8 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 8 +- 5 files changed, 283 insertions(+), 261 deletions(-) diff --git a/bridges/bin/runtime-common/src/messages_generation.rs b/bridges/bin/runtime-common/src/messages_generation.rs index be7c0458d09a..21b7a6fa7490 100644 --- a/bridges/bin/runtime-common/src/messages_generation.rs +++ b/bridges/bin/runtime-common/src/messages_generation.rs @@ -23,8 +23,8 @@ use bp_messages::{ OutboundLaneData, }; use bp_runtime::{ - record_all_trie_keys, Chain, RawStorageProof, StorageProofSize, UnderlyingChainOf, - UntrustedVecDb, + record_all_trie_keys, Chain, RangeInclusiveExt, RawStorageProof, StorageProofSize, + UnderlyingChainOf, UntrustedVecDb, }; use codec::Encode; use frame_support::sp_runtime::StateVersion; @@ -112,7 +112,7 @@ where HashOf>: 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; + let message_count = message_nonces.saturating_len(); let mut storage_keys = Vec::with_capacity(message_count as usize + 1); let mut root = Default::default(); let mut mdb = MemoryDB::default(); diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 4f13c4409672..5006b55573b0 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -16,6 +16,8 @@ //! Messages pallet benchmarking. +#![cfg(feature = "runtime-benchmarks")] + use crate::{ inbound_lane::InboundLaneStorage, outbound_lane, weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH, Call, OutboundLanes, RuntimeInboundLaneStorage, @@ -28,7 +30,7 @@ use bp_messages::{ }; use bp_runtime::StorageProofSize; 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}; @@ -109,42 +111,116 @@ pub trait Config: crate::Config { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool; } -benchmarks_instance_pallet! { +fn send_regular_message, I: 'static>() { + let mut outbound_lane = outbound_lane::(T::bench_lane_id()); + outbound_lane.send_message(BoundedVec::try_from(vec![]).expect("We craft valid messages")); +} + +fn receive_messages, I: 'static>(nonce: MessageNonce) { + let mut inbound_lane_storage = + RuntimeInboundLaneStorage::::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, I: 'static> { + relayer_id_on_src: T::InboundRelayer, + relayer_id_on_tgt: T::AccountId, + msgs_count: u32, + _phantom_data: sp_std::marker::PhantomData, +} + +impl, I: 'static> ReceiveMessagesProofSetup { + 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::(Self::LATEST_RECEIVED_NONCE); + + setup + } + + fn relayer_id_on_src(&self) -> T::InboundRelayer { + 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 { + (Self::LATEST_RECEIVED_NONCE + 1)..=self.last_nonce() + } + + fn check_last_nonce(&self) { + assert_eq!( + crate::InboundLanes::::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: + // 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::(20); - + #[benchmark] + fn receive_single_message_proof() { + // setup code + let setup = ReceiveMessagesProofSetup::::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), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::::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(), + 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 two 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); @@ -154,129 +230,104 @@ benchmarks_instance_pallet! { // `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::(20); - + #[benchmark] + fn receive_two_messages_proof() { + // setup code + let setup = ReceiveMessagesProofSetup::::new(2); 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), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 2, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::::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(), + 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::(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::::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::::LATEST_RECEIVED_NONCE, + latest_generated_nonce: setup.last_nonce(), }), is_successful_dispatch_expected: false, size: StorageProofSize::Minimal(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::::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::(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::::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(), + 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::(20); - + #[benchmark] + fn receive_single_message_n_kb_proof( + /// Proof size in KB + n: Linear<1, 16>, + ) { + // setup code + let setup = ReceiveMessagesProofSetup::::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), + size: StorageProofSize::Minimal(n * 1024), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::::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(), + proof, + setup.msgs_count, + dispatch_weight, ); + + // verification code + setup.check_last_nonce(); } // Benchmark `receive_messages_delivery_proof` extrinsic with following conditions: @@ -284,7 +335,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 +354,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), }); - }: 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::::get(T::bench_lane_id()).latest_received_nonce, 1); assert!(T::is_relayer_rewarded(&relayer_id)); } @@ -320,7 +380,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 +402,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), }); - }: 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::::get(T::bench_lane_id()).latest_received_nonce, 2); assert!(T::is_relayer_rewarded(&relayer_id)); } @@ -359,7 +428,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 +455,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), }); - }: 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::::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 +489,34 @@ 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::(20); - + #[benchmark] + fn receive_single_message_n_bytes_proof_with_dispatch( + /// Proof size in bytes + n: Linear, + ) { + // setup code + let setup = ReceiveMessagesProofSetup::::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), + size: StorageProofSize::Minimal(n), }); - }: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight) - verify { - assert_eq!( - crate::InboundLanes::::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(), + proof, + setup.msgs_count, + dispatch_weight, + ); -fn send_regular_message, I: 'static>() { - let mut outbound_lane = outbound_lane::(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, I: 'static>(nonce: MessageNonce) { - let mut inbound_lane_storage = - RuntimeInboundLaneStorage::::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::mock::new_test_ext(), crate::mock::TestRuntime); } diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index 51152b83d9bc..39b372fd219a 100644 --- a/bridges/modules/messages/src/weights.rs +++ b/bridges/modules/messages/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for pallet_bridge_messages //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-06-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! 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 @@ -53,12 +53,11 @@ pub trait WeightInfo { fn receive_single_message_proof() -> Weight; fn receive_two_messages_proof() -> 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_message_n_kb_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_message_n_bytes_proof_with_dispatch(n: u32) -> Weight; } /// Weights for `pallet_bridge_messages` that are generated using one of the Bridge testnets. @@ -84,8 +83,8 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 34_049 nanoseconds. - Weight::from_parts(39_460_000, 52645) + // Minimum execution time: 32_573 nanoseconds. + Weight::from_parts(35_227_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -107,8 +106,8 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 44_030 nanoseconds. - Weight::from_parts(48_036_000, 52645) + // Minimum execution time: 43_726 nanoseconds. + Weight::from_parts(47_518_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -130,8 +129,8 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 42_839 nanoseconds. - Weight::from_parts(45_052_000, 52645) + // Minimum execution time: 40_091 nanoseconds. + Weight::from_parts(43_639_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -147,37 +146,20 @@ impl WeightInfo for BridgeWeight { /// /// 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: `428` - // Estimated: `52645` - // Minimum execution time: 33_925 nanoseconds. - Weight::from_parts(36_321_000, 52645) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::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: BridgeUnknownGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), - /// added: 2048, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), + /// added: 51655, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) + /// The range of component `n` is `[1, 16]`. /// - /// 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, 16]`. + fn receive_single_message_n_kb_proof(n: u32) -> Weight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 50_591 nanoseconds. - Weight::from_parts(56_245_000, 52645) + // Minimum execution time: 34_578 nanoseconds. + Weight::from_parts(36_723_095, 52645) + // Standard Error: 8_197 + .saturating_add(Weight::from_parts(1_317_904, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -204,8 +186,8 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `453` // Estimated: `3530` - // Minimum execution time: 33_199 nanoseconds. - Weight::from_parts(34_349_000, 3530) + // Minimum execution time: 32_635 nanoseconds. + Weight::from_parts(33_711_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -232,8 +214,8 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `470` // Estimated: `3530` - // Minimum execution time: 32_221 nanoseconds. - Weight::from_parts(33_944_000, 3530) + // Minimum execution time: 31_808 nanoseconds. + Weight::from_parts(33_071_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -260,8 +242,8 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `470` // Estimated: `6070` - // Minimum execution time: 34_880 nanoseconds. - Weight::from_parts(36_087_000, 6070) + // Minimum execution time: 34_171 nanoseconds. + Weight::from_parts(35_591_000, 6070) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -280,15 +262,15 @@ impl WeightInfo for BridgeWeight { /// 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 `[128, 2048]`. + fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 73_740 nanoseconds. - Weight::from_parts(74_788_229, 52645) - // Standard Error: 1_392 - .saturating_add(Weight::from_parts(302_332, 0).saturating_mul(i.into())) + // Minimum execution time: 76_504 nanoseconds. + Weight::from_parts(75_331_522, 52645) + // Standard Error: 1_440 + .saturating_add(Weight::from_parts(302_158, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -314,8 +296,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 34_049 nanoseconds. - Weight::from_parts(39_460_000, 52645) + // Minimum execution time: 32_573 nanoseconds. + Weight::from_parts(35_227_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -337,8 +319,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 44_030 nanoseconds. - Weight::from_parts(48_036_000, 52645) + // Minimum execution time: 43_726 nanoseconds. + Weight::from_parts(47_518_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -360,8 +342,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 42_839 nanoseconds. - Weight::from_parts(45_052_000, 52645) + // Minimum execution time: 40_091 nanoseconds. + Weight::from_parts(43_639_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -377,37 +359,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: `428` - // Estimated: `52645` - // Minimum execution time: 33_925 nanoseconds. - Weight::from_parts(36_321_000, 52645) - .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: BridgeUnknownGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), - /// added: 2048, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), + /// added: 51655, mode: MaxEncodedLen) /// - /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) + /// The range of component `n` is `[1, 16]`. /// - /// 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, 16]`. + fn receive_single_message_n_kb_proof(n: u32) -> Weight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 50_591 nanoseconds. - Weight::from_parts(56_245_000, 52645) + // Minimum execution time: 34_578 nanoseconds. + Weight::from_parts(36_723_095, 52645) + // Standard Error: 8_197 + .saturating_add(Weight::from_parts(1_317_904, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -434,8 +399,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `453` // Estimated: `3530` - // Minimum execution time: 33_199 nanoseconds. - Weight::from_parts(34_349_000, 3530) + // Minimum execution time: 32_635 nanoseconds. + Weight::from_parts(33_711_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -462,8 +427,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `470` // Estimated: `3530` - // Minimum execution time: 32_221 nanoseconds. - Weight::from_parts(33_944_000, 3530) + // Minimum execution time: 31_808 nanoseconds. + Weight::from_parts(33_071_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -490,8 +455,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `470` // Estimated: `6070` - // Minimum execution time: 34_880 nanoseconds. - Weight::from_parts(36_087_000, 6070) + // Minimum execution time: 34_171 nanoseconds. + Weight::from_parts(35_591_000, 6070) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -510,15 +475,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 `[128, 2048]`. + fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 73_740 nanoseconds. - Weight::from_parts(74_788_229, 52645) - // Standard Error: 1_392 - .saturating_add(Weight::from_parts(302_332, 0).saturating_mul(i.into())) + // Minimum execution time: 76_504 nanoseconds. + Weight::from_parts(75_331_522, 52645) + // Standard Error: 1_440 + .saturating_add(Weight::from_parts(302_158, 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 c12e04f692bf..01058d19ccb9 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -426,9 +426,9 @@ 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_message_n_kb_proof(2) - + Self::receive_single_message_n_kb_proof(1)) / + 1024; proof_size_in_bytes * byte_weight } @@ -443,7 +443,7 @@ pub trait WeightInfoExt: WeightInfo { // 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) + Self::receive_single_message_n_bytes_proof_with_dispatch(message_size) .saturating_sub(Self::receive_single_message_proof()) } } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index fb47fc694392..20dd60c67ac3 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -124,17 +124,13 @@ impl pallet_bridge_messages::WeightInfo for TestMessagesWeights { Weight::zero() } - fn receive_single_message_proof_1_kb() -> Weight { + fn receive_single_message_n_kb_proof(_: u32) -> Weight { Weight::zero() } - fn receive_single_message_proof_16_kb() -> Weight { + fn receive_single_message_n_bytes_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 { From 9197d85faf14aa42002c19b28cae632b3a680c9b Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Mon, 5 Jun 2023 10:06:53 +0300 Subject: [PATCH 06/58] Improve receive_messages_proof benchmarks accuracy (#2176) * Adjust messages pallet benchmarks * Address comment --- bridges/modules/messages/src/benchmarking.rs | 24 +-- bridges/modules/messages/src/weights.rs | 162 ++++++++++--------- bridges/modules/messages/src/weights_ext.rs | 33 +--- bridges/modules/xcm-bridge-hub/src/mock.rs | 14 +- 4 files changed, 108 insertions(+), 125 deletions(-) diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 5006b55573b0..ee969d727ddc 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -33,7 +33,10 @@ use codec::Decode; use frame_benchmarking::{account, v2::*}; use frame_support::weights::Weight; use frame_system::RawOrigin; -use sp_runtime::{traits::TrailingZeroInput, BoundedVec}; +use sp_runtime::{ + traits::{Get, TrailingZeroInput}, + BoundedVec, +}; use sp_std::{ops::RangeInclusive, prelude::*}; const SEED: u32 = 0; @@ -186,14 +189,17 @@ mod benchmarks { // Benchmarks that are used directly by the runtime calls weight formulae. // + fn max_msgs, I: 'static>() -> u32 { + T::MaxUnconfirmedMessagesAtInboundLane::get() as u32 - + ReceiveMessagesProofSetup::::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. #[benchmark] fn receive_single_message_proof() { // setup code @@ -219,21 +225,16 @@ mod benchmarks { setup.check_last_nonce(); } - // Benchmark `receive_messages_proof` extrinsic with two minimal-weight messages and following + // 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. #[benchmark] - fn receive_two_messages_proof() { + fn receive_n_messages_proof(n: Linear<1, { max_msgs::() }>) { // setup code - let setup = ReceiveMessagesProofSetup::::new(2); + let setup = ReceiveMessagesProofSetup::::new(n); let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams { lane: T::bench_lane_id(), message_nonces: setup.nonces(), @@ -489,6 +490,7 @@ mod benchmarks { // * 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. + // #[benchmark(extra)] #[benchmark] fn receive_single_message_n_bytes_proof_with_dispatch( /// Proof size in bytes diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index 39b372fd219a..660a6d4aa9e4 100644 --- a/bridges/modules/messages/src/weights.rs +++ b/bridges/modules/messages/src/weights.rs @@ -51,7 +51,7 @@ 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_n_kb_proof(n: u32) -> Weight; fn receive_delivery_proof_for_single_message() -> Weight; @@ -81,33 +81,39 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 32_573 nanoseconds. - Weight::from_parts(35_227_000, 52645) + // Minimum execution time: 34_644 nanoseconds. + Weight::from_parts(36_135_000, 52645) .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) + /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) - fn receive_two_messages_proof() -> Weight { + /// + /// 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: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 43_726 nanoseconds. - Weight::from_parts(47_518_000, 52645) + // Minimum execution time: 35_330 nanoseconds. + Weight::from_parts(27_526_047, 52645) + // Standard Error: 2_681 + .saturating_add(Weight::from_parts(7_412_923, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -127,10 +133,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 40_091 nanoseconds. - Weight::from_parts(43_639_000, 52645) + // Minimum execution time: 41_123 nanoseconds. + Weight::from_parts(43_023_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -146,20 +152,20 @@ impl WeightInfo for BridgeWeight { /// /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), - /// added: 51655, mode: MaxEncodedLen) + /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: + /// 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16]`. /// /// The range of component `n` is `[1, 16]`. fn receive_single_message_n_kb_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 34_578 nanoseconds. - Weight::from_parts(36_723_095, 52645) - // Standard Error: 8_197 - .saturating_add(Weight::from_parts(1_317_904, 0).saturating_mul(n.into())) + // Minimum execution time: 36_301 nanoseconds. + Weight::from_parts(37_103_459, 52645) + // Standard Error: 4_645 + .saturating_add(Weight::from_parts(1_172_720, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -184,10 +190,10 @@ impl WeightInfo for BridgeWeight { /// mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `453` + // Measured: `515` // Estimated: `3530` - // Minimum execution time: 32_635 nanoseconds. - Weight::from_parts(33_711_000, 3530) + // Minimum execution time: 33_941 nanoseconds. + Weight::from_parts(35_252_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -212,10 +218,10 @@ impl WeightInfo for BridgeWeight { /// mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `3530` - // Minimum execution time: 31_808 nanoseconds. - Weight::from_parts(33_071_000, 3530) + // Minimum execution time: 33_259 nanoseconds. + Weight::from_parts(34_558_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -240,10 +246,10 @@ impl WeightInfo for BridgeWeight { /// mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `6070` - // Minimum execution time: 34_171 nanoseconds. - Weight::from_parts(35_591_000, 6070) + // Minimum execution time: 35_199 nanoseconds. + Weight::from_parts(36_989_000, 6070) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -265,12 +271,12 @@ impl WeightInfo for BridgeWeight { /// The range of component `n` is `[128, 2048]`. fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 76_504 nanoseconds. - Weight::from_parts(75_331_522, 52645) - // Standard Error: 1_440 - .saturating_add(Weight::from_parts(302_158, 0).saturating_mul(n.into())) + // Minimum execution time: 75_228 nanoseconds. + Weight::from_parts(62_255_691, 52645) + // Standard Error: 2_005 + .saturating_add(Weight::from_parts(353_141, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -294,33 +300,39 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 32_573 nanoseconds. - Weight::from_parts(35_227_000, 52645) + // Minimum execution time: 34_644 nanoseconds. + Weight::from_parts(36_135_000, 52645) .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: + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) - fn receive_two_messages_proof() -> Weight { + /// + /// 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: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 43_726 nanoseconds. - Weight::from_parts(47_518_000, 52645) + // Minimum execution time: 35_330 nanoseconds. + Weight::from_parts(27_526_047, 52645) + // Standard Error: 2_681 + .saturating_add(Weight::from_parts(7_412_923, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -340,10 +352,10 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 40_091 nanoseconds. - Weight::from_parts(43_639_000, 52645) + // Minimum execution time: 41_123 nanoseconds. + Weight::from_parts(43_023_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -359,20 +371,20 @@ impl WeightInfo for () { /// /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), - /// added: 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: + /// 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16]`. /// /// The range of component `n` is `[1, 16]`. fn receive_single_message_n_kb_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 34_578 nanoseconds. - Weight::from_parts(36_723_095, 52645) - // Standard Error: 8_197 - .saturating_add(Weight::from_parts(1_317_904, 0).saturating_mul(n.into())) + // Minimum execution time: 36_301 nanoseconds. + Weight::from_parts(37_103_459, 52645) + // Standard Error: 4_645 + .saturating_add(Weight::from_parts(1_172_720, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -397,10 +409,10 @@ impl WeightInfo for () { /// mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `453` + // Measured: `515` // Estimated: `3530` - // Minimum execution time: 32_635 nanoseconds. - Weight::from_parts(33_711_000, 3530) + // Minimum execution time: 33_941 nanoseconds. + Weight::from_parts(35_252_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -425,10 +437,10 @@ impl WeightInfo for () { /// mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `3530` - // Minimum execution time: 31_808 nanoseconds. - Weight::from_parts(33_071_000, 3530) + // Minimum execution time: 33_259 nanoseconds. + Weight::from_parts(34_558_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -453,10 +465,10 @@ impl WeightInfo for () { /// mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `6070` - // Minimum execution time: 34_171 nanoseconds. - Weight::from_parts(35_591_000, 6070) + // Minimum execution time: 35_199 nanoseconds. + Weight::from_parts(36_989_000, 6070) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -478,12 +490,12 @@ impl WeightInfo for () { /// The range of component `n` is `[128, 2048]`. fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 76_504 nanoseconds. - Weight::from_parts(75_331_522, 52645) - // Standard Error: 1_440 - .saturating_add(Weight::from_parts(302_158, 0).saturating_mul(n.into())) + // Minimum execution time: 75_228 nanoseconds. + Weight::from_parts(62_255_691, 52645) + // Standard Error: 2_005 + .saturating_add(Weight::from_parts(353_141, 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 01058d19ccb9..3fc23b3ba740 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() { // 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 @@ -297,13 +290,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 +306,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 +344,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 { diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 20dd60c67ac3..bfbcc4c31a84 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -107,24 +107,22 @@ 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_message_n_kb_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_n_kb_proof(_: u32) -> Weight { + fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { Weight::zero() } From 7c46371aab581beef7fe7b65ef458f3528ac81a7 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 5 Jun 2023 11:57:52 +0300 Subject: [PATCH 07/58] Moving messages code to pallet (#2180) * moved files around * and fix compilation Move Chain::ID from relay-level Chain to primitives-level Chain (#2181) * move Chain::ID from relay-level Chain to primitives-level Chain * removed chain IDs from bp-runtime * add missing file header Adjust weights (#2185) fix clippy (#2186) Remove source header chain (#2183) * moved messages proof verification to messages pallet * removed SourceHeaderChain * cleanup * benchmarks compilation * fix benchmark tests compilation * clippy * fmt Use compact proofs for messages delivery confirmation (#2187) * Use compact proofs for messages delivery confirmation * Fix benchmarks Move messages delivery proof verification to pallet (#2189) * rename messages_proof.rs to proofs.rs * moved delivery proof verification to the messages pallet * removed TargetHeaderChain * cleaning up * fixed benchmarks compilation * Update modules/messages/README.md Co-authored-by: Adrian Catangiu * uncommented test and removed printlns * vec![].into_iter().collect() -> vec![].into() --------- Co-authored-by: Adrian Catangiu removed MaxUnrewardedRelayerEntriesAtInboundLane and MaxUnconfirmedMessagesAtInboundLane from messages pallet config (#2190) * removed MaxUnrewardedRelayerEntriesAtInboundLane and MaxUnconfirmedMessagesAtInboundLane from messages pallet config * fixed doc * fixed benchmarking code * more fixes remove MaximalOutboundPayloadSize and use BridgedChain::maximal_incomging_message_size instead (#2191) remove MessageBridge trait (#2192) --- Cargo.lock | 4 + bridges/bin/runtime-common/Cargo.toml | 10 +- .../src/extensions/priority_calculator.rs | 3 +- .../extensions/refund_relayer_extension.rs | 56 +- bridges/bin/runtime-common/src/integrity.rs | 94 +- bridges/bin/runtime-common/src/lib.rs | 3 +- bridges/bin/runtime-common/src/messages.rs | 699 ----- .../src/messages_benchmarking.rs | 210 +- .../runtime-common/src/messages_call_ext.rs | 43 +- bridges/bin/runtime-common/src/mock.rs | 124 +- .../src/parachains_benchmarking.rs | 7 +- bridges/modules/messages/Cargo.toml | 17 +- bridges/modules/messages/README.md | 105 +- bridges/modules/messages/src/benchmarking.rs | 24 +- bridges/modules/messages/src/inbound_lane.rs | 20 +- bridges/modules/messages/src/lib.rs | 2545 ++++++++--------- bridges/modules/messages/src/outbound_lane.rs | 22 +- bridges/modules/messages/src/proofs.rs | 503 ++++ .../src/tests}/messages_generation.rs | 172 +- .../modules/messages/src/{ => tests}/mock.rs | 317 +- bridges/modules/messages/src/tests/mod.rs | 26 + .../messages/src/tests/pallet_tests.rs | 1082 +++++++ bridges/modules/messages/src/weights.rs | 16 +- bridges/modules/messages/src/weights_ext.rs | 2 +- .../modules/relayers/src/payment_adapter.rs | 3 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 80 +- bridges/primitives/messages/src/lib.rs | 66 +- .../primitives/messages/src/source_chain.rs | 69 +- .../primitives/messages/src/target_chain.rs | 52 +- bridges/primitives/runtime/src/lib.rs | 2 +- .../primitives/runtime/src/storage_proof.rs | 12 + .../src/cli/relay_messages.rs | 2 +- .../lib-substrate-relay/src/messages/mod.rs | 11 +- .../src/messages/target.rs | 27 +- 34 files changed, 3642 insertions(+), 2786 deletions(-) delete mode 100644 bridges/bin/runtime-common/src/messages.rs create mode 100644 bridges/modules/messages/src/proofs.rs rename bridges/{bin/runtime-common/src => modules/messages/src/tests}/messages_generation.rs (58%) rename bridges/modules/messages/src/{ => tests}/mock.rs (63%) create mode 100644 bridges/modules/messages/src/tests/mod.rs create mode 100644 bridges/modules/messages/src/tests/pallet_tests.rs diff --git a/Cargo.lock b/Cargo.lock index 15b5ea3431c5..f65f64a0fbe8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10116,6 +10116,7 @@ dependencies = [ name = "pallet-bridge-messages" version = "0.7.0" dependencies = [ + "bp-header-chain", "bp-messages", "bp-runtime", "bp-test-utils", @@ -10125,11 +10126,14 @@ dependencies = [ "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]] diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index d69a064aab81..91a3c1665275 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -19,7 +19,6 @@ 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,7 +33,6 @@ 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 } @@ -44,15 +42,16 @@ 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"] @@ -93,6 +92,7 @@ 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", diff --git a/bridges/bin/runtime-common/src/extensions/priority_calculator.rs b/bridges/bin/runtime-common/src/extensions/priority_calculator.rs index 92810290f95e..9f559dc13b64 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: 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", 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 252bb202649b..6a982bd7e576 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: ::Id::get(), ::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 = ::Instance, - >>::MaxUnconfirmedMessagesAtInboundLane::get( - ); + >>::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; if bundled_messages > max_unconfirmed_messages_in_confirmation_tx { return None } @@ -1163,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 { @@ -1326,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, }, }), ), @@ -1396,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, }, }), ), @@ -1458,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, }, }), ), @@ -1498,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, }, }, )), @@ -1734,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, @@ -2864,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 d3827a14dd6c..9b41a4bf4902 100644 --- a/bridges/bin/runtime-common/src/integrity.rs +++ b/bridges/bin/runtime-common/src/integrity.rs @@ -19,10 +19,7 @@ //! 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_messages::{ChainWithMessages, InboundLaneData, MessageNonce}; use codec::Encode; use frame_support::{storage::generator::StorageValue, traits::Get, weights::Weight}; use frame_system::limits; @@ -50,23 +47,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 +54,25 @@ macro_rules! assert_bridge_messages_pallet_types( ( runtime: $r:path, with_bridged_chain_messages_instance: $i:path, - bridge: $bridge: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 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>>::OutboundPayload, XcmAsPlainPayload); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf>); - - assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, TargetHeaderChainAdapter<$bridge>); - assert_type_eq_all!(<$r as MessagesConfig<$i>>::SourceHeaderChain, SourceHeaderChainAdapter<$bridge>); + // TODO: https://github.com/paritytech/parity-bridges-common/issues/1666: check ThisChain, BridgedChain + // and BridgedHeaderChain types } } ); /// 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 +81,13 @@ 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 ); } ); @@ -184,20 +150,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(params: AssertBridgeMessagesPalletConstants) +pub fn assert_bridge_messages_pallet_constants() where R: pallet_bridge_messages::Config, MI: 'static, @@ -207,19 +161,6 @@ 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, - ); - assert_eq!(R::BridgedChainId::get(), params.bridged_chain_id); } /// Parameters for asserting bridge pallet names. @@ -238,14 +179,12 @@ 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(params: AssertBridgePalletNames) +pub fn assert_bridge_pallet_names(params: AssertBridgePalletNames) where - B: MessageBridge, R: pallet_bridge_grandpa::Config + pallet_bridge_messages::Config, GI: 'static, MI: 'static, { - assert_eq!(B::BRIDGED_MESSAGES_PALLET_NAME, params.with_this_chain_messages_pallet_name); assert_eq!( pallet_bridge_grandpa::PalletOwner::::storage_value_final_key().to_vec(), bp_runtime::storage_value_key(params.with_bridged_chain_grandpa_pallet_name, "PalletOwner",).0, @@ -265,32 +204,29 @@ where pub struct AssertCompleteBridgeConstants<'a> { /// 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(params: AssertCompleteBridgeConstants) +pub fn assert_complete_bridge_constants(params: AssertCompleteBridgeConstants) where R: frame_system::Config + pallet_bridge_grandpa::Config + pallet_bridge_messages::Config, GI: 'static, MI: 'static, - B: MessageBridge, { assert_chain_constants::(params.this_chain_constants); assert_bridge_grandpa_pallet_constants::(); - assert_bridge_messages_pallet_constants::(params.messages_pallet_constants); - assert_bridge_pallet_names::(params.pallet_names); + assert_bridge_messages_pallet_constants::(); + assert_bridge_pallet_names::(params.pallet_names); } /// 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: 'static, >( @@ -309,13 +245,13 @@ pub fn check_message_lane_weights< pallet_bridge_messages::ensure_weights_are_correct::>(); // 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::>( 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 5679acd6006c..b65bb6041d56 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 9f71d542937e..000000000000 --- a/bridges/bin/runtime-common/src/messages.rs +++ /dev/null @@ -1,699 +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 . - -//! 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. - -use bp_header_chain::HeaderChain; -use bp_messages::{ - source_chain::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChain}, - target_chain::{ - FromBridgedChainMessagesProof, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, - }, - InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, - VerificationError, -}; -pub use bp_runtime::{ - Chain, RangeInclusiveExt, RawStorageProof, Size, TrustedVecDb, UnderlyingChainOf, - UnderlyingChainProvider, UntrustedVecDb, -}; -use frame_support::{traits::Get, weights::Weight}; -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>; -} - -/// 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 = ::ThisChain; -/// Bridged chain in context of message bridge. -pub type BridgedChain = ::BridgedChain; -/// Hash used on the chain. -pub type HashOf = bp_runtime::HashOf<::Chain>; -/// Hasher used on the chain. -pub type HasherOf = bp_runtime::HasherOf>; -/// Account id used on the chain. -pub type AccountIdOf = bp_runtime::AccountIdOf>; -/// Type of balances that is used on the chain. -pub type BalanceOf = bp_runtime::BalanceOf>; - -/// 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(PhantomData); - - impl Get for FromThisChainMaximalOutboundPayloadSize { - fn get() -> u32 { - maximal_message_size::() - } - } - - /// 'Parsed' message delivery proof - inbound lane id and its state. - pub type ParsedMessagesDeliveryProofFromBridgedChain = - (LaneId, InboundLaneData>>); - - /// Return maximal message size of This -> Bridged chain message. - pub fn maximal_message_size() -> u32 { - super::target::maximal_incoming_message_size( - UnderlyingChainOf::>::max_extrinsic_size(), - ) - } - - /// `TargetHeaderChain` implementation that is using default types and perform default checks. - pub struct TargetHeaderChainAdapter(PhantomData); - - impl TargetHeaderChain>> - for TargetHeaderChainAdapter - { - type MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof>>; - - fn verify_message(payload: &FromThisChainMessagePayload) -> Result<(), VerificationError> { - verify_chain_message::(payload) - } - - fn verify_messages_delivery_proof( - proof: Self::MessagesDeliveryProof, - ) -> Result<(LaneId, InboundLaneData>>), VerificationError> { - verify_messages_delivery_proof::(proof) - } - } - - /// Do basic Bridged-chain specific verification of This -> Bridged chain message. - /// - /// Ok result from this function means that the delivery transaction with this message - /// may be 'mined' by the target chain. - pub fn verify_chain_message( - 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::() 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( - proof: FromBridgedChainMessagesDeliveryProof>>, - ) -> Result, 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; - - /// 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(PhantomData); - - impl SourceHeaderChain for SourceHeaderChainAdapter { - type MessagesProof = FromBridgedChainMessagesProof>>; - - fn verify_messages_proof( - proof: Self::MessagesProof, - messages_count: u32, - ) -> Result, VerificationError> { - verify_messages_proof::(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( - proof: FromBridgedChainMessagesProof>>, - messages_count: u32, - ) -> Result, VerificationError> { - let FromBridgedChainMessagesProof { - bridged_header_hash, - storage, - lane, - nonces_start, - nonces_end, - } = proof; - let storage = B::BridgedHeaderChain::verify_vec_db_storage(bridged_header_hash, storage) - .map_err(VerificationError::HeaderChain)?; - let mut parser = StorageAdapter:: { 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 `VecDb` doesn't have any untouched keys. - parser.storage.ensure_no_unused_keys().map_err(VerificationError::VecDb)?; - - // 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 StorageAdapter { - storage: TrustedVecDb, - _dummy: sp_std::marker::PhantomData, - } - - impl StorageAdapter { - fn read_and_decode_outbound_lane_data( - &mut self, - lane_id: &LaneId, - ) -> Result, VerificationError> { - let storage_outbound_lane_data_key = bp_messages::storage_keys::outbound_lane_data_key( - B::BRIDGED_MESSAGES_PALLET_NAME, - lane_id, - ); - - self.storage - .get_and_decode_optional(&storage_outbound_lane_data_key) - .map_err(VerificationError::OutboundLaneStorage) - } - - fn read_and_decode_message_payload( - &mut self, - message_key: &MessageKey, - ) -> Result { - let storage_message_key = bp_messages::storage_keys::message_key( - B::BRIDGED_MESSAGES_PALLET_NAME, - &message_key.lane_id, - message_key.nonce, - ); - self.storage - .get_and_decode_mandatory(&storage_message_key) - .map_err(VerificationError::MessageStorage) - } - } -} - -/// The `BridgeMessagesCall` used by a chain. -pub type BridgeMessagesCallOf = bp_messages::BridgeMessagesCall< - bp_runtime::AccountIdOf, - FromBridgedChainMessagesProof>, - bp_messages::source_chain::FromBridgedChainMessagesDeliveryProof>, ->; - -#[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, VecDbError}; - use codec::Encode; - use sp_core::H256; - use sp_runtime::traits::Header as _; - - #[test] - fn verify_chain_message_rejects_message_with_too_large_declared_weight() { - assert!(source::verify_chain_message::(&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::(&vec![ - 0; - source::maximal_message_size::() - as usize + 1 - ],) - .is_err()); - } - - #[test] - fn verify_chain_message_accepts_maximal_message() { - assert_eq!( - source::verify_chain_message::(&vec![ - 0; - source::maximal_message_size::() - as _ - ],), - Ok(()), - ); - } - - fn using_messages_proof( - nonces_end: MessageNonce, - outbound_lane_data: Option, - encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, - encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, - add_duplicate_key: bool, - add_unused_key: bool, - test: impl Fn(FromBridgedChainMessagesProof) -> R, - ) -> R { - let (state_root, storage) = prepare_messages_storage_proof::( - TEST_LANE_ID, - 1..=nonces_end, - outbound_lane_data, - bp_runtime::StorageProofSize::Minimal(0), - vec![42], - 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::::put(HeaderId( - 0, - bridged_header_hash, - )); - pallet_bridge_grandpa::ImportedHeaders::::insert( - bridged_header_hash, - bridged_header.build(), - ); - test(FromBridgedChainMessagesProof { - bridged_header_hash, - storage, - 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| { target::verify_messages_proof::(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| { target::verify_messages_proof::(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::::get().unwrap().1; - pallet_bridge_grandpa::ImportedHeaders::::remove( - bridged_header_hash, - ); - target::verify_messages_proof::(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::::get().unwrap().1; - pallet_bridge_grandpa::ImportedHeaders::::insert( - bridged_header_hash, - BridgedChainHeader::new( - 0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ) - .build(), - ); - target::verify_messages_proof::(proof, 10) - } - ), - Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), - ); - } - - #[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| { target::verify_messages_proof::(proof, 10) }, - ), - Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), - ); - } - - #[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| { target::verify_messages_proof::(proof, 10) }, - ), - Err(VerificationError::VecDb(VecDbError::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| target::verify_messages_proof::(proof, 10) - ), - Err(VerificationError::MessageStorage(VecDbError::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| target::verify_messages_proof::(proof, 10), - ), - Err(VerificationError::MessageStorage(VecDbError::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| target::verify_messages_proof::(proof, 10), - ), - Err(VerificationError::OutboundLaneStorage(VecDbError::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| { target::verify_messages_proof::(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| target::verify_messages_proof::(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| target::verify_messages_proof::(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; - target::verify_messages_proof::(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 8b2051e7e910..08d103ee32ae 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -19,25 +19,42 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{ - messages::{AccountIdOf, BridgedChain, HashOf, MessageBridge, ThisChain}, - messages_generation::{ - encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, - prepare_messages_storage_proof, - }, -}; +// use crate::{ +// messages::{BridgedChain, HashOf, ThisChain}, +// messages_generation::{ +// encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, +// prepare_messages_storage_proof, +// }, +// }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, MessagePayload, }; use bp_polkadot_core::parachains::ParaHash; -use bp_runtime::{Chain, Parachain, StorageProofSize, UnderlyingChainOf}; +use bp_runtime::{Chain, Parachain, StorageProofSize}; +// TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 - merge with message +// generation methods from messages pallet and use it here + +use bp_messages::{storage_keys, ChainWithMessages}; +use bp_runtime::{ + grow_trie_leaf_value, record_all_trie_keys, AccountIdOf, HashOf, HasherOf, UntrustedVecDb, +}; use codec::Encode; use frame_support::weights::Weight; -use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams}; -use sp_runtime::traits::{Header, Zero}; +use pallet_bridge_messages::{ + benchmarking::{MessageDeliveryProofParams, MessageProofParams}, + messages_generation::{encode_all_messages, encode_lane_data, prepare_messages_storage_proof}, + BridgedChainOf, ThisChainOf, +}; +use sp_runtime::{ + traits::{Header, Zero}, + StateVersion, +}; use sp_std::prelude::*; +use sp_trie::{ + LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, TrieDBMutBuilder, TrieMut, +}; use xcm::latest::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. @@ -75,27 +92,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( +pub fn prepare_message_proof_from_grandpa_chain( params: MessageProofParams, message_generator: impl Fn(usize) -> MessagePayload, -) -> (FromBridgedChainMessagesProof>>, Weight) +) -> (FromBridgedChainMessagesProof>>, Weight) where - R: pallet_bridge_grandpa::Config>>, + R: pallet_bridge_grandpa::Config> + + pallet_bridge_messages::Config< + MI, + BridgedHeaderChain = pallet_bridge_grandpa::Pallet, + >, FI: 'static, - B: MessageBridge, + MI: 'static, { // prepare storage proof - let (state_root, storage) = prepare_messages_storage_proof::( - 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, - false, - false, - ); + let (state_root, storage) = + prepare_messages_storage_proof::, ThisChainOf>( + 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, + false, + false, + ); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::(state_root); @@ -120,32 +142,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( +pub fn prepare_message_proof_from_parachain( params: MessageProofParams, message_generator: impl Fn(usize) -> MessagePayload, -) -> (FromBridgedChainMessagesProof>>, Weight) +) -> (FromBridgedChainMessagesProof>>, Weight) where - R: pallet_bridge_parachains::Config, + R: pallet_bridge_parachains::Config + pallet_bridge_messages::Config, PI: 'static, - B: MessageBridge, - UnderlyingChainOf>: Chain + Parachain, + MI: 'static, + BridgedChainOf: Chain + Parachain, { // prepare storage proof - let (state_root, storage) = prepare_messages_storage_proof::( - 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, - false, - false, - ); + let (state_root, storage) = + prepare_messages_storage_proof::, ThisChainOf>( + 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, + false, + false, + ); // update runtime storage let (_, bridged_header_hash) = - insert_header_to_parachains_pallet::>>(state_root); + insert_header_to_parachains_pallet::>(state_root); ( FromBridgedChainMessagesProof { @@ -164,21 +187,21 @@ 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( - params: MessageDeliveryProofParams>>, -) -> FromBridgedChainMessagesDeliveryProof>> +pub fn prepare_message_delivery_proof_from_grandpa_chain( + params: MessageDeliveryProofParams>>, +) -> FromBridgedChainMessagesDeliveryProof>> where - R: pallet_bridge_grandpa::Config>>, + R: pallet_bridge_grandpa::Config> + + pallet_bridge_messages::Config< + MI, + BridgedHeaderChain = pallet_bridge_grandpa::Pallet, + >, FI: 'static, - B: MessageBridge, + MI: 'static, { // prepare storage proof let lane = params.lane; - let (state_root, storage_proof) = prepare_message_delivery_storage_proof::( - params.lane, - params.inbound_lane_data, - params.size, - ); + let (state_root, storage_proof) = prepare_message_delivery_proof::(params); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::(state_root); @@ -195,26 +218,22 @@ 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( - params: MessageDeliveryProofParams>>, -) -> FromBridgedChainMessagesDeliveryProof>> +pub fn prepare_message_delivery_proof_from_parachain( + params: MessageDeliveryProofParams>>, +) -> FromBridgedChainMessagesDeliveryProof>> where - R: pallet_bridge_parachains::Config, + R: pallet_bridge_parachains::Config + pallet_bridge_messages::Config, PI: 'static, - B: MessageBridge, - UnderlyingChainOf>: Chain + Parachain, + MI: 'static, + BridgedChainOf: Chain + Parachain, { // prepare storage proof let lane = params.lane; - let (state_root, storage_proof) = prepare_message_delivery_storage_proof::( - params.lane, - params.inbound_lane_data, - params.size, - ); + let (state_root, storage_proof) = prepare_message_delivery_proof::(params); // update runtime storage let (_, bridged_header_hash) = - insert_header_to_parachains_pallet::>>(state_root); + insert_header_to_parachains_pallet::>(state_root); FromBridgedChainMessagesDeliveryProof { bridged_header_hash: bridged_header_hash.into(), @@ -223,6 +242,69 @@ where } } +/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage. +fn prepare_message_delivery_proof( + params: MessageDeliveryProofParams>>, +) -> (HashOf>, UntrustedVecDb) +where + R: pallet_bridge_messages::Config, + MI: 'static, +{ + match BridgedChainOf::::STATE_VERSION { + StateVersion::V0 => + do_prepare_message_delivery_proof::>>>( + params, + ), + StateVersion::V1 => + do_prepare_message_delivery_proof::>>>( + params, + ), + } +} + +/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage. +fn do_prepare_message_delivery_proof< + R, + MI, + L: TrieConfiguration>>, +>( + params: MessageDeliveryProofParams>>, +) -> (HashOf>, UntrustedVecDb) +where + R: pallet_bridge_messages::Config, + MI: 'static, +{ + // prepare Bridged chain storage with inbound lane state + let storage_key = storage_keys::inbound_lane_data_key( + R::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + ¶ms.lane, + ) + .0; + let mut root = Default::default(); + let mut mdb = MemoryDB::default(); + { + let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut root).build(); + let inbound_lane_data = + grow_trie_leaf_value(params.inbound_lane_data.encode(), params.size); + 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 read_proof = record_all_trie_keys::(&mdb, &root) + .map_err(|_| "record_all_trie_keys has failed") + .expect("record_all_trie_keys should not fail in benchmarks"); + let storage_proof = UntrustedVecDb::try_new::>>( + StorageProof::new(read_proof), + root, + vec![storage_key], + ) + .unwrap(); + + (root, storage_proof) +} + /// Insert header to the bridge GRANDPA pallet. pub(crate) fn insert_header_to_grandpa_pallet( state_root: bp_runtime::HashOf, diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index aacf3190b78b..0c860e5451f1 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -18,15 +18,10 @@ //! (and some other invalid) transactions. use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::{FromBridgedChainMessagesProof, MessageDispatch}, - InboundLaneData, LaneId, MessageNonce, + target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, MessageNonce, }; use bp_runtime::OwnedBridgeModule; -use frame_support::{ - dispatch::CallableCallFor, - traits::{Get, IsSubType}, -}; +use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; use pallet_bridge_messages::{Config, Pallet}; use sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug}; use sp_std::ops::RangeInclusive; @@ -214,18 +209,8 @@ pub trait MessagesCallSubType, I: 'static>: } impl< - BridgedHeaderHash, - SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof, - >, - TargetHeaderChain: bp_messages::source_chain::TargetHeaderChain< - >::OutboundPayload, - ::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof, - >, Call: IsSubType, T>>, - T: frame_system::Config - + Config, + T: frame_system::Config + Config, I: 'static, > MessagesCallSubType for T::RuntimeCall { @@ -344,13 +329,14 @@ fn unrewarded_relayers_occupation, I: 'static>( inbound_lane_data: &InboundLaneData, ) -> 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) }, } } @@ -360,10 +346,7 @@ mod tests { use super::*; use crate::{ messages_call_ext::MessagesCallSubType, - mock::{ - DummyMessageDispatch, MaxUnconfirmedMessagesAtInboundLane, - MaxUnrewardedRelayerEntriesAtInboundLane, TestRuntime, ThisChainRuntimeCall, - }, + mock::{BridgedUnderlyingChain, DummyMessageDispatch, TestRuntime, ThisChainRuntimeCall}, }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, @@ -375,7 +358,7 @@ mod tests { fn fill_unrewarded_relayers() { let mut inbound_lane_state = pallet_bridge_messages::InboundLanes::::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 }, @@ -394,7 +377,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::::insert( @@ -510,8 +493,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 )); }); } @@ -542,7 +525,7 @@ mod tests { pallet_bridge_messages::Call::::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 { @@ -610,7 +593,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 aac693dfb352..378d201f1299 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::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}, @@ -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; /// 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,13 @@ impl pallet_bridge_messages::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; type ActiveOutboundLanes = ActiveOutboundLanes; - type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; - type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; - type MaximalOutboundPayloadSize = FromThisChainMaximalOutboundPayloadSize; - type OutboundPayload = FromThisChainMessagePayload; + type OutboundPayload = XcmAsPlainPayload; type InboundPayload = Vec; type InboundRelayer = BridgedChainAccountId; type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< TestRuntime, (), @@ -221,9 +200,11 @@ impl pallet_bridge_messages::Config for TestRuntime { >; type OnMessagesDelivered = (); - type SourceHeaderChain = SourceHeaderChainAdapter; type MessageDispatch = DummyMessageDispatch; - type BridgedChainId = BridgedChainId; + + type ThisChain = ThisUnderlyingChain; + type BridgedChain = BridgedUnderlyingChain; + type BridgedHeaderChain = BridgeGrandpa; } impl pallet_bridge_relayers::Config for TestRuntime { @@ -262,55 +243,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; -} - -/// 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 for ThisHeaderChain { - fn finalized_header_state_root(_hash: HashOf) -> Option> { - unreachable!() - } -} - -/// Call origin at `BridgedChain`. -#[derive(Clone, Debug)] -pub struct BridgedChainOrigin; - -impl From - for Result, BridgedChainOrigin> -{ - fn from( - _origin: BridgedChainOrigin, - ) -> Result, BridgedChainOrigin> { - unreachable!() - } -} - /// Underlying chain of `ThisChain`. pub struct ThisUnderlyingChain; @@ -337,29 +269,20 @@ impl Chain for ThisUnderlyingChain { } } -/// The chain where we are in tests. -pub struct ThisChain; +impl ChainWithMessages for ThisUnderlyingChain { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = ""; -impl UnderlyingChainProvider for ThisChain { - type Chain = ThisUnderlyingChain; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 16; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1000; } -impl ThisChainWithMessages for ThisChain { - type RuntimeOrigin = ThisChainCallOrigin; -} - -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; @@ -388,6 +311,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"; @@ -415,19 +344,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 b3050b9ac0f3..7f43f78b719f 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_trie_leaf_value, record_all_trie_keys, StorageProofSize}; use codec::Encode; use frame_support::traits::Get; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index 573d0ba47668..63a2dc255f7b 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -17,26 +17,29 @@ 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-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", "codec/std", @@ -48,6 +51,7 @@ std = [ "scale-info/std", "sp-runtime/std", "sp-std/std", + "sp-trie/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -62,3 +66,6 @@ try-runtime = [ "pallet-balances/try-runtime", "sp-runtime/try-runtime", ] +test-helpers = [ + "sp-trie", +] diff --git a/bridges/modules/messages/README.md b/bridges/modules/messages/README.md index c06b96b857de..80fd92eb0e5a 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 ee969d727ddc..41d6b463a123 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -20,23 +20,21 @@ 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::{HashOf, StorageProofSize}; use codec::Decode; use frame_benchmarking::{account, v2::*}; use frame_support::weights::Weight; use frame_system::RawOrigin; -use sp_runtime::{ - traits::{Get, TrailingZeroInput}, - BoundedVec, -}; +use sp_runtime::{traits::TrailingZeroInput, BoundedVec}; use sp_std::{ops::RangeInclusive, prelude::*}; const SEED: u32 = 0; @@ -99,11 +97,11 @@ pub trait Config: crate::Config { /// Prepare messages proof to receive by the module. fn prepare_message_proof( params: MessageProofParams, - ) -> (::MessagesProof, Weight); + ) -> (FromBridgedChainMessagesProof>>, Weight); /// Prepare messages delivery proof to receive by the module. fn prepare_message_delivery_proof( params: MessageDeliveryProofParams, - ) -> >::MessagesDeliveryProof; + ) -> FromBridgedChainMessagesDeliveryProof>>; /// Returns true if message has been successfully dispatched or not. fn is_message_successfully_dispatched(_nonce: MessageNonce) -> bool { @@ -190,7 +188,7 @@ mod benchmarks { // fn max_msgs, I: 'static>() -> u32 { - T::MaxUnconfirmedMessagesAtInboundLane::get() as u32 - + T::BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX as u32 - ReceiveMessagesProofSetup::::LATEST_RECEIVED_NONCE as u32 } @@ -520,5 +518,9 @@ mod benchmarks { assert!(T::is_message_successfully_dispatched(setup.last_nonce())); } - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime); + 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 da1698e6e037..1c5585463c8b 100644 --- a/bridges/modules/messages/src/inbound_lane.rs +++ b/bridges/modules/messages/src/inbound_lane.rs @@ -16,15 +16,14 @@ //! 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 codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; -use frame_support::traits::Get; use scale_info::{Type, TypeInfo}; use sp_runtime::RuntimeDebug; use sp_std::prelude::PartialEq; @@ -101,7 +100,7 @@ impl, I: 'static> TypeInfo for StoredInboundLaneData { impl, I: 'static> MaxEncodedLen for StoredInboundLaneData { fn max_encoded_len() -> usize { InboundLaneData::::encoded_size_hint( - T::MaxUnrewardedRelayerEntriesAtInboundLane::get() as usize, + BridgedChainOf::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as usize, ) .unwrap_or(usize::MAX) } @@ -216,10 +215,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 +371,7 @@ mod tests { fn fails_to_receive_messages_above_unrewarded_relayer_entries_limit_per_lane() { run_test(|| { let mut lane = inbound_lane::(TEST_LANE_ID); - let max_nonce = - ::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::( @@ -409,7 +407,7 @@ mod tests { fn fails_to_receive_messages_above_unconfirmed_messages_limit_per_lane() { run_test(|| { let mut lane = inbound_lane::(TEST_LANE_ID); - let max_nonce = ::MaxUnconfirmedMessagesAtInboundLane::get(); + let max_nonce = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; for current_nonce in 1..=max_nonce { assert_eq!( lane.receive_message::( diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index e31a4542056c..cff7eb9dd6d0 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -50,20 +50,22 @@ 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, + BasicOperatingMode, HashOf, OwnedBridgeModule, PreComputedSize, RangeInclusiveExt, Size, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound}; @@ -72,6 +74,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 +83,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,39 +108,16 @@ 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; + /// This chain type. + type ThisChain: ChainWithMessages; + /// Bridged chain type. + type BridgedChain: ChainWithMessages; + /// Bridged chain headers provider. + type BridgedHeaderChain: HeaderChain; /// 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; - /// 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; - - /// Maximal encoded size of the outbound payload. - #[pallet::constant] - type MaximalOutboundPayloadSize: Get; + /// Payload type of outbound messages. This payload is dispatched on the bridged chain. type OutboundPayload: Parameter + Size; @@ -146,13 +126,9 @@ pub mod pallet { /// 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; // Types that are used by outbound_lane (on source chain). - /// Target header chain. - type TargetHeaderChain: TargetHeaderChain; /// Delivery confirmation payments. type DeliveryConfirmationPayments: DeliveryConfirmationPayments; /// Delivery confirmation callback. @@ -160,21 +136,18 @@ pub mod pallet { // 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. type MessageDispatch: MessageDispatch; + /// Delivery payments. + type DeliveryPayments: DeliveryPayments; } - /// Shortcut to messages proof type for Config. - pub type MessagesProofOf = - <>::SourceHeaderChain as SourceHeaderChain>::MessagesProof; - /// Shortcut to messages delivery proof type for Config. - pub type MessagesDeliveryProofOf = - <>::TargetHeaderChain as TargetHeaderChain< - >::OutboundPayload, - ::AccountId, - >>::MessagesDeliveryProof; + /// Shortcut to this chain type for Config. + pub type ThisChainOf = >::ThisChain; + /// Shortcut to bridged chain type for Config. + pub type BridgedChainOf = >::BridgedChain; + /// Shortcut to bridged header chain type for Config. + pub type BridgedHeaderChainOf = >::BridgedHeaderChain; #[pallet::pallet] pub struct Pallet(PhantomData<(T, I)>); @@ -269,7 +242,7 @@ pub mod pallet { pub fn receive_messages_proof( origin: OriginFor, relayer_id_at_bridged_chain: T::InboundRelayer, - proof: MessagesProofOf, + proof: FromBridgedChainMessagesProof>>, messages_count: u32, dispatch_weight: Weight, ) -> DispatchResultWithPostInfo { @@ -278,7 +251,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::::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, Error::::TooManyMessagesInTheProof ); @@ -303,15 +277,12 @@ pub mod pallet { 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::(proof, messages_count) + .map_err(|err| { + log::trace!(target: LOG_TARGET, "Rejecting invalid messages proof: {:?}", err,); - Error::::InvalidMessagesProof - })?; + Error::::InvalidMessagesProof + })?; // dispatch messages and (optionally) update lane(s) state(s) let mut total_messages = 0; @@ -424,14 +395,14 @@ pub mod pallet { ))] pub fn receive_messages_delivery_proof( origin: OriginFor, - proof: MessagesDeliveryProofOf, + proof: FromBridgedChainMessagesDeliveryProof>>, mut relayers_state: UnrewardedRelayersState, ) -> DispatchResultWithPostInfo { Self::ensure_not_halted().map_err(Error::::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::(proof) .map_err(|err| { log::trace!( target: LOG_TARGET, @@ -714,18 +685,6 @@ where // let's check if outbound lane is active ensure!(T::ActiveOutboundLanes::get().contains(&lane), Error::::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::::MessageRejectedByChainVerifier(err) - })?; - Ok(SendMessageArgs { lane_id: lane, payload: StoredMessagePayload::::try_from(message.encode()).map_err(|_| { @@ -802,7 +761,7 @@ impl, I: 'static> RuntimeInboundLaneStorage { /// 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 { @@ -823,11 +782,11 @@ impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage< } fn max_unrewarded_relayer_entries(&self) -> MessageNonce { - T::MaxUnrewardedRelayerEntriesAtInboundLane::get() + BridgedChainOf::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX } fn max_unconfirmed_messages(&self) -> MessageNonce { - T::MaxUnconfirmedMessagesAtInboundLane::get() + BridgedChainOf::::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX } fn get_or_init_data(&mut self) -> InboundLaneData { @@ -887,14 +846,14 @@ impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag } /// Verify messages proof and return proved messages with decoded payload. -fn verify_and_decode_messages_proof( - proof: Chain::MessagesProof, +fn verify_and_decode_messages_proof, I: 'static>( + proof: FromBridgedChainMessagesProof>>, messages_count: u32, -) -> Result>, VerificationError> { - // `receive_messages_proof` weight formula and `MaxUnconfirmedMessagesAtInboundLane` check - // guarantees that the `message_count` is sane and Vec may be allocated. +) -> Result>, VerificationError> { + // `receive_messages_proof` weight formula and `MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX` + // check guarantees that the `message_count` is sane and Vec 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::(proof, messages_count).map(|messages_by_lane| { messages_by_lane .into_iter() .map(|(lane, lane_data)| { @@ -910,1208 +869,1208 @@ fn verify_and_decode_messages_proof::set_block_number(1); - System::::reset_events(); - } - - fn send_regular_message(lane_id: LaneId) { - get_ready_for_events(); - - let outbound_lane = outbound_lane::(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::::validate_message(lane_id, ®ULAR_PAYLOAD) - .expect("validate_message has failed"); - let artifacts = Pallet::::send_message(valid_message); - assert_eq!(artifacts.enqueued_messages, prev_enqueued_messages + 1); - - // check event with assigned nonce - assert_eq!( - System::::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: TestEvent::Messages(Event::MessageAccepted { - lane_id, - nonce: message_nonce - }), - topics: vec![], - }], - ); - } - - fn receive_messages_delivery_proof() { - System::::set_block_number(1); - System::::reset_events(); - - assert_ok!(Pallet::::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::::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::::put(MessagesOperatingMode::Basic( - BasicOperatingMode::Halted, - )); - - assert_noop!( - Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), - Error::::NotOperatingNormally, - ); - - assert_noop!( - Pallet::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(2, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - ), - Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), - ); - - assert_noop!( - Pallet::::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::::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::::put( - MessagesOperatingMode::RejectingOutboundMessages, - ); - - assert_noop!( - Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), - Error::::NotOperatingNormally, - ); - - assert_ok!(Pallet::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - ),); - - assert_ok!(Pallet::::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::::validate_message(TEST_LANE_ID, &message_payload.clone(),), - Error::::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::::validate_message(TEST_LANE_ID, &message_payload) - .expect("validate_message has failed"); - Pallet::::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::::validate_message( - TEST_LANE_ID, - &PAYLOAD_REJECTED_BY_TARGET_CHAIN, - ), - Error::::MessageRejectedByChainVerifier(VerificationError::Other( - mock::TEST_ERROR - )), - ); - }); - } - - #[test] - fn receive_messages_proof_works() { - run_test(|| { - assert_ok!(Pallet::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - )); - - assert_eq!(InboundLanes::::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::::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::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - message_proof, - 1, - REGULAR_PAYLOAD.declared_weight, - )); - - assert_eq!( - InboundLanes::::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::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - REGULAR_PAYLOAD.declared_weight, - ), - Error::::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::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - 1, - declared_weight, - ), - Error::::InsufficientDispatchWeight - ); - assert_eq!(InboundLanes::::get(TEST_LANE_ID).last_delivered_nonce(), 0); - }); - } - - #[test] - fn receive_messages_proof_rejects_invalid_proof() { - run_test(|| { - assert_noop!( - Pallet::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Err(()).into(), - 1, - Weight::zero(), - ), - Error::::InvalidMessagesProof, - ); - }); - } - - #[test] - fn receive_messages_proof_rejects_proof_with_too_many_messages() { - run_test(|| { - assert_noop!( - Pallet::::receive_messages_proof( - RuntimeOrigin::signed(1), - TEST_RELAYER_A, - Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), - u32::MAX, - Weight::zero(), - ), - Error::::TooManyMessagesInTheProof, - ); - }); - } - - #[test] - fn receive_messages_delivery_proof_works() { - run_test(|| { - send_regular_message(TEST_LANE_ID); - receive_messages_delivery_proof(); - - assert_eq!( - OutboundLanes::::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::::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::::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::::receive_messages_delivery_proof( - RuntimeOrigin::signed(1), - TestMessagesDeliveryProof(Err(())), - Default::default(), - ), - Error::::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::::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::::InvalidUnrewardedRelayersState, - ); - - // when number of messages is invalid - assert_noop!( - Pallet::::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::::InvalidUnrewardedRelayersState, - ); - - // when last delivered nonce is invalid - assert_noop!( - Pallet::::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::::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::::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::::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::::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::::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::::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::::InsufficientDispatchWeight - ); - assert_eq!(InboundLanes::::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 = - ::WeightInfo::receive_messages_proof_weight( - &proof, - messages_count, - REGULAR_PAYLOAD.declared_weight, - ); - let result = Pallet::::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 = - ::WeightInfo::receive_messages_proof_weight( - &proof, - messages_count, - REGULAR_PAYLOAD.declared_weight, - ); - InboundLanes::::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::::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::::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::::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::::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::::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::::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::::ReceptionConfirmation( - ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected - ), - ); - }); - } - - #[test] - fn storage_keys_computed_properly() { - assert_eq!( - PalletOperatingMode::::storage_value_final_key().to_vec(), - bp_messages::storage_keys::operating_mode_key("Messages").0, - ); - - assert_eq!( - OutboundMessages::::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::::storage_map_final_key(TEST_LANE_ID), - bp_messages::storage_keys::outbound_lane_data_key("Messages", &TEST_LANE_ID).0, - ); - - assert_eq!( - InboundLanes::::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::::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::::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::(TEST_LANE_ID).data().latest_received_nonce, - 4 - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 1 - ); - System::::set_block_number(2); - - // if passed wight is too low to do anything - let dbw = DbWeight::get(); - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 1)), - Weight::zero(), - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 1 - ); - - // if passed wight is enough to prune single message - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 2)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 2 - ); - - // if passed wight is enough to prune two more messages - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 3)), - dbw.reads_writes(1, 3), - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 4 - ); - - // if passed wight is enough to prune many messages - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, - 1 - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 1 - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, - 1 - ); - assert_eq!( - outbound_lane::(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::::set_block_number(2); - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 2 - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 1 - ); - - // in block#3.on_idle lane messages of lane 2 are pruned - System::::set_block_number(3); - - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, - 2 - ); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 2 - ); - }); - } - - #[test] - fn outbound_message_from_unconfigured_lane_is_rejected() { - run_test(|| { - assert_noop!( - Pallet::::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), - Error::::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::::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::::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 { - UnrewardedRelayer { relayer: 42u64, messages: DeliveredMessages { begin: 0, end: 100 } } - } - - fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage { - 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::::get(), - Some(mock::ActiveOutboundLanes::get().len() as u32) - ); - } -} +// #[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::::set_block_number(1); +// System::::reset_events(); +// } +// +// fn send_regular_message(lane_id: LaneId) { +// get_ready_for_events(); +// +// let outbound_lane = outbound_lane::(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::::validate_message(lane_id, ®ULAR_PAYLOAD) +// .expect("validate_message has failed"); +// let artifacts = Pallet::::send_message(valid_message); +// assert_eq!(artifacts.enqueued_messages, prev_enqueued_messages + 1); +// +// // check event with assigned nonce +// assert_eq!( +// System::::events(), +// vec![EventRecord { +// phase: Phase::Initialization, +// event: TestEvent::Messages(Event::MessageAccepted { +// lane_id, +// nonce: message_nonce +// }), +// topics: vec![], +// }], +// ); +// } +// +// fn receive_messages_delivery_proof() { +// System::::set_block_number(1); +// System::::reset_events(); +// +// assert_ok!(Pallet::::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::::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::::put(MessagesOperatingMode::Basic( +// BasicOperatingMode::Halted, +// )); +// +// assert_noop!( +// Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), +// Error::::NotOperatingNormally, +// ); +// +// assert_noop!( +// Pallet::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Ok(vec![message(2, REGULAR_PAYLOAD)]).into(), +// 1, +// REGULAR_PAYLOAD.declared_weight, +// ), +// Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), +// ); +// +// assert_noop!( +// Pallet::::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::::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::::put( +// MessagesOperatingMode::RejectingOutboundMessages, +// ); +// +// assert_noop!( +// Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), +// Error::::NotOperatingNormally, +// ); +// +// assert_ok!(Pallet::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), +// 1, +// REGULAR_PAYLOAD.declared_weight, +// ),); +// +// assert_ok!(Pallet::::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::::validate_message(TEST_LANE_ID, &message_payload.clone(),), +// Error::::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::::validate_message(TEST_LANE_ID, &message_payload) +// .expect("validate_message has failed"); +// Pallet::::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::::validate_message( +// TEST_LANE_ID, +// &PAYLOAD_REJECTED_BY_TARGET_CHAIN, +// ), +// Error::::MessageRejectedByChainVerifier(VerificationError::Other( +// mock::TEST_ERROR +// )), +// ); +// }); +// } +// +// #[test] +// fn receive_messages_proof_works() { +// run_test(|| { +// assert_ok!(Pallet::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), +// 1, +// REGULAR_PAYLOAD.declared_weight, +// )); +// +// assert_eq!(InboundLanes::::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::::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::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// message_proof, +// 1, +// REGULAR_PAYLOAD.declared_weight, +// )); +// +// assert_eq!( +// InboundLanes::::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::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), +// 1, +// REGULAR_PAYLOAD.declared_weight, +// ), +// Error::::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::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), +// 1, +// declared_weight, +// ), +// Error::::InsufficientDispatchWeight +// ); +// assert_eq!(InboundLanes::::get(TEST_LANE_ID).last_delivered_nonce(), 0); +// }); +// } +// +// #[test] +// fn receive_messages_proof_rejects_invalid_proof() { +// run_test(|| { +// assert_noop!( +// Pallet::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Err(()).into(), +// 1, +// Weight::zero(), +// ), +// Error::::InvalidMessagesProof, +// ); +// }); +// } +// +// #[test] +// fn receive_messages_proof_rejects_proof_with_too_many_messages() { +// run_test(|| { +// assert_noop!( +// Pallet::::receive_messages_proof( +// RuntimeOrigin::signed(1), +// TEST_RELAYER_A, +// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), +// u32::MAX, +// Weight::zero(), +// ), +// Error::::TooManyMessagesInTheProof, +// ); +// }); +// } +// +// #[test] +// fn receive_messages_delivery_proof_works() { +// run_test(|| { +// send_regular_message(TEST_LANE_ID); +// receive_messages_delivery_proof(); +// +// assert_eq!( +// OutboundLanes::::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::::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::::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::::receive_messages_delivery_proof( +// RuntimeOrigin::signed(1), +// TestMessagesDeliveryProof(Err(())), +// Default::default(), +// ), +// Error::::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::::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::::InvalidUnrewardedRelayersState, +// ); +// +// // when number of messages is invalid +// assert_noop!( +// Pallet::::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::::InvalidUnrewardedRelayersState, +// ); +// +// // when last delivered nonce is invalid +// assert_noop!( +// Pallet::::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::::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::::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::::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::::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::::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::::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::::InsufficientDispatchWeight +// ); +// assert_eq!(InboundLanes::::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 = +// ::WeightInfo::receive_messages_proof_weight( +// &proof, +// messages_count, +// REGULAR_PAYLOAD.declared_weight, +// ); +// let result = Pallet::::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 = +// ::WeightInfo::receive_messages_proof_weight( +// &proof, +// messages_count, +// REGULAR_PAYLOAD.declared_weight, +// ); +// InboundLanes::::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::::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::::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::::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::::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::::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::::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::::ReceptionConfirmation( +// ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected +// ), +// ); +// }); +// } +// +// #[test] +// fn storage_keys_computed_properly() { +// assert_eq!( +// PalletOperatingMode::::storage_value_final_key().to_vec(), +// bp_messages::storage_keys::operating_mode_key("Messages").0, +// ); +// +// assert_eq!( +// OutboundMessages::::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::::storage_map_final_key(TEST_LANE_ID), +// bp_messages::storage_keys::outbound_lane_data_key("Messages", &TEST_LANE_ID).0, +// ); +// +// assert_eq!( +// InboundLanes::::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::::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::::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::(TEST_LANE_ID).data().latest_received_nonce, +// 4 +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 1 +// ); +// System::::set_block_number(2); +// +// // if passed wight is too low to do anything +// let dbw = DbWeight::get(); +// assert_eq!( +// Pallet::::on_idle(0, dbw.reads_writes(1, 1)), +// Weight::zero(), +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 1 +// ); +// +// // if passed wight is enough to prune single message +// assert_eq!( +// Pallet::::on_idle(0, dbw.reads_writes(1, 2)), +// dbw.reads_writes(1, 2), +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 2 +// ); +// +// // if passed wight is enough to prune two more messages +// assert_eq!( +// Pallet::::on_idle(0, dbw.reads_writes(1, 3)), +// dbw.reads_writes(1, 3), +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 4 +// ); +// +// // if passed wight is enough to prune many messages +// assert_eq!( +// Pallet::::on_idle(0, dbw.reads_writes(100, 100)), +// dbw.reads_writes(1, 2), +// ); +// assert_eq!( +// outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, +// 1 +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 1 +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, +// 1 +// ); +// assert_eq!( +// outbound_lane::(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::::set_block_number(2); +// assert_eq!( +// Pallet::::on_idle(0, dbw.reads_writes(100, 100)), +// dbw.reads_writes(1, 2), +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 2 +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, +// 1 +// ); +// +// // in block#3.on_idle lane messages of lane 2 are pruned +// System::::set_block_number(3); +// +// assert_eq!( +// Pallet::::on_idle(0, dbw.reads_writes(100, 100)), +// dbw.reads_writes(1, 2), +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, +// 2 +// ); +// assert_eq!( +// outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, +// 2 +// ); +// }); +// } +// +// #[test] +// fn outbound_message_from_unconfigured_lane_is_rejected() { +// run_test(|| { +// assert_noop!( +// Pallet::::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), +// Error::::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::::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::::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 { +// UnrewardedRelayer { relayer: 42u64, messages: DeliveredMessages { begin: 0, end: 100 } } +// } +// +// fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage { +// 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::::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 acef5546d2a6..2508ea9a4c41 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -18,16 +18,19 @@ 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_std::{collections::vec_deque::VecDeque, marker::PhantomData}; /// Outbound lane storage. pub trait OutboundLaneStorage { @@ -48,8 +51,17 @@ pub trait OutboundLaneStorage { fn remove_message(&mut self, nonce: &MessageNonce); } +/// Limit for the `StoredMessagePayload` vector. +pub struct StoredMessagePayloadLimit(PhantomData<(T, I)>); + +impl, I: 'static> Get for StoredMessagePayloadLimit { + fn get() -> u32 { + T::BridgedChain::maximal_incoming_message_size() + } +} + /// Outbound message data wrapper that implements `MaxEncodedLen`. -pub type StoredMessagePayload = BoundedVec>::MaximalOutboundPayloadSize>; +pub type StoredMessagePayload = BoundedVec>; /// Result of messages receival confirmation. #[derive(Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] @@ -204,11 +216,11 @@ fn ensure_unrewarded_relayers_are_correct( 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; diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs new file mode 100644 index 000000000000..9d331d846d8c --- /dev/null +++ b/bridges/modules/messages/src/proofs.rs @@ -0,0 +1,503 @@ +// 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 . + +//! Tools for messages and delivery proof verification. + +use crate::{BridgedChainOf, BridgedHeaderChainOf, Config}; + +use bp_header_chain::HeaderChain; +use bp_messages::{ + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::{FromBridgedChainMessagesProof, ProvedLaneMessages, ProvedMessages}, + ChainWithMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, + OutboundLaneData, VerificationError, +}; +use bp_runtime::{HashOf, RangeInclusiveExt, TrustedVecDb}; +use sp_std::vec::Vec; + +/// 'Parsed' message delivery proof - inbound lane id and its state. +pub(crate) type ParsedMessagesDeliveryProofFromBridgedChain = + (LaneId, InboundLaneData<::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, I: 'static>( + proof: FromBridgedChainMessagesProof>>, + messages_count: u32, +) -> Result, VerificationError> { + let FromBridgedChainMessagesProof { + bridged_header_hash, + storage, + lane, + nonces_start, + nonces_end, + } = proof; + let storage = BridgedHeaderChainOf::::verify_vec_db_storage(bridged_header_hash, storage) + .map_err(VerificationError::HeaderChain)?; + let mut parser = StorageAdapter:: { 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 `VecDb` doesn't have any untouched keys. + parser.storage.ensure_no_unused_keys().map_err(VerificationError::VecDb)?; + + // 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, I: 'static>( + proof: FromBridgedChainMessagesDeliveryProof>>, +) -> Result, VerificationError> { + let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = proof; + let mut storage = + T::BridgedHeaderChain::verify_vec_db_storage(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 = storage + .get_and_decode_mandatory(&storage_inbound_lane_data_key) + .map_err(VerificationError::InboundLaneStorage)?; + + // check that the storage proof doesn't have any untouched trie nodes + storage.ensure_no_unused_keys().map_err(VerificationError::VecDb)?; + + Ok((lane, inbound_lane_data)) +} + +struct StorageAdapter { + storage: TrustedVecDb, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl, I: 'static> StorageAdapter { + fn read_and_decode_outbound_lane_data( + &mut self, + lane_id: &LaneId, + ) -> Result, VerificationError> { + let storage_outbound_lane_data_key = bp_messages::storage_keys::outbound_lane_data_key( + T::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + lane_id, + ); + + self.storage + .get_and_decode_optional(&storage_outbound_lane_data_key) + .map_err(VerificationError::OutboundLaneStorage) + } + + fn read_and_decode_message_payload( + &mut self, + message_key: &MessageKey, + ) -> Result { + 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.storage + .get_and_decode_mandatory(&storage_message_key) + .map_err(VerificationError::MessageStorage) + } +} + +#[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::{HeaderChainError, StoredHeaderDataBuilder}; + use bp_runtime::{HeaderId, VecDbError}; + use codec::Encode; + use sp_runtime::traits::Header; + + fn using_messages_proof( + nonces_end: MessageNonce, + outbound_lane_data: Option, + encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, + encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, + add_duplicate_key: bool, + add_unused_key: bool, + test: impl Fn(FromBridgedChainMessagesProof) -> R, + ) -> R { + let (state_root, storage) = prepare_messages_storage_proof::( + TEST_LANE_ID, + 1..=nonces_end, + outbound_lane_data, + bp_runtime::StorageProofSize::Minimal(0), + 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::::put(HeaderId( + 0, + bridged_header_hash, + )); + pallet_bridge_grandpa::ImportedHeaders::::insert( + bridged_header_hash, + bridged_header.build(), + ); + test(FromBridgedChainMessagesProof { + bridged_header_hash, + storage, + 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::(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::(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::::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::::remove( + bridged_header_hash, + ); + verify_messages_proof::(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::::get().unwrap().1; + pallet_bridge_grandpa::ImportedHeaders::::insert( + bridged_header_hash, + BridgedChainHeader::new( + 0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ) + .build(), + ); + verify_messages_proof::(proof, 10) + } + ), + Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), + ); + } + + #[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::(proof, 10) }, + ), + Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), + ); + } + + #[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::(proof, 10) }, + ), + Err(VerificationError::VecDb(VecDbError::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::(proof, 10) + ), + Err(VerificationError::MessageStorage(VecDbError::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::(proof, 10), + ), + Err(VerificationError::MessageStorage(VecDbError::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::(proof, 10), + ), + Err(VerificationError::OutboundLaneStorage(VecDbError::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::(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::(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::(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::(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 58% rename from bridges/bin/runtime-common/src/messages_generation.rs rename to bridges/modules/messages/src/tests/messages_generation.rs index 21b7a6fa7490..6d0969004f7e 100644 --- a/bridges/bin/runtime-common/src/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -15,25 +15,29 @@ // along with Parity Bridges Common. If not, see . //! Helpers for generating message storage proofs, that are used by tests and by benchmarks. - -use crate::messages::{AccountIdOf, BridgedChain, HashOf, HasherOf, MessageBridge, ThisChain}; +// TODO: remove me in https://github.com/paritytech/parity-bridges-common/issues/1666 +#![allow(dead_code)] use bp_messages::{ - storage_keys, InboundLaneData, LaneId, MessageKey, MessageNonce, MessagePayload, - OutboundLaneData, + storage_keys, ChainWithMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, + MessagePayload, OutboundLaneData, }; use bp_runtime::{ - record_all_trie_keys, Chain, RangeInclusiveExt, RawStorageProof, StorageProofSize, - UnderlyingChainOf, UntrustedVecDb, + grow_trie_leaf_value, record_all_trie_keys, AccountIdOf, Chain, HashOf, HasherOf, + RangeInclusiveExt, StorageProofSize, UntrustedVecDb, }; use codec::Encode; use frame_support::sp_runtime::StateVersion; use sp_std::{ops::RangeInclusive, prelude::*}; use sp_trie::{ - trie_types::TrieDBMutBuilderV1, LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, - TrieDBMutBuilder, TrieMut, + LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, TrieDBMutBuilder, 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> { Some(m.encode()) @@ -48,46 +52,74 @@ pub fn encode_lane_data(d: &OutboundLaneData) -> Vec { /// /// Returns state trie root and nodes with prepared messages. #[allow(clippy::too_many_arguments)] -pub fn prepare_messages_storage_proof( +pub fn prepare_messages_storage_proof( lane: LaneId, message_nonces: RangeInclusive, outbound_lane_data: Option, size: StorageProofSize, - message_payload: MessagePayload, + generate_message: impl Fn(MessageNonce) -> MessagePayload, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, add_duplicate_key: bool, add_unused_key: bool, -) -> (HashOf>, UntrustedVecDb) +) -> (HashOf, UntrustedVecDb) +where + HashOf: Copy + Default, +{ + match BridgedChain::STATE_VERSION { + StateVersion::V0 => do_prepare_messages_storage_proof::< + BridgedChain, + ThisChain, + LayoutV0>, + >( + lane, + message_nonces, + outbound_lane_data, + size, + generate_message, + encode_message, + encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, + ), + StateVersion::V1 => do_prepare_messages_storage_proof::< + BridgedChain, + ThisChain, + LayoutV1>, + >( + lane, + message_nonces, + outbound_lane_data, + size, + generate_message, + encode_message, + encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, + ), + } +} + +/// Prepare storage proof that proves given messages delivery. +pub fn prepare_message_delivery_storage_proof( + lane: LaneId, + inbound_lane_data: InboundLaneData>, + size: StorageProofSize, +) -> (HashOf, UntrustedVecDb) where - B: MessageBridge, - HashOf>: Copy + Default, + HashOf: Copy + Default, { - match >>::STATE_VERSION { - StateVersion::V0 => - do_prepare_messages_storage_proof::>>>( - lane, - message_nonces, - outbound_lane_data, - size, - message_payload, - encode_message, - encode_outbound_lane_data, - add_duplicate_key, - add_unused_key, - ), - StateVersion::V1 => - do_prepare_messages_storage_proof::>>>( - lane, - message_nonces, - outbound_lane_data, - size, - message_payload, - encode_message, - encode_outbound_lane_data, - add_duplicate_key, - add_unused_key, - ), + match BridgedChain::STATE_VERSION { + StateVersion::V0 => do_prepare_message_delivery_storage_proof::< + BridgedChain, + ThisChain, + LayoutV0>, + >(lane, inbound_lane_data, size), + StateVersion::V1 => do_prepare_message_delivery_storage_proof::< + BridgedChain, + ThisChain, + LayoutV1>, + >(lane, inbound_lane_data, size), } } @@ -95,21 +127,20 @@ where /// /// Returns state trie root and nodes with prepared messages. #[allow(clippy::too_many_arguments)] -pub fn do_prepare_messages_storage_proof( +fn do_prepare_messages_storage_proof( lane: LaneId, message_nonces: RangeInclusive, outbound_lane_data: Option, size: StorageProofSize, - message_payload: MessagePayload, + generate_message: impl Fn(MessageNonce) -> MessagePayload, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, add_duplicate_key: bool, add_unused_key: bool, -) -> (HashOf>, UntrustedVecDb) +) -> (HashOf, UntrustedVecDb) where - B: MessageBridge, - L: TrieConfiguration>>, - HashOf>: Copy + Default, + L: TrieConfiguration>, + HashOf: Copy + Default, { // prepare Bridged chain storage with messages and (optionally) outbound lane state let message_count = message_nonces.saturating_len(); @@ -122,7 +153,7 @@ where // 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) @@ -132,7 +163,7 @@ where 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, ) @@ -146,8 +177,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"); @@ -172,7 +206,7 @@ where let read_proof = record_all_trie_keys::(&mdb, &root) .map_err(|_| "record_all_trie_keys has failed") .expect("record_all_trie_keys should not fail in benchmarks"); - let storage = UntrustedVecDb::try_new::>>( + let storage = UntrustedVecDb::try_new::>( StorageProof::new(read_proof), root, storage_keys, @@ -183,22 +217,23 @@ where /// Prepare storage proof of given messages delivery. /// -/// Returns state trie root and nodes with prepared messages. -pub fn prepare_message_delivery_storage_proof( +/// Returns state trie root and partial storage trie. +fn do_prepare_message_delivery_storage_proof( lane: LaneId, - inbound_lane_data: InboundLaneData>>, + inbound_lane_data: InboundLaneData>, size: StorageProofSize, -) -> (HashOf>, RawStorageProof) +) -> (HashOf, UntrustedVecDb) where - B: MessageBridge, + L: TrieConfiguration>, + HashOf: 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::>>::new(&mut mdb, &mut root).build(); + let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut root).build(); let inbound_lane_data = grow_trie_leaf_value(inbound_lane_data.encode(), size); trie.insert(&storage_key, &inbound_lane_data) .map_err(|_| "TrieMut::insert has failed") @@ -206,21 +241,14 @@ where } // generate storage proof to be delivered to This chain - let storage_proof = record_all_trie_keys::>>, _>(&mdb, &root) + let read_proof = record_all_trie_keys::(&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, size: StorageProofSize) -> Vec { - 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 + let storage = UntrustedVecDb::try_new::>( + StorageProof::new(read_proof), + root, + vec![storage_key], + ) + .unwrap(); + (root, storage) } diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/tests/mock.rs similarity index 63% rename from bridges/modules/messages/src/mock.rs rename to bridges/modules/messages/src/tests/mock.rs index 3a1e0063d533..5d88f9150743 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -17,30 +17,41 @@ // 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, Size}; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Size, StorageProofSize}; 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 +73,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 = AccountId; + 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; use crate as pallet_bridge_messages; @@ -71,6 +153,7 @@ frame_support::construct_runtime! { { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Event}, + BridgedChainGrandpa: pallet_bridge_grandpa::{Pallet, Call, Event}, Messages: pallet_bridge_messages::{Pallet, Call, Event}, } } @@ -89,10 +172,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; +} + 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 +193,23 @@ 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; 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 +220,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, 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, - ) -> TestMessagesDeliveryProof { + ) -> FromBridgedChainMessagesDeliveryProof { // 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 +253,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 +265,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 +277,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)>; - -/// Test messages proof. -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo)] -pub struct TestMessagesProof { - pub result: Result, -} - -impl Size for TestMessagesProof { - fn size(&self) -> u32 { - 0 - } -} - -impl From, ()>> for TestMessagesProof { - fn from(result: Result, ()>) -> Self { - Self { - result: result.map(|messages| { - let mut messages_by_lane: BTreeMap> = - 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), ()>); - -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 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), 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 +337,6 @@ impl DeliveryConfirmationPayments 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, 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 +455,73 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pub fn run_test(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, + outbound_lane_data: Option, +) -> FromBridgedChainMessagesProof { + // 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) = prepare_messages_storage_proof::( + TEST_LANE_ID, + nonces_start..=nonces_end, + outbound_lane_data, + StorageProofSize::Minimal(0), + |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::::insert( + bridged_header_hash, + StoredHeaderData { number: 0, state_root: storage_root }, + ); + + FromBridgedChainMessagesProof:: { + bridged_header_hash, + storage, + 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, +) -> FromBridgedChainMessagesDeliveryProof { + // first - let's generate storage proof + let (storage_root, storage_proof) = prepare_message_delivery_storage_proof::< + BridgedChain, + ThisChain, + >(lane, inbound_lane_data, StorageProofSize::Minimal(0)); + + // let's now insert bridged chain header into the storage + let bridged_header_hash = Default::default(); + pallet_bridge_grandpa::ImportedHeaders::::insert( + bridged_header_hash, + StoredHeaderData { number: 0, state_root: storage_root }, + ); + + FromBridgedChainMessagesDeliveryProof:: { + 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 000000000000..c3bde5fc2758 --- /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 . + +//! 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 000000000000..be52d12cc390 --- /dev/null +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -0,0 +1,1082 @@ +// 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 . + +//! 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::::set_block_number(1); + System::::reset_events(); +} + +fn send_regular_message(lane_id: LaneId) { + get_ready_for_events(); + + let outbound_lane = outbound_lane::(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::::validate_message(lane_id, ®ULAR_PAYLOAD) + .expect("validate_message has failed"); + let artifacts = Pallet::::send_message(valid_message); + assert_eq!(artifacts.enqueued_messages, prev_enqueued_messages + 1); + + // check event with assigned nonce + assert_eq!( + System::::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: TestEvent::Messages(Event::MessageAccepted { lane_id, nonce: message_nonce }), + topics: vec![], + }], + ); +} + +fn receive_messages_delivery_proof() { + System::::set_block_number(1); + System::::reset_events(); + + assert_ok!(Pallet::::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::::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::::put(MessagesOperatingMode::Basic( + BasicOperatingMode::Halted, + )); + + assert_noop!( + Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), + Error::::NotOperatingNormally, + ); + + let messages_proof = prepare_messages_proof(vec![message(2, REGULAR_PAYLOAD)], None); + assert_noop!( + Pallet::::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + messages_proof, + 1, + REGULAR_PAYLOAD.declared_weight, + ), + Error::::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::::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::::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::::put( + MessagesOperatingMode::RejectingOutboundMessages, + ); + + assert_noop!( + Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), + Error::::NotOperatingNormally, + ); + + assert_ok!(Pallet::::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::::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::::validate_message(TEST_LANE_ID, &message_payload.clone(),), + Error::::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::::validate_message(TEST_LANE_ID, &message_payload) + .expect("validate_message has failed"); + Pallet::::send_message(valid_message); + }) +} + +#[test] +fn receive_messages_proof_works() { + run_test(|| { + assert_ok!(Pallet::::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::::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::::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::::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::::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::::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + 1, + declared_weight, + ), + Error::::InsufficientDispatchWeight + ); + assert_eq!(InboundLanes::::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::::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + 1, + Weight::zero(), + ), + Error::::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::::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + u32::MAX, + Weight::zero(), + ), + Error::::TooManyMessagesInTheProof, + ); + }); +} + +#[test] +fn receive_messages_delivery_proof_works() { + run_test(|| { + send_regular_message(TEST_LANE_ID); + receive_messages_delivery_proof(); + + assert_eq!(OutboundLanes::::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::::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::::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::::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + Default::default(), + ), + Error::::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::::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 1, + total_messages: 2, + last_delivered_nonce: 2, + ..Default::default() + }, + ), + Error::::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::::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + total_messages: 1, + last_delivered_nonce: 2, + ..Default::default() + }, + ), + Error::::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::::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { + unrewarded_relayer_entries: 2, + total_messages: 2, + last_delivered_nonce: 8, + ..Default::default() + }, + ), + Error::::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::::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::::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::::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::::get(TEST_LANE_ID).last_delivered_nonce(), 3,); + }); +} + +#[test] +fn actual_dispatch_weight_does_not_overlow() { + 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::::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + // this may cause overflow if source chain storage is invalid + proof, + 3, + Weight::MAX, + ), + Error::::InsufficientDispatchWeight + ); + assert_eq!(InboundLanes::::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 = + ::WeightInfo::receive_messages_proof_weight( + &proof, + messages_count, + REGULAR_PAYLOAD.declared_weight, + ); + let result = Pallet::::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 = + ::WeightInfo::receive_messages_proof_weight( + &proof, + messages_count, + REGULAR_PAYLOAD.declared_weight, + ); + InboundLanes::::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::::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::::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::::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::::receive_messages_delivery_proof( + RuntimeOrigin::signed(1), + proof, + UnrewardedRelayersState { last_delivered_nonce: 1, ..Default::default() }, + ), + Error::::ReceptionConfirmation( + ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected + ), + ); + }); +} + +#[test] +fn storage_keys_computed_properly() { + assert_eq!( + PalletOperatingMode::::storage_value_final_key().to_vec(), + bp_messages::storage_keys::operating_mode_key("Messages").0, + ); + + assert_eq!( + OutboundMessages::::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::::storage_map_final_key(TEST_LANE_ID), + bp_messages::storage_keys::outbound_lane_data_key("Messages", &TEST_LANE_ID).0, + ); + + assert_eq!( + InboundLanes::::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::::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::::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::(TEST_LANE_ID).data().latest_received_nonce, 4); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + System::::set_block_number(2); + + // if passed wight is too low to do anything + let dbw = DbWeight::get(); + assert_eq!(Pallet::::on_idle(0, dbw.reads_writes(1, 1)), Weight::zero(),); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + + // if passed wight is enough to prune single message + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(1, 2)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + + // if passed wight is enough to prune two more messages + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(1, 3)), + dbw.reads_writes(1, 3), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 4); + + // if passed wight is enough to prune many messages + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, 1); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, + 1 + ); + assert_eq!( + outbound_lane::(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::::set_block_number(2); + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 1 + ); + + // in block#3.on_idle lane messages of lane 2 are pruned + System::::set_block_number(3); + + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 2 + ); + }); +} + +#[test] +fn outbound_message_from_unconfigured_lane_is_rejected() { + run_test(|| { + assert_noop!( + Pallet::::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), + Error::::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::::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, + FromBridgedChainMessagesDeliveryProof, + >::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::::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, + FromBridgedChainMessagesDeliveryProof, + >::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 { + UnrewardedRelayer { relayer: 42u64, messages: DeliveredMessages { begin: 0, end: 100 } } + } + + fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage { + 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::::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 660a6d4aa9e4..530026120996 100644 --- a/bridges/modules/messages/src/weights.rs +++ b/bridges/modules/messages/src/weights.rs @@ -81,10 +81,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 34_644 nanoseconds. - Weight::from_parts(36_135_000, 52645) + // Minimum execution time: 32_573 nanoseconds. + Weight::from_parts(35_227_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -490,12 +490,12 @@ impl WeightInfo for () { /// The range of component `n` is `[128, 2048]`. fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 75_228 nanoseconds. - Weight::from_parts(62_255_691, 52645) - // Standard Error: 2_005 - .saturating_add(Weight::from_parts(353_141, 0).saturating_mul(n.into())) + // Minimum execution time: 76_504 nanoseconds. + Weight::from_parts(75_331_522, 52645) + // Standard Error: 1_440 + .saturating_add(Weight::from_parts(302_158, 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 3fc23b3ba740..cb0bcd3d3da4 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -450,7 +450,7 @@ impl WeightInfoExt for crate::weights::BridgeWeight #[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/relayers/src/payment_adapter.rs b/bridges/modules/relayers/src/payment_adapter.rs index b2d9c676bddc..f75c409aca4f 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 bfbcc4c31a84..879de67d5420 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -20,18 +20,18 @@ use crate as pallet_xcm_bridge_hub; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, - LaneId, + ChainWithMessages, LaneId, MessageNonce, }; -use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, UnderlyingChainProvider}; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; use bridge_runtime_common::{ - messages::{ - source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, - BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, - }, + // messages::{ + // source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, + // BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, + // }, 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, @@ -85,20 +85,18 @@ 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; type InboundPayload = Vec; type InboundRelayer = (); type DeliveryPayments = (); - type TargetHeaderChain = TargetHeaderChainAdapter; type DeliveryConfirmationPayments = (); type OnMessagesDelivered = (); - type SourceHeaderChain = SourceHeaderChainAdapter; type MessageDispatch = TestMessageDispatch; + + type ThisChain = ThisUnderlyingChain; + type BridgedChain = BridgedUnderlyingChain; + type BridgedHeaderChain = BridgedHeaderChain; } pub struct TestMessagesWeights; @@ -192,9 +190,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; @@ -216,12 +214,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; @@ -242,6 +247,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; @@ -270,42 +281,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 for BridgedHeaderChain { +impl bp_header_chain::HeaderChain for BridgedHeaderChain { fn finalized_header_state_root( - _hash: HashOf, - ) -> Option> { + _hash: HashOf, + ) -> Option> { 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(test: impl FnOnce() -> T) -> T { sp_io::TestExternalities::new( diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 6914b42b6596..740e7c1dea09 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -21,8 +21,8 @@ use bp_header_chain::HeaderChainError; use bp_runtime::{ - messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt, - StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, VecDbError, + messages::MessageDispatchResult, AccountIdOf, BasicOperatingMode, Chain, HashOf, OperatingMode, + RangeInclusiveExt, UnderlyingChainOf, UnderlyingChainProvider, VecDbError, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::PalletError; @@ -48,11 +48,56 @@ 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. + max_extrinsic_size / 3 * 2 } impl ChainWithMessages for T @@ -435,7 +480,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()); @@ -447,6 +492,13 @@ where relayers_rewards } +/// The `BridgeMessagesCall` used by a chain. +pub type BridgeMessagesCallOf = BridgeMessagesCall< + AccountIdOf, + target_chain::FromBridgedChainMessagesProof>, + source_chain::FromBridgedChainMessagesDeliveryProof>, +>; + /// A minimized version of `pallet-bridge-messages::Call` that can be used without a runtime. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] #[allow(non_camel_case_types)] @@ -481,7 +533,7 @@ pub enum VerificationError { /// Error returned by the bridged header chain. HeaderChain(HeaderChainError), /// Error returned while reading/decoding inbound lane data from the storage proof. - InboundLaneStorage(StorageProofError), + InboundLaneStorage(VecDbError), /// The declared message weight is incorrect. InvalidMessageWeight, /// Declared messages count doesn't match actual value. @@ -492,8 +544,6 @@ pub enum VerificationError { MessageTooLarge, /// Error returned while reading/decoding outbound lane data from the `VecDb`. OutboundLaneStorage(VecDbError), - /// Storage proof related error. - StorageProof(StorageProofError), /// `VecDb` related error. VecDb(VecDbError), /// Custom error diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index eb2e14159abc..281ea77151f9 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -16,11 +16,10 @@ //! Primitives of messages module, that are used on the source chain. -use crate::{InboundLaneData, LaneId, MessageNonce, UnrewardedRelayer, VerificationError}; +use crate::{LaneId, MessageNonce, UnrewardedRelayer}; -use bp_runtime::{RawStorageProof, Size}; +use bp_runtime::{Size, UntrustedVecDb}; use codec::{Decode, Encode}; -use frame_support::Parameter; use scale_info::TypeInfo; use sp_core::RuntimeDebug; use sp_std::{ @@ -44,58 +43,20 @@ pub struct FromBridgedChainMessagesDeliveryProof { /// 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, + pub storage_proof: UntrustedVecDb, /// Lane id of which messages were delivered and the proof is for. pub lane: LaneId, } impl Size for FromBridgedChainMessagesDeliveryProof { fn size(&self) -> u32 { - u32::try_from( - self.storage_proof - .iter() - .fold(0usize, |sum, node| sum.saturating_add(node.len())), - ) - .unwrap_or(u32::MAX) + self.storage_proof.size() } } /// Number of messages, delivered by relayers. pub type RelayersRewards = BTreeMap; -/// Target chain API. Used by source chain to verify target 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. -/// -/// 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 { - /// 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), VerificationError>; -} - /// Manages payments that are happening at the source chain during delivery confirmation /// transaction. pub trait DeliveryConfirmationPayments { @@ -175,28 +136,10 @@ pub trait MessagesBridge { 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 TargetHeaderChain 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), VerificationError> { - Err(VerificationError::Other(ALL_OUTBOUND_MESSAGES_REJECTED)) - } -} - impl DeliveryConfirmationPayments 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 1178f4e44ce7..7f678cd13a0f 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -16,13 +16,11 @@ //! 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, UntrustedVecDb}; 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::*}; @@ -87,33 +85,6 @@ pub struct DispatchMessage { pub data: DispatchMessageData, } -/// 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, VerificationError>; -} - /// Called when inbound message is received. pub trait MessageDispatch { /// Decoded message payload type. Valid message may contain invalid payload. In this case @@ -199,29 +170,12 @@ impl DeliveryPayments 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( 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 SourceHeaderChain - for ForbidInboundMessages -{ - type MessagesProof = MessagesProof; - - fn verify_messages_proof( - _proof: Self::MessagesProof, - _messages_count: u32, - ) -> Result, VerificationError> { - Err(VerificationError::Other(ALL_INBOUND_MESSAGES_REJECTED)) - } -} - impl MessageDispatch for ForbidInboundMessages { diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index a5477f002470..b9d29fe06b20 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -41,7 +41,7 @@ pub use chain::{ pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; pub use storage_proof::{ - record_all_keys as record_all_trie_keys, Error as StorageProofError, + grow_trie_leaf_value, record_all_keys as record_all_trie_keys, Error as StorageProofError, ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker, }; pub use storage_types::BoundedStorageValue; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 1b706aa66c16..3b1b31e7012d 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -43,6 +43,18 @@ pub enum ProofSize { HasLargeLeaf(u32), } +/// 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, size: ProofSize) -> Vec { + match size { + ProofSize::Minimal(_) => (), + ProofSize::HasLargeLeaf(size) if size as usize > value.len() => { + value.extend(sp_std::iter::repeat(42u8).take(size as usize - value.len())); + }, + ProofSize::HasLargeLeaf(_) => (), + } + value +} + /// This struct is used to read storage values from a subset of a Merklized database. The "proof" /// is a subset of the nodes in the Merkle structure of the database, so that it provides /// authentication against a known Merkle root as well as the values in the 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 8ce562da3442..68bbe71ae599 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs @@ -197,7 +197,7 @@ where })? .id(); - crate::messages_lane::relay_messages_delivery_confirmation::( + crate::messages::relay_messages_delivery_confirmation::( source_client, target_client, TransactionParams { signer: source_sign, mortality: source_transactions_mortality }, diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index 50246ea438df..cfbb7ecf5de5 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -27,7 +27,6 @@ use crate::{ use async_std::sync::Arc; use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, LaneId, MessageNonce, }; use bp_runtime::{ @@ -391,9 +390,7 @@ where P: SubstrateMessageLane, R: BridgeMessagesConfig>, I: 'static, - R::SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof>, - >, + R::BridgedChain: bp_runtime::Chain>, CallOf: From> + GetDispatchInfo, { fn build_receive_messages_proof_call( @@ -489,11 +486,7 @@ where P: SubstrateMessageLane, R: BridgeMessagesConfig, I: 'static, - R::TargetHeaderChain: bp_messages::source_chain::TargetHeaderChain< - R::OutboundPayload, - R::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof>, - >, + R::BridgedChain: bp_runtime::Chain>, CallOf: From> + GetDispatchInfo, { fn build_receive_messages_delivery_proof_call( diff --git a/bridges/relays/lib-substrate-relay/src/messages/target.rs b/bridges/relays/lib-substrate-relay/src/messages/target.rs index a8395dc4fc74..fdd2619ffc04 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/target.rs @@ -37,6 +37,7 @@ use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, storage_keys::inbound_lane_data_key, ChainWithMessages as _, InboundLaneData, LaneId, MessageNonce, UnrewardedRelayersState, }; +use bp_runtime::{HasherOf, UntrustedVecDb}; use messages_relay::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{NoncesSubmitArtifacts, TargetClient, TargetClientState}, @@ -47,7 +48,8 @@ use relay_substrate_client::{ }; use relay_utils::relay_loop::Client as RelayClient; use sp_core::Pair; -use std::ops::RangeInclusive; +use sp_runtime::traits::Header; +use std::{convert::TryFrom, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. pub type SubstrateMessagesDeliveryProof = @@ -231,19 +233,24 @@ 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 root = *self.target_client.header_by_hash(id.hash()).await?.state_root(); + let read_proof = self.target_client.prove_storage(id.hash(), storage_keys.clone()).await?; + let storage_proof = + UntrustedVecDb::try_new::>(read_proof, root, storage_keys) + .map_err(|e| { + SubstrateError::Custom(format!( + "Error generating messages delivery confirmation storage: {:?}", + e + )) + })?; let proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: id.1, - storage_proof: proof, + storage_proof, lane: self.lane_id, }; Ok((id, (relayers_state, proof))) From acb15cce091a31e38646e2a43b51a18612f634b6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 7 Jun 2023 13:47:33 +0300 Subject: [PATCH 08/58] use BridgedChain::Account instead of InbundRelayer (#2193) --- .../runtime-common/src/messages_call_ext.rs | 9 ++--- bridges/bin/runtime-common/src/mock.rs | 1 - bridges/modules/messages/src/benchmarking.rs | 10 ++--- bridges/modules/messages/src/inbound_lane.rs | 15 +++++--- bridges/modules/messages/src/lib.rs | 38 +++++++++---------- bridges/modules/messages/src/tests/mock.rs | 3 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 1 - .../lib-substrate-relay/src/messages/mod.rs | 5 ++- 8 files changed, 39 insertions(+), 43 deletions(-) diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index 0c860e5451f1..8fc0d5794fd9 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -14,15 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! 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 bp_messages::{ target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, MessageNonce, }; -use bp_runtime::OwnedBridgeModule; +use bp_runtime::{AccountIdOf, OwnedBridgeModule}; use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; -use pallet_bridge_messages::{Config, Pallet}; +use pallet_bridge_messages::{BridgedChainOf, Config, Pallet}; use sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug}; use sp_std::ops::RangeInclusive; @@ -326,7 +325,7 @@ impl< /// Returns occupation state of unrewarded relayers vector. fn unrewarded_relayers_occupation, I: 'static>( - inbound_lane_data: &InboundLaneData, + inbound_lane_data: &InboundLaneData>>, ) -> UnrewardedRelayerOccupation { UnrewardedRelayerOccupation { free_relayer_slots: T::BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index 378d201f1299..2f248a7162a6 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -190,7 +190,6 @@ impl pallet_bridge_messages::Config for TestRuntime { type OutboundPayload = XcmAsPlainPayload; type InboundPayload = Vec; - type InboundRelayer = BridgedChainAccountId; type DeliveryPayments = (); type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 41d6b463a123..9f1b985f23e1 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -29,7 +29,7 @@ use bp_messages::{ InboundLaneData, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; -use bp_runtime::{HashOf, StorageProofSize}; +use bp_runtime::{AccountIdOf, HashOf, StorageProofSize}; use codec::Decode; use frame_benchmarking::{account, v2::*}; use frame_support::weights::Weight; @@ -83,8 +83,8 @@ pub trait Config: crate::Config { /// 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> { + Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap() } /// Create given account and give it enough balance for test purposes. Used to create @@ -132,7 +132,7 @@ fn receive_messages, I: 'static>(nonce: MessageNonce) { } struct ReceiveMessagesProofSetup, I: 'static> { - relayer_id_on_src: T::InboundRelayer, + relayer_id_on_src: AccountIdOf>, relayer_id_on_tgt: T::AccountId, msgs_count: u32, _phantom_data: sp_std::marker::PhantomData, @@ -155,7 +155,7 @@ impl, I: 'static> ReceiveMessagesProofSetup { setup } - fn relayer_id_on_src(&self) -> T::InboundRelayer { + fn relayer_id_on_src(&self) -> AccountIdOf> { self.relayer_id_on_src.clone() } diff --git a/bridges/modules/messages/src/inbound_lane.rs b/bridges/modules/messages/src/inbound_lane.rs index 1c5585463c8b..7ef4599a93c4 100644 --- a/bridges/modules/messages/src/inbound_lane.rs +++ b/bridges/modules/messages/src/inbound_lane.rs @@ -23,6 +23,7 @@ use bp_messages::{ ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, OutboundLaneData, ReceptionResult, UnrewardedRelayer, }; +use bp_runtime::AccountIdOf; use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; use scale_info::{Type, TypeInfo}; use sp_runtime::RuntimeDebug; @@ -54,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, I: 'static>(pub InboundLaneData); +pub struct StoredInboundLaneData, I: 'static>( + pub InboundLaneData>>, +); impl, I: 'static> sp_std::ops::Deref for StoredInboundLaneData { - type Target = InboundLaneData; + type Target = InboundLaneData>>; fn deref(&self) -> &Self::Target { &self.0 @@ -77,7 +80,7 @@ impl, I: 'static> Default for StoredInboundLaneData { } impl, I: 'static> From> - for InboundLaneData + for InboundLaneData>> { fn from(data: StoredInboundLaneData) -> Self { data.0 @@ -85,7 +88,7 @@ impl, I: 'static> From> } impl, I: 'static> EncodeLike> - for InboundLaneData + for InboundLaneData>> { } @@ -93,13 +96,13 @@ impl, I: 'static> TypeInfo for StoredInboundLaneData { type Identity = Self; fn type_info() -> Type { - InboundLaneData::::type_info() + InboundLaneData::>>::type_info() } } impl, I: 'static> MaxEncodedLen for StoredInboundLaneData { fn max_encoded_len() -> usize { - InboundLaneData::::encoded_size_hint( + InboundLaneData::>>::encoded_size_hint( BridgedChainOf::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as usize, ) .unwrap_or(usize::MAX) diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index cff7eb9dd6d0..60c65641d947 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -65,7 +65,8 @@ use bp_messages::{ OutboundMessageDetails, UnrewardedRelayersState, VerificationError, }; use bp_runtime::{ - BasicOperatingMode, HashOf, 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}; @@ -120,26 +121,19 @@ pub mod pallet { /// 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; - - // Types that are used by outbound_lane (on source chain). - /// Delivery confirmation payments. + /// Handler for relayer payments that happen during message delivery transaction. + type DeliveryPayments: DeliveryPayments; + /// Handler for relayer payments that happen during message delivery confirmation + /// transaction. type DeliveryConfirmationPayments: DeliveryConfirmationPayments; /// Delivery confirmation callback. type OnMessagesDelivered: OnMessagesDelivered; - // Types that are used by inbound_lane (on target chain). - - /// Message dispatch. + /// Message dispatch handler. type MessageDispatch: MessageDispatch; - /// Delivery payments. - type DeliveryPayments: DeliveryPayments; } /// Shortcut to this chain type for Config. @@ -241,7 +235,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::receive_messages_proof_weight(proof, *messages_count, *dispatch_weight))] pub fn receive_messages_proof( origin: OriginFor, - relayer_id_at_bridged_chain: T::InboundRelayer, + relayer_id_at_bridged_chain: AccountIdOf>, proof: FromBridgedChainMessagesProof>>, messages_count: u32, dispatch_weight: Weight, @@ -645,7 +639,9 @@ pub mod pallet { } /// Return inbound lane data. - pub fn inbound_lane_data(lane: LaneId) -> InboundLaneData { + pub fn inbound_lane_data( + lane: LaneId, + ) -> InboundLaneData>> { InboundLanes::::get(lane).0 } } @@ -744,7 +740,7 @@ fn outbound_lane, I: 'static>( /// Runtime inbound lane storage. struct RuntimeInboundLaneStorage, I: 'static = ()> { lane_id: LaneId, - cached_data: Option>, + cached_data: Option>>>, _phantom: PhantomData, } @@ -768,14 +764,14 @@ impl, I: 'static> RuntimeInboundLaneStorage { let max_encoded_len = StoredInboundLaneData::::max_encoded_len(); let relayers_count = self.get_or_init_data().relayers.len(); let actual_encoded_len = - InboundLaneData::::encoded_size_hint(relayers_count) + InboundLaneData::>>::encoded_size_hint(relayers_count) .unwrap_or(usize::MAX); max_encoded_len.saturating_sub(actual_encoded_len) as _ } } impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage { - type Relayer = T::InboundRelayer; + type Relayer = AccountIdOf>; fn id(&self) -> LaneId { self.lane_id @@ -789,11 +785,11 @@ impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage< BridgedChainOf::::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX } - fn get_or_init_data(&mut self) -> InboundLaneData { + fn get_or_init_data(&mut self) -> InboundLaneData>> { match self.cached_data { Some(ref data) => data.clone(), None => { - let data: InboundLaneData = + let data: InboundLaneData>> = InboundLanes::::get(self.lane_id).into(); self.cached_data = Some(data.clone()); data @@ -801,7 +797,7 @@ impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage< } } - fn set_data(&mut self, data: InboundLaneData) { + fn set_data(&mut self, data: InboundLaneData>>) { self.cached_data = Some(data.clone()); InboundLanes::::insert(self.lane_id, StoredInboundLaneData::(data)) } diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 5d88f9150743..e6d29b62e4e7 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -115,7 +115,7 @@ impl Chain for BridgedChain { type Hash = BridgedHeaderHash; type Hasher = BlakeTwo256; type Header = BridgedChainHeader; - type AccountId = AccountId; + type AccountId = TestRelayer; type Balance = Balance; type Nonce = u64; type Signature = sp_runtime::MultiSignature; @@ -203,7 +203,6 @@ impl Config for TestRuntime { type OutboundPayload = TestPayload; type InboundPayload = TestPayload; - type InboundRelayer = TestRelayer; type DeliveryPayments = TestDeliveryPayments; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 879de67d5420..434f4295691e 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -88,7 +88,6 @@ impl pallet_bridge_messages::Config for TestRuntime { type ActiveOutboundLanes = ActiveOutboundLanes; type OutboundPayload = Vec; type InboundPayload = Vec; - type InboundRelayer = (); type DeliveryPayments = (); type DeliveryConfirmationPayments = (); type OnMessagesDelivered = (); diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index cfbb7ecf5de5..982795ee3e0e 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -388,9 +388,10 @@ pub struct DirectReceiveMessagesProofCallBuilder { impl ReceiveMessagesProofCallBuilder

for DirectReceiveMessagesProofCallBuilder where P: SubstrateMessageLane, - R: BridgeMessagesConfig>, + R: BridgeMessagesConfig, I: 'static, - R::BridgedChain: bp_runtime::Chain>, + R::BridgedChain: + bp_runtime::Chain, Hash = HashOf>, CallOf: From> + GetDispatchInfo, { fn build_receive_messages_proof_call( From 91d6f6bab15ef215955ffe653976b8d7646a4359 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Wed, 7 Jun 2023 14:10:28 +0300 Subject: [PATCH 09/58] Use compact proofs for parachains (#2194) * Use compact proofs for parachains * Remove StorageProofChecker * Cleanup Reuse messages proof generation from messages pallet (#2195) * reuse messages proof generation from messages pallet * incorrect merge fixed remaining TODOs after messages pallet Config refactoring (#2196) Return UntrustedVecDb from prove_storage() (#2197) Storage proofs related renamings (#2198) * Storage proofs related renamings * Leftovers * StorageSize -> StorageProofSize --- .../extensions/refund_relayer_extension.rs | 6 +- bridges/bin/runtime-common/src/integrity.rs | 81 ++- .../src/messages_benchmarking.rs | 103 +--- .../src/parachains_benchmarking.rs | 51 +- bridges/modules/grandpa/src/lib.rs | 20 +- bridges/modules/messages/src/proofs.rs | 35 +- .../messages/src/tests/messages_generation.rs | 44 +- bridges/modules/parachains/src/call_ext.rs | 4 +- bridges/modules/parachains/src/lib.rs | 18 +- bridges/primitives/header-chain/src/lib.rs | 28 +- bridges/primitives/messages/src/lib.rs | 16 +- .../primitives/messages/src/source_chain.rs | 4 +- .../primitives/messages/src/target_chain.rs | 4 +- .../polkadot-core/src/parachains.rs | 11 +- bridges/primitives/runtime/src/lib.rs | 9 +- .../primitives/runtime/src/storage_proof.rs | 548 +++++++++++------- bridges/primitives/runtime/src/vec_db.rs | 332 ----------- bridges/primitives/test-utils/src/lib.rs | 12 +- .../client-substrate/src/client/caching.rs | 11 +- .../relays/client-substrate/src/client/rpc.rs | 29 +- .../client-substrate/src/client/traits.rs | 21 +- bridges/relays/client-substrate/src/error.rs | 3 - .../src/messages/source.rs | 14 +- .../src/messages/target.rs | 12 +- .../src/parachains/source.rs | 11 +- .../relays/parachains/src/parachains_loop.rs | 4 +- 26 files changed, 603 insertions(+), 828 deletions(-) delete mode 100644 bridges/primitives/runtime/src/vec_db.rs 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 6a982bd7e576..24b9ce9b34c2 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -1121,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() }, }) } @@ -1134,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, }) } @@ -2111,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), ], diff --git a/bridges/bin/runtime-common/src/integrity.rs b/bridges/bin/runtime-common/src/integrity.rs index 9b41a4bf4902..3ea5222d2329 100644 --- a/bridges/bin/runtime-common/src/integrity.rs +++ b/bridges/bin/runtime-common/src/integrity.rs @@ -19,7 +19,9 @@ //! Most of the tests in this module assume that the bridge is using standard (see `crate::messages` //! module for details) configuration. +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; @@ -54,19 +56,24 @@ macro_rules! assert_bridge_messages_pallet_types( ( runtime: $r:path, with_bridged_chain_messages_instance: $i: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_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, XcmAsPlainPayload); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::ThisChain, $this); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::BridgedChain, $bridged); - // TODO: https://github.com/paritytech/parity-bridges-common/issues/1666: check ThisChain, BridgedChain - // and BridgedHeaderChain types + assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, XcmAsPlainPayload); + assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, XcmAsPlainPayload); } } ); @@ -88,6 +95,8 @@ macro_rules! assert_complete_bridge_types( $crate::assert_bridge_messages_pallet_types!( runtime: $r, with_bridged_chain_messages_instance: $mi, + this_chain: $this, + bridged_chain: $bridged, ); } ); @@ -161,14 +170,22 @@ where "ActiveOutboundLanes ({:?}) must not be empty", R::ActiveOutboundLanes::get(), ); + + assert!( + pallet_bridge_messages::BridgedChainOf::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX + <= pallet_bridge_messages::BridgedChainOf::::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::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + pallet_bridge_messages::BridgedChainOf::::ID, + pallet_bridge_messages::BridgedChainOf::::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + ); } /// 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, @@ -179,16 +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(params: AssertBridgePalletNames) +fn assert_bridge_pallet_names(params: AssertBridgePalletNames) where R: pallet_bridge_grandpa::Config + pallet_bridge_messages::Config, GI: 'static, MI: 'static, { + // check that the bridge GRANDPA pallet has required name assert_eq!( pallet_bridge_grandpa::PalletOwner::::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::::storage_value_final_key().to_vec(), bp_runtime::storage_value_key( @@ -201,27 +224,53 @@ 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 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(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( + params: AssertCompleteBridgeConstants, +) where + R: frame_system::Config + + pallet_bridge_grandpa::Config + + pallet_bridge_messages::Config, + GI: 'static, + MI: 'static, +{ + assert_chain_constants::(params.this_chain_constants); + assert_bridge_grandpa_pallet_constants::(); + assert_bridge_messages_pallet_constants::(); + assert_bridge_pallet_names::(AssertBridgePalletNames { + with_bridged_chain_grandpa_pallet_name: + >::BridgedChain::WITH_CHAIN_GRANDPA_PALLET_NAME, + with_bridged_chain_messages_pallet_name: + >::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( + params: AssertCompleteBridgeConstants, +) where R: frame_system::Config + pallet_bridge_grandpa::Config + pallet_bridge_messages::Config, GI: 'static, MI: 'static, + RelayChain: ChainWithGrandpa, { assert_chain_constants::(params.this_chain_constants); assert_bridge_grandpa_pallet_constants::(); assert_bridge_messages_pallet_constants::(); - assert_bridge_pallet_names::(params.pallet_names); + assert_bridge_pallet_names::(AssertBridgePalletNames { + with_bridged_chain_grandpa_pallet_name: RelayChain::WITH_CHAIN_GRANDPA_PALLET_NAME, + with_bridged_chain_messages_pallet_name: + >::BridgedChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + }); } /// Check that the message lane weights are correct. diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index 08d103ee32ae..b339605554da 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -19,42 +19,24 @@ #![cfg(feature = "runtime-benchmarks")] -// use crate::{ -// messages::{BridgedChain, HashOf, ThisChain}, -// messages_generation::{ -// encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, -// prepare_messages_storage_proof, -// }, -// }; - use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, MessagePayload, }; use bp_polkadot_core::parachains::ParaHash; -use bp_runtime::{Chain, Parachain, StorageProofSize}; -// TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 - merge with message -// generation methods from messages pallet and use it here - -use bp_messages::{storage_keys, ChainWithMessages}; -use bp_runtime::{ - grow_trie_leaf_value, record_all_trie_keys, AccountIdOf, HashOf, HasherOf, UntrustedVecDb, -}; +use bp_runtime::{AccountIdOf, Chain, HashOf, Parachain, StorageProofSize}; use codec::Encode; use frame_support::weights::Weight; use pallet_bridge_messages::{ benchmarking::{MessageDeliveryProofParams, MessageProofParams}, - messages_generation::{encode_all_messages, encode_lane_data, prepare_messages_storage_proof}, + messages_generation::{ + encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, + prepare_messages_storage_proof, + }, BridgedChainOf, ThisChainOf, }; -use sp_runtime::{ - traits::{Header, Zero}, - StateVersion, -}; +use sp_runtime::traits::{Header, Zero}; use sp_std::prelude::*; -use sp_trie::{ - LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, TrieDBMutBuilder, TrieMut, -}; use xcm::latest::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. @@ -201,7 +183,10 @@ where { // prepare storage proof let lane = params.lane; - let (state_root, storage_proof) = prepare_message_delivery_proof::(params); + let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< + BridgedChainOf, + ThisChainOf, + >(params.lane, params.inbound_lane_data, params.size); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::(state_root); @@ -229,7 +214,10 @@ where { // prepare storage proof let lane = params.lane; - let (state_root, storage_proof) = prepare_message_delivery_proof::(params); + let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< + BridgedChainOf, + ThisChainOf, + >(params.lane, params.inbound_lane_data, params.size); // update runtime storage let (_, bridged_header_hash) = @@ -242,69 +230,6 @@ where } } -/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage. -fn prepare_message_delivery_proof( - params: MessageDeliveryProofParams>>, -) -> (HashOf>, UntrustedVecDb) -where - R: pallet_bridge_messages::Config, - MI: 'static, -{ - match BridgedChainOf::::STATE_VERSION { - StateVersion::V0 => - do_prepare_message_delivery_proof::>>>( - params, - ), - StateVersion::V1 => - do_prepare_message_delivery_proof::>>>( - params, - ), - } -} - -/// Prepare in-memory message delivery proof, without inserting anything to the runtime storage. -fn do_prepare_message_delivery_proof< - R, - MI, - L: TrieConfiguration>>, ->( - params: MessageDeliveryProofParams>>, -) -> (HashOf>, UntrustedVecDb) -where - R: pallet_bridge_messages::Config, - MI: 'static, -{ - // prepare Bridged chain storage with inbound lane state - let storage_key = storage_keys::inbound_lane_data_key( - R::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, - ¶ms.lane, - ) - .0; - let mut root = Default::default(); - let mut mdb = MemoryDB::default(); - { - let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut root).build(); - let inbound_lane_data = - grow_trie_leaf_value(params.inbound_lane_data.encode(), params.size); - 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 read_proof = record_all_trie_keys::(&mdb, &root) - .map_err(|_| "record_all_trie_keys has failed") - .expect("record_all_trie_keys should not fail in benchmarks"); - let storage_proof = UntrustedVecDb::try_new::>>( - StorageProof::new(read_proof), - root, - vec![storage_key], - ) - .unwrap(); - - (root, storage_proof) -} - /// Insert header to the bridge GRANDPA pallet. pub(crate) fn insert_header_to_grandpa_pallet( state_root: bp_runtime::HashOf, diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index 7f43f78b719f..045653551706 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -22,12 +22,13 @@ 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::{grow_trie_leaf_value, record_all_trie_keys, StorageProofSize}; +use bp_runtime::{grow_storage_value, Chain, StorageProofSize, UnverifiedStorageProof}; use codec::Encode; -use frame_support::traits::Get; +use frame_support::{sp_runtime::StateVersion, traits::Get}; +use pallet_bridge_grandpa::BridgedChain; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; use sp_std::prelude::*; -use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; +use sp_trie::{LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, TrieDBMutBuilder, TrieMut}; /// Prepare proof of messages for the `receive_messages_proof` call. /// @@ -43,7 +44,34 @@ where + pallet_bridge_grandpa::Config, PI: 'static, >::BridgedChain: - bp_runtime::Chain, + Chain, +{ + match as Chain>::STATE_VERSION { + StateVersion::V0 => do_prepare_parachain_heads_proof::>( + parachains, + parachain_head_size, + size, + ), + StateVersion::V1 => do_prepare_parachain_heads_proof::>( + parachains, + parachain_head_size, + size, + ), + } +} + +fn do_prepare_parachain_heads_proof( + parachains: &[ParaId], + parachain_head_size: u32, + size: StorageProofSize, +) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) +where + R: pallet_bridge_parachains::Config + + pallet_bridge_grandpa::Config, + PI: 'static, + >::BridgedChain: + Chain, + L: TrieConfiguration, { let parachain_head = ParaHead(vec![0u8; parachain_head_size as usize]); @@ -53,33 +81,32 @@ where let mut state_root = Default::default(); let mut mdb = MemoryDB::default(); { - let mut trie = - TrieDBMutBuilderV1::::new(&mut mdb, &mut state_root).build(); + let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut state_root).build(); // insert parachain heads for (i, parachain) in parachains.into_iter().enumerate() { 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(), size) } else { parachain_head.encode() }; trie.insert(&storage_key.0, &leaf_data) .map_err(|_| "TrieMut::insert has failed") .expect("TrieMut::insert should not fail in benchmarks"); - storage_keys.push(storage_key); + storage_keys.push(storage_key.0); parachain_heads.push((*parachain, parachain_head.hash())) } } // generate heads storage proof - let proof = record_all_trie_keys::, _>(&mdb, &state_root) - .map_err(|_| "record_all_trie_keys has failed") - .expect("record_all_trie_keys should not fail in benchmarks"); + let storage_proof = + UnverifiedStorageProof::try_from_db::(&mdb, state_root, storage_keys) + .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); let (relay_block_number, relay_block_hash) = insert_header_to_grandpa_pallet::(state_root); - (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof: proof }, parachain_heads) + (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof }, parachain_heads) } diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 3b77f676870e..5a74442ae1bf 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -834,7 +834,7 @@ mod tests { System, TestBridgedChain, TestHeader, TestNumber, TestRuntime, MAX_BRIDGED_AUTHORITIES, }; use bp_header_chain::BridgeGrandpaCall; - use bp_runtime::BasicOperatingMode; + use bp_runtime::{BasicOperatingMode, UnverifiedStorageProof}; use bp_test_utils::{ authority_list, generate_owned_bridge_module_tests, make_default_justification, make_justification_for_header, JustificationGeneratorParams, ALICE, BOB, @@ -1443,11 +1443,14 @@ mod tests { } #[test] - fn parse_finalized_storage_proof_rejects_proof_on_unknown_header() { + fn verify_vec_db_storage_rejects_unknown_header() { run_test(|| { assert_noop!( - Pallet::::storage_proof_checker(Default::default(), vec![],) - .map(|_| ()), + Pallet::::verify_storage_proof( + Default::default(), + Default::default(), + ) + .map(|_| ()), bp_header_chain::HeaderChainError::UnknownHeader, ); }); @@ -1456,7 +1459,10 @@ mod tests { #[test] fn parse_finalized_storage_accepts_valid_proof() { run_test(|| { - let (state_root, storage_proof) = bp_runtime::craft_valid_storage_proof(); + let (state_root, storage_proof) = UnverifiedStorageProof::try_from_entries::< + sp_core::Blake2Hasher, + >(Default::default(), &[(b"key1".to_vec(), None)]) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); let mut header = test_header(2); header.set_state_root(state_root); @@ -1465,9 +1471,7 @@ mod tests { >::put(HeaderId(2, hash)); >::insert(hash, header.build()); - assert_ok!( - Pallet::::storage_proof_checker(hash, storage_proof).map(|_| ()) - ); + assert_ok!(Pallet::::verify_storage_proof(hash, storage_proof).map(|_| ())); }); } diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index 9d331d846d8c..f2bf1d1b0821 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -25,7 +25,7 @@ use bp_messages::{ ChainWithMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, }; -use bp_runtime::{HashOf, RangeInclusiveExt, TrustedVecDb}; +use bp_runtime::{HashOf, RangeInclusiveExt, VerifiedStorageProof}; use sp_std::vec::Vec; /// 'Parsed' message delivery proof - inbound lane id and its state. @@ -51,7 +51,7 @@ pub fn verify_messages_proof, I: 'static>( nonces_start, nonces_end, } = proof; - let storage = BridgedHeaderChainOf::::verify_vec_db_storage(bridged_header_hash, storage) + let storage = BridgedHeaderChainOf::::verify_storage_proof(bridged_header_hash, storage) .map_err(VerificationError::HeaderChain)?; let mut parser = StorageAdapter:: { storage, _dummy: Default::default() }; let nonces_range = nonces_start..=nonces_end; @@ -85,8 +85,11 @@ pub fn verify_messages_proof, I: 'static>( return Err(VerificationError::EmptyMessageProof) } - // Check that the `VecDb` doesn't have any untouched keys. - parser.storage.ensure_no_unused_keys().map_err(VerificationError::VecDb)?; + // Check that the storage proof doesn't have any untouched keys. + parser + .storage + .ensure_no_unused_keys() + .map_err(VerificationError::StorageProof)?; // We only support single lane messages in this generated_schema let mut proved_messages = ProvedMessages::new(); @@ -101,7 +104,7 @@ pub fn verify_messages_delivery_proof, I: 'static>( ) -> Result, VerificationError> { let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = proof; let mut storage = - T::BridgedHeaderChain::verify_vec_db_storage(bridged_header_hash, storage_proof) + T::BridgedHeaderChain::verify_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. @@ -114,13 +117,13 @@ pub fn verify_messages_delivery_proof, I: 'static>( .map_err(VerificationError::InboundLaneStorage)?; // check that the storage proof doesn't have any untouched trie nodes - storage.ensure_no_unused_keys().map_err(VerificationError::VecDb)?; + storage.ensure_no_unused_keys().map_err(VerificationError::StorageProof)?; Ok((lane, inbound_lane_data)) } struct StorageAdapter { - storage: TrustedVecDb, + storage: VerifiedStorageProof, _dummy: sp_std::marker::PhantomData<(T, I)>, } @@ -166,7 +169,7 @@ mod tests { }; use bp_header_chain::{HeaderChainError, StoredHeaderDataBuilder}; - use bp_runtime::{HeaderId, VecDbError}; + use bp_runtime::{HeaderId, StorageProofError}; use codec::Encode; use sp_runtime::traits::Header; @@ -301,7 +304,9 @@ mod tests { verify_messages_proof::(proof, 10) } ), - Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), + Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( + StorageProofError::InvalidProof + ))), ); } @@ -317,7 +322,9 @@ mod tests { false, |proof| { verify_messages_proof::(proof, 10) }, ), - Err(VerificationError::HeaderChain(HeaderChainError::VecDb(VecDbError::InvalidProof))), + Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( + StorageProofError::InvalidProof + ))), ); } @@ -333,7 +340,7 @@ mod tests { true, |proof| { verify_messages_proof::(proof, 10) }, ), - Err(VerificationError::VecDb(VecDbError::UnusedKey)), + Err(VerificationError::StorageProof(StorageProofError::UnusedKey)), ); } @@ -349,7 +356,7 @@ mod tests { false, |proof| verify_messages_proof::(proof, 10) ), - Err(VerificationError::MessageStorage(VecDbError::EmptyVal)), + Err(VerificationError::MessageStorage(StorageProofError::EmptyVal)), ); } @@ -371,7 +378,7 @@ mod tests { false, |proof| verify_messages_proof::(proof, 10), ), - Err(VerificationError::MessageStorage(VecDbError::DecodeError)), + Err(VerificationError::MessageStorage(StorageProofError::DecodeError)), ); } @@ -395,7 +402,7 @@ mod tests { false, |proof| verify_messages_proof::(proof, 10), ), - Err(VerificationError::OutboundLaneStorage(VecDbError::DecodeError)), + Err(VerificationError::OutboundLaneStorage(StorageProofError::DecodeError)), ); } diff --git a/bridges/modules/messages/src/tests/messages_generation.rs b/bridges/modules/messages/src/tests/messages_generation.rs index 6d0969004f7e..56df19cf8809 100644 --- a/bridges/modules/messages/src/tests/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -15,23 +15,19 @@ // along with Parity Bridges Common. If not, see . //! Helpers for generating message storage proofs, that are used by tests and by benchmarks. -// TODO: remove me in https://github.com/paritytech/parity-bridges-common/issues/1666 -#![allow(dead_code)] use bp_messages::{ storage_keys, ChainWithMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, }; use bp_runtime::{ - grow_trie_leaf_value, record_all_trie_keys, AccountIdOf, Chain, HashOf, HasherOf, - RangeInclusiveExt, StorageProofSize, UntrustedVecDb, + grow_storage_value, AccountIdOf, Chain, HashOf, HasherOf, RangeInclusiveExt, StorageProofSize, + UnverifiedStorageProof, }; use codec::Encode; use frame_support::sp_runtime::StateVersion; use sp_std::{ops::RangeInclusive, prelude::*}; -use sp_trie::{ - LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieConfiguration, TrieDBMutBuilder, TrieMut, -}; +use sp_trie::{LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, TrieDBMutBuilder, TrieMut}; /// Dummy message generation function. pub fn generate_dummy_message(_: MessageNonce) -> MessagePayload { @@ -62,7 +58,7 @@ pub fn prepare_messages_storage_proof Vec, add_duplicate_key: bool, add_unused_key: bool, -) -> (HashOf, UntrustedVecDb) +) -> (HashOf, UnverifiedStorageProof) where HashOf: Copy + Default, { @@ -105,7 +101,7 @@ pub fn prepare_message_delivery_storage_proof>, size: StorageProofSize, -) -> (HashOf, UntrustedVecDb) +) -> (HashOf, UnverifiedStorageProof) where HashOf: Copy + Default, { @@ -137,7 +133,7 @@ fn do_prepare_messages_storage_proof Vec, add_duplicate_key: bool, add_unused_key: bool, -) -> (HashOf, UntrustedVecDb) +) -> (HashOf, UnverifiedStorageProof) where L: TrieConfiguration>, HashOf: Copy + Default, @@ -156,7 +152,7 @@ where 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, size) } else { message_payload }, @@ -203,15 +199,10 @@ where } // generate storage proof to be delivered to This chain - let read_proof = record_all_trie_keys::(&mdb, &root) - .map_err(|_| "record_all_trie_keys has failed") - .expect("record_all_trie_keys should not fail in benchmarks"); - let storage = UntrustedVecDb::try_new::>( - StorageProof::new(read_proof), - root, - storage_keys, - ) - .unwrap(); + let storage = + UnverifiedStorageProof::try_from_db::, _>(&mdb, root, storage_keys) + .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); + (root, storage) } @@ -222,7 +213,7 @@ fn do_prepare_message_delivery_storage_proof>, size: StorageProofSize, -) -> (HashOf, UntrustedVecDb) +) -> (HashOf, UnverifiedStorageProof) where L: TrieConfiguration>, HashOf: Copy + Default, @@ -234,21 +225,18 @@ where let mut mdb = MemoryDB::default(); { let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut root).build(); - let inbound_lane_data = grow_trie_leaf_value(inbound_lane_data.encode(), size); + let inbound_lane_data = grow_storage_value(inbound_lane_data.encode(), size); 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 read_proof = record_all_trie_keys::(&mdb, &root) - .map_err(|_| "record_all_trie_keys has failed") - .expect("record_all_trie_keys should not fail in benchmarks"); - let storage = UntrustedVecDb::try_new::>( - StorageProof::new(read_proof), + let storage = UnverifiedStorageProof::try_from_db::, _>( + &mdb, root, vec![storage_key], ) - .unwrap(); + .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); (root, storage) } diff --git a/bridges/modules/parachains/src/call_ext.rs b/bridges/modules/parachains/src/call_ext.rs index fe6b319205d4..0f77eaf2c5a9 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::::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::::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 d323aef3b220..c228cc40571a 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -30,7 +30,7 @@ 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_runtime::{Chain, HashOf, HeaderId, HeaderIdOf, Parachain}; use frame_support::{dispatch::PostDispatchInfo, DefaultNoBound}; use pallet_bridge_grandpa::SubmitFinalityProofHelper; use sp_std::{marker::PhantomData, vec::Vec}; @@ -83,7 +83,7 @@ pub mod pallet { }; use bp_runtime::{ BasicOperatingMode, BoundedStorageValue, OwnedBridgeModule, StorageDoubleMapKeyProvider, - StorageMapKeyProvider, + StorageMapKeyProvider, StorageProofError, VerifiedStorageProof, }; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -448,8 +448,7 @@ pub mod pallet { parachains.len() as _, ); - let mut is_updated_something = false; - let mut storage = GrandpaPalletOf::::storage_proof_checker( + let mut storage = GrandpaPalletOf::::verify_storage_proof( relay_block_hash, parachain_heads_proof.storage_proof, ) @@ -541,7 +540,6 @@ pub mod pallet { parachain_head_hash, )?; - is_updated_something = true; if is_free { free_parachain_heads = free_parachain_heads + 1; } @@ -572,7 +570,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::::HeaderChainStorageProof(HeaderChainError::StorageProof(e)) })?; @@ -635,12 +633,12 @@ pub mod pallet { /// Read parachain head from storage proof. fn read_parachain_head( - storage: &mut bp_runtime::StorageProofChecker, + storage: &mut VerifiedStorageProof, parachain: ParaId, ) -> Result, 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()) + storage.get_and_decode_optional(¶chain_head_key) } /// Try to update parachain head. @@ -846,7 +844,7 @@ pub(crate) mod tests { }; use bp_runtime::{ BasicOperatingMode, OwnedBridgeModuleError, StorageDoubleMapKeyProvider, - StorageMapKeyProvider, + StorageMapKeyProvider, StorageProofError, }; use bp_test_utils::{ authority_list, generate_owned_bridge_module_tests, make_default_justification, @@ -1579,7 +1577,7 @@ pub(crate) mod tests { assert_noop!( import_parachain_1_head(0, Default::default(), parachains, proof), Error::::HeaderChainStorageProof(HeaderChainError::StorageProof( - StorageProofError::StorageRootMismatch + StorageProofError::InvalidProof )) ); }); diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index 22b70d40c1d5..08d7bcd64f3e 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -24,9 +24,8 @@ use crate::justification::{ GrandpaJustification, JustificationVerificationContext, JustificationVerificationError, }; use bp_runtime::{ - BasicOperatingMode, BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, RawStorageProof, - StorageProofChecker, StorageProofError, TrustedVecDb, UnderlyingChainProvider, UntrustedVecDb, - VecDbError, + BasicOperatingMode, BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, StorageProofError, + UnderlyingChainProvider, UnverifiedStorageProof, VerifiedStorageProof, }; use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug}; @@ -47,10 +46,8 @@ 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), - /// Error generated by the `vec_db` module. - VecDb(VecDbError), } /// Header data that we're storing on-chain. @@ -81,24 +78,15 @@ impl StoredHeaderDataBuilder for H { pub trait HeaderChain { /// Returns state (storage) root of given finalized header. fn finalized_header_state_root(header_hash: HashOf) -> Option>; - /// Get a `TrustedVecDb` starting from an `UntrustedVecDb`. - fn verify_vec_db_storage( + /// Get a `VerifiedStorageProof` starting from an `UnverifiedStorageProof`. + fn verify_storage_proof( header_hash: HashOf, - db: UntrustedVecDb, - ) -> Result { + db: UnverifiedStorageProof, + ) -> Result { let state_root = Self::finalized_header_state_root(header_hash) .ok_or(HeaderChainError::UnknownHeader)?; db.verify::>(C::STATE_VERSION, &state_root) - .map_err(HeaderChainError::VecDb) - } - /// Get storage proof checker using finalized header. - fn storage_proof_checker( - header_hash: HashOf, - storage_proof: RawStorageProof, - ) -> Result>, HeaderChainError> { - let state_root = Self::finalized_header_state_root(header_hash) - .ok_or(HeaderChainError::UnknownHeader)?; - StorageProofChecker::new(state_root, storage_proof).map_err(HeaderChainError::StorageProof) + .map_err(HeaderChainError::StorageProof) } } diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 740e7c1dea09..e6540dc33af6 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -22,7 +22,7 @@ use bp_header_chain::HeaderChainError; use bp_runtime::{ messages::MessageDispatchResult, AccountIdOf, BasicOperatingMode, Chain, HashOf, OperatingMode, - RangeInclusiveExt, UnderlyingChainOf, UnderlyingChainProvider, VecDbError, + RangeInclusiveExt, StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::PalletError; @@ -533,19 +533,19 @@ pub enum VerificationError { /// Error returned by the bridged header chain. HeaderChain(HeaderChainError), /// Error returned while reading/decoding inbound lane data from the storage proof. - InboundLaneStorage(VecDbError), + InboundLaneStorage(StorageProofError), /// The declared message weight is incorrect. InvalidMessageWeight, /// Declared messages count doesn't match actual value. MessagesCountMismatch, - /// Error returned while reading/decoding message data from the `VecDb`. - MessageStorage(VecDbError), + /// 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 `VecDb`. - OutboundLaneStorage(VecDbError), - /// `VecDb` related error. - VecDb(VecDbError), + /// Error returned while reading/decoding outbound lane data from the `VerifiedStorageProof`. + OutboundLaneStorage(StorageProofError), + /// Storage proof related error. + StorageProof(StorageProofError), /// Custom error Other(#[codec(skip)] &'static str), } diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index 281ea77151f9..881052b8277a 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -18,7 +18,7 @@ use crate::{LaneId, MessageNonce, UnrewardedRelayer}; -use bp_runtime::{Size, UntrustedVecDb}; +use bp_runtime::{Size, UnverifiedStorageProof}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_core::RuntimeDebug; @@ -43,7 +43,7 @@ pub struct FromBridgedChainMessagesDeliveryProof { /// 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: UntrustedVecDb, + pub storage_proof: UnverifiedStorageProof, /// Lane id of which messages were delivered and the proof is for. pub lane: LaneId, } diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index 7f678cd13a0f..974cb38cbc0a 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -18,7 +18,7 @@ use crate::{LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData}; -use bp_runtime::{messages::MessageDispatchResult, Size, UntrustedVecDb}; +use bp_runtime::{messages::MessageDispatchResult, Size, UnverifiedStorageProof}; use codec::{Decode, Encode, Error as CodecError}; use frame_support::weights::Weight; use scale_info::TypeInfo; @@ -42,7 +42,7 @@ pub struct FromBridgedChainMessagesProof { /// Hash of the finalized bridged header the proof is for. pub bridged_header_hash: BridgedHeaderHash, /// The proved storage containing the messages being delivered. - pub storage: UntrustedVecDb, + pub storage: UnverifiedStorageProof, /// Messages in this proof are sent over this lane. pub lane: LaneId, /// Nonce of the first message being delivered. diff --git a/bridges/primitives/polkadot-core/src/parachains.rs b/bridges/primitives/polkadot-core/src/parachains.rs index 433cd2845abd..87d706a1f4fa 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::{Size, UnverifiedStorageProof}; use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_core::Hasher; @@ -91,16 +91,11 @@ pub type ParaHasher = crate::Hasher; #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct ParaHeadsProof { /// Unverified storage proof of finalized parachain heads. - pub storage_proof: RawStorageProof, + pub storage_proof: UnverifiedStorageProof, } 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) + self.storage_proof.size() } } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index b9d29fe06b20..592242030b25 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -41,14 +41,10 @@ pub use chain::{ pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; pub use storage_proof::{ - grow_trie_leaf_value, record_all_keys as record_all_trie_keys, Error as StorageProofError, - ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker, + grow_storage_value, StorageProofError, StorageProofSize, UnverifiedStorageProof, + VerifiedStorageProof, }; pub use storage_types::BoundedStorageValue; -pub use vec_db::{TrustedVecDb, UntrustedVecDb, VecDbError}; - -#[cfg(feature = "std")] -pub use storage_proof::craft_valid_storage_proof; pub mod extensions; pub mod messages; @@ -56,7 +52,6 @@ pub mod messages; mod chain; mod storage_proof; mod storage_types; -mod vec_db; // Re-export macro to avoid include paste dependency everywhere pub use sp_runtime::paste; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 3b1b31e7012d..abc5a8d86544 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -14,271 +14,399 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! 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, collections::btree_set::BTreeSet, vec::Vec}; +use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; +use sp_runtime::{SaturatedConversion, StateVersion}; +use sp_std::{collections::btree_set::BTreeSet, default::Default, vec, vec::Vec}; use sp_trie::{ - read_trie_value, LayoutV1, MemoryDB, Recorder, StorageProof, Trie, TrieConfiguration, - TrieDBBuilder, TrieError, TrieHash, + generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, PrefixedMemoryDB, StorageProof, + TrieDBBuilder, TrieHash, }; +use codec::{Codec, Decode, Encode}; +use hash_db::Hasher; +use scale_info::TypeInfo; +use sp_state_machine::TrieBackend; +use trie_db::{DBValue, Recorder, Trie}; + +use crate::Size; + /// Raw storage proof type (just raw trie nodes). pub type RawStorageProof = Vec>; -/// Storage proof size requirements. +pub type RawStorageKey = Vec; + +/// 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 in the `VerifiedStorageProof` wasn't read. + UnusedKey, +} + +/// Structure representing a key-value database stored as a sorted `Vec` of tuples. /// -/// 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), +/// The structure also contains a proof of the fact that the key-value tuples are actually present +/// in the chain storage. +#[derive(Clone, Default, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct UnverifiedStorageProof { + proof: RawStorageProof, + db: Vec<(RawStorageKey, Option)>, } -/// 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, size: ProofSize) -> Vec { - match size { - ProofSize::Minimal(_) => (), - ProofSize::HasLargeLeaf(size) if size as usize > value.len() => { - value.extend(sp_std::iter::repeat(42u8).take(size as usize - value.len())); - }, - ProofSize::HasLargeLeaf(_) => (), +impl UnverifiedStorageProof { + /// Creates a new instance of `UnverifiedStorageProof`. + pub fn try_new( + read_proof: StorageProof, + root: TrieHash>, + mut keys: Vec + Ord>, + ) -> Result { + // It's ok to use `LayoutV1` in this function, no matter the actual underlying layout, + // because we only perform read operations. When reading `LayoutV0` and `LayoutV1` lead to + // the same result. + let mem_db = read_proof.into_memory_db(); + let trie_db = TrieDBBuilder::>::new(&mem_db, &root).build(); + + let trie_proof = generate_trie_proof::, _, _, _>(&mem_db, root, &keys) + .map_err(|_| StorageProofError::UnableToGenerateTrieProof)?; + + let mut entries = Vec::with_capacity(keys.len()); + keys.sort(); + for key in keys { + let val = trie_db.get(key.as_ref()).map_err(|_| StorageProofError::UnavailableKey)?; + entries.push((key.as_ref().to_vec(), val)); + } + + Ok(Self { proof: trie_proof, db: entries }) } - value -} -/// This struct is used to read storage values from a subset of a Merklized database. The "proof" -/// is a subset of the nodes in the Merkle structure of the database, so that it provides -/// authentication against a known Merkle root as well as the values in the -/// database themselves. -pub struct StorageProofChecker -where - H: Hasher, -{ - proof_nodes_count: usize, - root: H::Out, - db: MemoryDB, - recorder: Recorder>, -} + /// Creates a new instance of `UnverifiedStorageProof` from the provided entries. + /// + /// **This function is used only in tests and benchmarks.** + #[cfg(feature = "std")] + pub fn try_from_entries( + state_version: StateVersion, + entries: &[(RawStorageKey, Option)], + ) -> Result<(H::Out, UnverifiedStorageProof), StorageProofError> + where + H::Out: Codec, + { + let keys: Vec<_> = entries.iter().map(|(key, _)| key.clone()).collect(); + let entries: Vec<_> = + entries.iter().cloned().map(|(key, val)| (None, vec![(key, val)])).collect(); + let backend = TrieBackend::, H>::from((entries, state_version)); + let root = *backend.root(); + + Ok((root, UnverifiedStorageProof::try_from_db(backend.backend_storage(), root, keys)?)) + } -impl StorageProofChecker -where - H: Hasher, -{ - /// Constructs a new storage proof checker. + /// Creates a new instance of `UnverifiedStorageProof` from the provided db. /// - /// 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 { - // 1. we don't want extra items in the storage proof - // 2. `StorageProof` is storing all trie nodes in the `BTreeSet` - // - // => someone could simply add duplicate items to the proof and we won't be - // able to detect that by just using `StorageProof` - // - // => let's check it when we are converting our "raw proof" into `StorageProof` - let proof_nodes_count = proof.len(); - let proof = StorageProof::new(proof); - if proof_nodes_count != proof.iter_nodes().count() { - return Err(Error::DuplicateNodesInProof) + /// **This function is used only in tests and benchmarks.** + pub fn try_from_db( + db: &DB, + root: H::Out, + keys: Vec + Ord>, + ) -> Result + where + DB: hash_db::HashDBRef, + { + let mut recorder = Recorder::>::new(); + let trie = TrieDBBuilder::>::new(db, &root) + .with_recorder(&mut recorder) + .build(); + for key in &keys { + trie.get(key.as_ref()).map_err(|_| StorageProofError::UnavailableKey)?; } - let db = proof.into_memory_db(); - if !db.contains(&root, EMPTY_PREFIX) { - return Err(Error::StorageRootMismatch) - } + let raw_read_proof: Vec<_> = recorder + .drain() + .into_iter() + .map(|n| n.data) + // recorder may record the same trie node multiple times and we don't want duplicate + // nodes in our proofs => let's deduplicate it by collecting to the BTreeSet first + .collect::>() + .into_iter() + .collect(); - let recorder = Recorder::default(); - let checker = StorageProofChecker { proof_nodes_count, root, db, recorder }; - Ok(checker) + UnverifiedStorageProof::try_new::(StorageProof::new(raw_read_proof), root, keys) } - /// Returns error if the proof has some nodes that are left intact by previous `read_value` - /// calls. - pub fn ensure_no_unused_nodes(mut self) -> Result<(), Error> { - let visited_nodes = self - .recorder - .drain() - .into_iter() - .map(|record| record.data) - .collect::>(); - let visited_nodes_count = visited_nodes.len(); - if self.proof_nodes_count == visited_nodes_count { - Ok(()) - } else { - Err(Error::UnusedNodesInTheProof) + /// Validates the contained `db` against the contained proof. If the `db` is valid, converts it + /// into a `VerifiedStorageProof`. + pub fn verify( + mut self, + state_version: StateVersion, + state_root: &TrieHash>, + ) -> Result { + // First we verify the proof for the `UnverifiedStorageProof`. + // Note that `verify_trie_proof()` also checks for duplicate keys and unused nodes. + match state_version { + StateVersion::V0 => + verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), + StateVersion::V1 => + verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), + } + .map_err(|_| StorageProofError::InvalidProof)?; + + // Fill the `VerifiedStorageProof` + let mut trusted_db = Vec::with_capacity(self.db.len()); + let mut iter = self.db.drain(..).peekable(); + while let Some((key, val)) = iter.next() { + // Let's also make sure that the db is actually sorted. + if let Some((next_key, _)) = iter.peek() { + if next_key <= &key { + return Err(StorageProofError::UnsortedEntries) + } + } + trusted_db.push((TrackedStorageKey::new(key), val)) } + Ok(VerifiedStorageProof { db: trusted_db }) } +} + +impl Size for UnverifiedStorageProof { + fn size(&self) -> u32 { + let proof_size = self.proof.iter().fold(0usize, |sum, node| sum.saturating_add(node.len())); + let entries_size = self.db.iter().fold(0usize, |sum, (key, value)| { + sum.saturating_add(key.len()) + .saturating_add(value.as_ref().unwrap_or(&vec![]).len()) + }); - /// 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>, Error> { - // LayoutV1 or LayoutV0 is identical for proof that only read values. - read_trie_value::, _>(&self.db, &self.root, key, Some(&mut self.recorder), None) - .map_err(|_| Error::StorageValueUnavailable) + proof_size.saturating_add(entries_size).saturated_into() } +} + +/// Structure representing a key-value database stored as a sorted `Vec` of tuples. +pub struct VerifiedStorageProof { + db: Vec<(TrackedStorageKey, Option)>, +} - /// 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(&mut self, key: &[u8]) -> Result, Error> { - self.read_value(key).and_then(|v| { - v.map(|v| T::decode(&mut &v[..]).map_err(|e| Error::StorageValueDecodeFailed(e.into()))) - .transpose() - }) +impl VerifiedStorageProof { + /// Returns a reference to the value corresponding to the key. + /// + /// Returns an error if the key doesn't exist. + pub fn get(&mut self, key: &impl AsRef<[u8]>) -> Result<&Option, StorageProofError> { + let idx = self + .db + .binary_search_by(|(db_key, _)| db_key.key.as_slice().cmp(key.as_ref())) + .map_err(|_| StorageProofError::UnavailableKey)?; + let (db_key, db_val) = self.db.get_mut(idx).ok_or(StorageProofError::UnavailableKey)?; + db_key.add_read(); + Ok(db_val) } - /// 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(&mut self, key: &[u8]) -> Result { - self.read_and_decode_value(key)?.ok_or(Error::StorageValueEmpty) + /// Returns a reference to the value corresponding to the key. + /// + /// Returns an error if the key doesn't exist or if the value associated to it is `None`. + pub fn get_and_decode_mandatory( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result { + let val = self.get(key)?.as_ref().ok_or(StorageProofError::EmptyVal)?; + D::decode(&mut &val[..]).map_err(|_| StorageProofError::DecodeError) } - /// 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(&mut self, key: &[u8]) -> Result, Error> { - match self.read_and_decode_value(key) { - Ok(outbound_lane_data) => Ok(outbound_lane_data), - Err(Error::StorageValueUnavailable) => Ok(None), + /// Returns a reference to the value corresponding to the key. + /// + /// Returns `None` if the key doesn't exist or if the value associated to it is `None`. + pub fn get_and_decode_optional( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, StorageProofError> { + match self.get_and_decode_mandatory(key) { + Ok(val) => Ok(Some(val)), + Err(StorageProofError::UnavailableKey | StorageProofError::EmptyVal) => Ok(None), Err(e) => Err(e), } } -} -/// Storage proof related errors. -#[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, Debug, TypeInfo)] -pub enum Error { - /// Duplicate trie nodes are found in the proof. - DuplicateNodesInProof, - /// Unused trie nodes are found in the proof. - UnusedNodesInTheProof, - /// 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), + /// Checks if each key was read. + pub fn ensure_no_unused_keys(&self) -> Result<(), StorageProofError> { + for (key, _) in &self.db { + if !key.has_been_read() { + return Err(StorageProofError::UnusedKey) + } + } + + Ok(()) + } } -/// Return valid storage proof and state root. +/// Storage proof size requirements. /// -/// NOTE: This should only be used for **testing**. -#[cfg(feature = "std")] -pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { - use sp_state_machine::{backend::Backend, prove_read, InMemoryBackend}; - - let state_version = sp_runtime::StateVersion::default(); - - // construct storage proof - let backend = >::from(( - 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()))]), - (None, vec![(b"key4".to_vec(), Some((42u64, 42u32, 42u16, 42u8).encode()))]), - // Value is too big to fit in a branch node - (None, vec![(b"key11".to_vec(), Some(vec![0u8; 32]))]), - ], - state_version, - )); - let root = backend.storage_root(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()) +/// This is currently used by benchmarks when generating storage proofs. +#[derive(Clone, Copy, Debug)] +pub enum StorageProofSize { + /// The storage proof is expected to be minimal. If value size may be changed, then it is + /// expected to have given size. + Minimal(u32), + /// The storage proof is expected to have at least given size and grow by increasing value that + /// is stored in the trie. + HasLargeLeaf(u32), } -/// Record all keys for a given root. -pub fn record_all_keys( - db: &DB, - root: &TrieHash, -) -> Result>> -where - DB: hash_db::HashDBRef, -{ - let mut recorder = Recorder::::new(); - let trie = TrieDBBuilder::::new(db, root).with_recorder(&mut recorder).build(); - for x in trie.iter()? { - let (key, _) = x?; - trie.get(&key)?; +/// Add extra data to the storage value so that it'll be of given size. +pub fn grow_storage_value(mut value: Vec, size: StorageProofSize) -> Vec { + 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(_) => (), } - - // recorder may record the same trie node multiple times and we don't want duplicate nodes - // in our proofs => let's deduplicate it by collecting to the BTreeSet first - Ok(recorder - .drain() - .into_iter() - .map(|n| n.data.to_vec()) - .collect::>() - .into_iter() - .collect()) + value } #[cfg(test)] -pub mod tests { +mod tests { use super::*; - use codec::Encode; + + type Hasher = sp_core::Blake2Hasher; + + #[test] + fn verify_succeeds_when_used_correctly() { + let (root, db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[(b"key1".to_vec(), None), (b"key2".to_vec(), Some(b"val2".to_vec()))], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + + assert!(db.verify::(StateVersion::V1, &root).is_ok()); + } #[test] - fn storage_proof_check() { - let (root, proof) = craft_valid_storage_proof(); - - // check proof in runtime - let mut checker = - >::new(root, proof.clone()).unwrap(); - 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"key22"), Ok(None)); - assert_eq!(checker.read_and_decode_value(b"key4"), Ok(Some((42u64, 42u32, 42u16, 42u8))),); + fn verify_fails_when_proof_contains_unneeded_nodes() { + let (root, mut db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[ + (b"key1".to_vec(), Some(b"val1".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + ], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + assert!(db.db.pop().is_some()); + assert!(matches!( - checker.read_and_decode_value::<[u8; 64]>(b"key4"), - Err(Error::StorageValueDecodeFailed(_)), + db.verify::(StateVersion::V1, &root), + Err(StorageProofError::InvalidProof) )); + } - // checking proof against invalid commitment fails - assert_eq!( - >::new(sp_core::H256::random(), proof).err(), - Some(Error::StorageRootMismatch) - ); + #[test] + fn verify_fails_when_db_contains_duplicate_nodes() { + let (root, mut db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[(b"key".to_vec(), None)], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + db.db.push((b"key".to_vec(), None)); + + assert!(matches!( + db.verify::(StateVersion::V1, &root), + Err(StorageProofError::InvalidProof) + )); } #[test] - fn proof_with_duplicate_items_is_rejected() { - let (root, mut proof) = craft_valid_storage_proof(); - proof.push(proof.first().unwrap().clone()); + fn verify_fails_when_entries_are_not_sorted() { + let (root, mut db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[ + (b"key1".to_vec(), Some(b"val1".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + ], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + db.db.reverse(); + + assert!(matches!( + db.verify::(StateVersion::V1, &root), + Err(StorageProofError::UnsortedEntries) + )); + } - assert_eq!( - StorageProofChecker::::new(root, proof).map(drop), - Err(Error::DuplicateNodesInProof), + #[test] + fn get_and_decode_mandatory_works() { + let (root, db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[ + (b"key11".to_vec(), Some(b"val11".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + (b"key1".to_vec(), None), + (b"key15".to_vec(), Some(b"val15".to_vec())), + ], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); + + assert!( + matches!(trusted_db.get_and_decode_mandatory::>(b"key11"), Ok(val) if val == b"val11".to_vec()) + ); + assert!( + matches!(trusted_db.get_and_decode_mandatory::>(b"key2"), Ok(val) if val == b"val2".to_vec()) ); + assert!(matches!( + trusted_db.get_and_decode_mandatory::>(b"key1"), + Err(StorageProofError::EmptyVal) + )); + assert!(matches!( + trusted_db.get_and_decode_mandatory::>(b"key15"), + Err(StorageProofError::DecodeError) + )); + } + + #[test] + fn get_and_decode_optional_works() { + let (root, db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[ + (b"key11".to_vec(), Some(b"val11".to_vec().encode())), + (b"key2".to_vec(), Some(b"val2".to_vec().encode())), + (b"key1".to_vec(), None), + (b"key15".to_vec(), Some(b"val15".to_vec())), + ], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); + + assert!( + matches!(trusted_db.get_and_decode_optional::>(b"key11"), Ok(Some(val)) if val == + b"val11".to_vec()) + ); + assert!( + matches!(trusted_db.get_and_decode_optional::>(b"key2"), Ok(Some(val)) if val == b"val2".to_vec()) + ); + assert!(matches!(trusted_db.get_and_decode_optional::>(b"key1"), Ok(None))); + assert!(matches!( + trusted_db.get_and_decode_optional::>(b"key15"), + Err(StorageProofError::DecodeError) + )); } #[test] - fn proof_with_unused_items_is_rejected() { - let (root, proof) = craft_valid_storage_proof(); - - let mut checker = - StorageProofChecker::::new(root, proof.clone()).unwrap(); - checker.read_value(b"key1").unwrap(); - checker.read_value(b"key2").unwrap(); - checker.read_value(b"key4").unwrap(); - checker.read_value(b"key22").unwrap(); - assert_eq!(checker.ensure_no_unused_nodes(), Ok(())); - - let checker = StorageProofChecker::::new(root, proof).unwrap(); - assert_eq!(checker.ensure_no_unused_nodes(), Err(Error::UnusedNodesInTheProof)); + fn ensure_no_unused_keys_works_correctly() { + let (root, db) = UnverifiedStorageProof::try_from_entries::( + StateVersion::default(), + &[(b"key1".to_vec(), None), (b"key2".to_vec(), Some(b"val2".to_vec()))], + ) + .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); + assert!(trusted_db.get(b"key1").is_ok()); + + assert!(matches!(trusted_db.ensure_no_unused_keys(), Err(StorageProofError::UnusedKey))); } } diff --git a/bridges/primitives/runtime/src/vec_db.rs b/bridges/primitives/runtime/src/vec_db.rs deleted file mode 100644 index 6034e102bd30..000000000000 --- a/bridges/primitives/runtime/src/vec_db.rs +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2019-2023 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 . - -//! Logic for working with more efficient storage proofs. - -use frame_support::PalletError; -use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; -use sp_runtime::{SaturatedConversion, StateVersion}; -use sp_std::{default::Default, vec, vec::Vec}; -use sp_trie::{ - generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, StorageProof, TrieDBBuilder, - TrieHash, -}; - -use codec::{Decode, Encode}; -use hash_db::Hasher; -use scale_info::TypeInfo; -use trie_db::{DBValue, Trie}; - -use crate::{storage_proof::RawStorageProof, Size}; - -pub type RawStorageKey = Vec; - -/// Errors that can occur when interacting with `UntrustedVecDb` and `TrustedVecDb`. -#[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] -pub enum VecDbError { - /// 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 in the `VecDb` wasn't read. - UnusedKey, -} - -/// Structure representing a key-value database stored as a sorted `Vec` of tuples. -/// -/// The structure also contains a proof of the fact that the key-value tuples are actually present -/// in the chain storage. -#[derive(Clone, Default, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct UntrustedVecDb { - proof: RawStorageProof, - db: Vec<(RawStorageKey, Option)>, -} - -impl UntrustedVecDb { - /// Creates a new instance of `UntrustedVecDb`. - pub fn try_new( - read_proof: StorageProof, - root: TrieHash>, - mut keys: Vec + Ord>, - ) -> Result { - // It's ok to use `LayoutV1` in this function, no matter the actual underlying layout, - // because we only perform read operations. When reading `LayoutV0` and `LayoutV1` lead to - // the same result. - let mem_db = read_proof.into_memory_db(); - let trie_db = TrieDBBuilder::>::new(&mem_db, &root).build(); - - let trie_proof = generate_trie_proof::, _, _, _>(&mem_db, root, &keys) - .map_err(|_| VecDbError::UnableToGenerateTrieProof)?; - - let mut entries = Vec::with_capacity(keys.len()); - keys.sort(); - for key in keys { - let val = trie_db.get(key.as_ref()).map_err(|_| VecDbError::UnavailableKey)?; - entries.push((key.as_ref().to_vec(), val)); - } - - Ok(Self { proof: trie_proof, db: entries }) - } - - /// Validates the contained `db` against the contained proof. If the `db` is valid, converts it - /// into a `TrustedVecDb`. - pub fn verify( - mut self, - state_version: StateVersion, - state_root: &TrieHash>, - ) -> Result { - // First we verify the proof for the `UntrustedVecDb`. - // Note that `verify_trie_proof()` also checks for duplicate keys and unused nodes. - match state_version { - StateVersion::V0 => - verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), - StateVersion::V1 => - verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), - } - .map_err(|_| VecDbError::InvalidProof)?; - - // Fill the `TrustedVecDb` - let mut trusted_db = Vec::with_capacity(self.db.len()); - let mut iter = self.db.drain(..).peekable(); - while let Some((key, val)) = iter.next() { - // Let's also make sure that the db is actually sorted. - if let Some((next_key, _)) = iter.peek() { - if next_key <= &key { - return Err(VecDbError::UnsortedEntries) - } - } - trusted_db.push((TrackedStorageKey::new(key), val)) - } - Ok(TrustedVecDb { db: trusted_db }) - } -} - -impl Size for UntrustedVecDb { - fn size(&self) -> u32 { - let proof_size = self.proof.iter().fold(0usize, |sum, node| sum.saturating_add(node.len())); - let entries_size = self.db.iter().fold(0usize, |sum, (key, value)| { - sum.saturating_add(key.len()) - .saturating_add(value.as_ref().unwrap_or(&vec![]).len()) - }); - - proof_size.saturating_add(entries_size).saturated_into() - } -} - -/// Structure representing a key-value database stored as a sorted `Vec` of tuples. -pub struct TrustedVecDb { - db: Vec<(TrackedStorageKey, Option)>, -} - -impl TrustedVecDb { - /// Returns a reference to the value corresponding to the key. - /// - /// Returns an error if the key doesn't exist. - pub fn get(&mut self, key: &impl AsRef<[u8]>) -> Result<&Option, VecDbError> { - let idx = self - .db - .binary_search_by(|(db_key, _)| db_key.key.as_slice().cmp(key.as_ref())) - .map_err(|_| VecDbError::UnavailableKey)?; - let (db_key, db_val) = self.db.get_mut(idx).ok_or(VecDbError::UnavailableKey)?; - db_key.add_read(); - Ok(db_val) - } - - /// Returns a reference to the value corresponding to the key. - /// - /// Returns an error if the key doesn't exist or if the value associated to it is `None`. - pub fn get_and_decode_mandatory( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result { - let val = self.get(key)?.as_ref().ok_or(VecDbError::EmptyVal)?; - D::decode(&mut &val[..]).map_err(|_| VecDbError::DecodeError) - } - - /// Returns a reference to the value corresponding to the key. - /// - /// Returns `None` if the key doesn't exist or if the value associated to it is `None`. - pub fn get_and_decode_optional( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result, VecDbError> { - match self.get_and_decode_mandatory(key) { - Ok(val) => Ok(Some(val)), - Err(VecDbError::UnavailableKey | VecDbError::EmptyVal) => Ok(None), - Err(e) => Err(e), - } - } - - /// Checks if each key was read. - pub fn ensure_no_unused_keys(&self) -> Result<(), VecDbError> { - for (key, _) in &self.db { - if !key.has_been_read() { - return Err(VecDbError::UnusedKey) - } - } - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use sp_core::H256; - - use sp_state_machine::{prove_read, InMemoryBackend}; - - type Hasher = sp_core::Blake2Hasher; - - fn generate_untrusted_vec_db( - entries: Vec<(RawStorageKey, Option)>, - ) -> (H256, Result) { - let keys: Vec<_> = entries.iter().map(|(key, _)| key.clone()).collect(); - let entries: Vec<_> = - entries.iter().cloned().map(|(key, val)| (None, vec![(key, val)])).collect(); - let backend = InMemoryBackend::::from((entries, StateVersion::V1)); - let root = *backend.root(); - let read_proof = prove_read(backend, &keys).unwrap(); - - (root, UntrustedVecDb::try_new::(read_proof, root, keys)) - } - - #[test] - fn verify_succeeds_when_used_correctly() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![ - (b"key1".to_vec(), None), - (b"key2".to_vec(), Some(b"val2".to_vec())), - ]); - let db = maybe_db.unwrap(); - - assert!(db.verify::(StateVersion::V1, &root).is_ok()); - } - - #[test] - fn verify_fails_when_proof_contains_unneeded_nodes() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![ - (b"key1".to_vec(), Some(b"val1".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - ]); - let mut db = maybe_db.unwrap(); - assert!(db.db.pop().is_some()); - - assert!(matches!( - db.verify::(StateVersion::V1, &root), - Err(VecDbError::InvalidProof) - )); - } - - #[test] - fn verify_fails_when_db_contains_duplicate_nodes() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![(b"key".to_vec(), None)]); - let mut db = maybe_db.unwrap(); - db.db.push((b"key".to_vec(), None)); - - assert!(matches!( - db.verify::(StateVersion::V1, &root), - Err(VecDbError::InvalidProof) - )); - } - - #[test] - fn verify_fails_when_entries_are_not_sorted() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![ - (b"key1".to_vec(), Some(b"val1".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - ]); - let mut db = maybe_db.unwrap(); - db.db.reverse(); - - assert!(matches!( - db.verify::(StateVersion::V1, &root), - Err(VecDbError::UnsortedEntries) - )); - } - - #[test] - fn get_and_decode_mandatory_works() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![ - (b"key11".to_vec(), Some(b"val11".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - (b"key1".to_vec(), None), - (b"key15".to_vec(), Some(b"val15".to_vec())), - ]); - let db = maybe_db.unwrap(); - let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); - - assert!( - matches!(trusted_db.get_and_decode_mandatory::>(b"key11"), Ok(val) if val == b"val11".to_vec()) - ); - assert!( - matches!(trusted_db.get_and_decode_mandatory::>(b"key2"), Ok(val) if val == b"val2".to_vec()) - ); - assert!(matches!( - trusted_db.get_and_decode_mandatory::>(b"key1"), - Err(VecDbError::EmptyVal) - )); - assert!(matches!( - trusted_db.get_and_decode_mandatory::>(b"key15"), - Err(VecDbError::DecodeError) - )); - } - - #[test] - fn get_and_decode_optional_works() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![ - (b"key11".to_vec(), Some(b"val11".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - (b"key1".to_vec(), None), - (b"key15".to_vec(), Some(b"val15".to_vec())), - ]); - let db = maybe_db.unwrap(); - let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); - - assert!( - matches!(trusted_db.get_and_decode_optional::>(b"key11"), Ok(Some(val)) if val == - b"val11".to_vec()) - ); - assert!( - matches!(trusted_db.get_and_decode_optional::>(b"key2"), Ok(Some(val)) if val == b"val2".to_vec()) - ); - assert!(matches!(trusted_db.get_and_decode_optional::>(b"key1"), Ok(None))); - assert!(matches!( - trusted_db.get_and_decode_optional::>(b"key15"), - Err(VecDbError::DecodeError) - )); - } - - #[test] - fn ensure_no_unused_keys_works_correctly() { - let (root, maybe_db) = generate_untrusted_vec_db(vec![ - (b"key1".to_vec(), None), - (b"key2".to_vec(), Some(b"val2".to_vec())), - ]); - let db = maybe_db.unwrap(); - let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); - assert!(trusted_db.get(b"key1").is_ok()); - - assert!(matches!(trusted_db.ensure_no_unused_keys(), Err(VecDbError::UnusedKey))); - } -} diff --git a/bridges/primitives/test-utils/src/lib.rs b/bridges/primitives/test-utils/src/lib.rs index f4fe4a242e79..e2f1fe68c585 100644 --- a/bridges/primitives/test-utils/src/lib.rs +++ b/bridges/primitives/test-utils/src/lib.rs @@ -22,12 +22,12 @@ use bp_header_chain::justification::{required_justification_precommits, GrandpaJustification}; 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; +use bp_runtime::UnverifiedStorageProof; use codec::Encode; use sp_consensus_grandpa::{AuthorityId, AuthoritySignature, AuthorityWeight, SetId}; use sp_runtime::traits::{Header as HeaderT, One, Zero}; use sp_std::prelude::*; -use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; +use sp_trie::{trie_types::TrieDBMutBuilderV1, MemoryDB, TrieMut}; // Re-export all our test account utilities pub use keyring::*; @@ -177,6 +177,7 @@ pub fn prepare_parachain_heads_proof( 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::::new(&mut mdb, &mut root).build(); for (parachain, head) in heads { @@ -185,14 +186,15 @@ pub fn prepare_parachain_heads_proof( 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 - let storage_proof = record_all_trie_keys::, _>(&mdb, &root) - .map_err(|_| "record_all_trie_keys has failed") - .expect("record_all_trie_keys should not fail in benchmarks"); + let storage_proof = + UnverifiedStorageProof::try_from_db::(&mdb, root, storage_keys) + .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); (root, ParaHeadsProof { storage_proof }, parachains) } diff --git a/bridges/relays/client-substrate/src/client/caching.rs b/bridges/relays/client-substrate/src/client/caching.rs index cb898cf51726..b57720befe6c 100644 --- a/bridges/relays/client-substrate/src/client/caching.rs +++ b/bridges/relays/client-substrate/src/client/caching.rs @@ -31,6 +31,7 @@ use async_std::{ task::JoinHandle, }; use async_trait::async_trait; +use bp_runtime::UnverifiedStorageProof; use codec::Encode; use frame_support::weights::Weight; use futures::{FutureExt, StreamExt}; @@ -41,7 +42,6 @@ use sp_core::{ Bytes, Pair, }; use sp_runtime::{traits::Header as _, transaction_validity::TransactionValidity}; -use sp_trie::StorageProof; use sp_version::RuntimeVersion; /// `quick_cache::unsync::Cache` wrapped in async-aware synchronization primitives. @@ -462,7 +462,12 @@ impl> Client for CachingClient { .await } - async fn prove_storage(&self, at: HashOf, keys: Vec) -> Result { - self.backend.prove_storage(at, keys).await + async fn prove_storage_with_root( + &self, + at: HashOf, + state_root: HashOf, + keys: Vec, + ) -> Result { + self.backend.prove_storage_with_root(at, state_root, keys).await } } diff --git a/bridges/relays/client-substrate/src/client/rpc.rs b/bridges/relays/client-substrate/src/client/rpc.rs index bf7442a95141..1a0f2a4b3cc9 100644 --- a/bridges/relays/client-substrate/src/client/rpc.rs +++ b/bridges/relays/client-substrate/src/client/rpc.rs @@ -37,7 +37,7 @@ use crate::{ use async_std::sync::{Arc, Mutex, RwLock}; use async_trait::async_trait; -use bp_runtime::HeaderIdProvider; +use bp_runtime::{HasherOf, HeaderIdProvider, UnverifiedStorageProof}; use codec::Encode; use frame_support::weights::Weight; use futures::TryFutureExt; @@ -635,16 +635,25 @@ impl Client for RpcClient { .map_err(|e| Error::failed_state_call::(at, method_clone, arguments_clone, e)) } - async fn prove_storage(&self, at: HashOf, keys: Vec) -> Result { + async fn prove_storage_with_root( + &self, + at: HashOf, + state_root: HashOf, + keys: Vec, + ) -> Result { let keys_clone = keys.clone(); - self.jsonrpsee_execute(move |client| async move { - SubstrateStateClient::::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::(at, keys_clone, e)) + let read_proof = self + .jsonrpsee_execute(move |client| async move { + SubstrateStateClient::::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::(at, keys.clone(), e))?; + + UnverifiedStorageProof::try_new::>(read_proof, state_root, keys) + .map_err(|e| Error::Custom(format!("Error generating storage proof: {:?}", e))) } } diff --git a/bridges/relays/client-substrate/src/client/traits.rs b/bridges/relays/client-substrate/src/client/traits.rs index 49f5c001c3f7..7796c69b7805 100644 --- a/bridges/relays/client-substrate/src/client/traits.rs +++ b/bridges/relays/client-substrate/src/client/traits.rs @@ -22,7 +22,7 @@ use crate::{ }; use async_trait::async_trait; -use bp_runtime::{StorageDoubleMapKeyProvider, StorageMapKeyProvider}; +use bp_runtime::{StorageDoubleMapKeyProvider, StorageMapKeyProvider, UnverifiedStorageProof}; use codec::{Decode, Encode}; use frame_support::weights::Weight; use sp_core::{ @@ -30,7 +30,6 @@ use sp_core::{ Bytes, Pair, }; use sp_runtime::{traits::Header as _, transaction_validity::TransactionValidity}; -use sp_trie::StorageProof; use sp_version::RuntimeVersion; use std::fmt::Debug; @@ -226,5 +225,21 @@ pub trait Client: 'static + Send + Sync + Clone + Debug { } /// Returns storage proof of given storage keys. - async fn prove_storage(&self, at: HashOf, keys: Vec) -> Result; + async fn prove_storage_with_root( + &self, + at: HashOf, + state_root: HashOf, + keys: Vec, + ) -> Result; + + /// Returns storage proof of given storage keys. + async fn prove_storage( + &self, + at: HashOf, + keys: Vec, + ) -> Result { + let root = *self.header_by_hash(at).await?.state_root(); + + self.prove_storage_with_root(at, root, keys).await + } } diff --git a/bridges/relays/client-substrate/src/error.rs b/bridges/relays/client-substrate/src/error.rs index b09e2c7abdc6..ee3c73f806e6 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/lib-substrate-relay/src/messages/source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs index 877b0438323e..8f0e1b54460c 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -36,9 +36,7 @@ use bp_messages::{ ChainWithMessages as _, InboundMessageDetails, LaneId, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, }; -use bp_runtime::{ - BasicOperatingMode, HasherOf, HeaderIdProvider, RangeInclusiveExt, UntrustedVecDb, -}; +use bp_runtime::{BasicOperatingMode, HeaderIdProvider, RangeInclusiveExt}; use codec::Encode; use frame_support::weights::Weight; use messages_relay::{ @@ -56,7 +54,6 @@ use relay_substrate_client::{ }; use relay_utils::relay_loop::Client as RelayClient; use sp_core::Pair; -use sp_runtime::traits::Header; use std::ops::RangeInclusive; /// Intermediate message proof returned by the source Substrate node. Includes everything @@ -339,14 +336,7 @@ where )); } - let root = *self.source_client.header_by_hash(id.hash()).await?.state_root(); - let storage_proof = - self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; - let storage = - UntrustedVecDb::try_new::>(storage_proof, root, storage_keys) - .map_err(|e| { - SubstrateError::Custom(format!("Error generating messages storage: {:?}", e)) - })?; + let storage = self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesProof { bridged_header_hash: id.1, storage, diff --git a/bridges/relays/lib-substrate-relay/src/messages/target.rs b/bridges/relays/lib-substrate-relay/src/messages/target.rs index fdd2619ffc04..6a137bda46ee 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/target.rs @@ -37,7 +37,6 @@ use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, storage_keys::inbound_lane_data_key, ChainWithMessages as _, InboundLaneData, LaneId, MessageNonce, UnrewardedRelayersState, }; -use bp_runtime::{HasherOf, UntrustedVecDb}; use messages_relay::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{NoncesSubmitArtifacts, TargetClient, TargetClientState}, @@ -48,7 +47,6 @@ use relay_substrate_client::{ }; use relay_utils::relay_loop::Client as RelayClient; use sp_core::Pair; -use sp_runtime::traits::Header; use std::{convert::TryFrom, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. @@ -238,16 +236,8 @@ where &self.lane_id, )]; - let root = *self.target_client.header_by_hash(id.hash()).await?.state_root(); - let read_proof = self.target_client.prove_storage(id.hash(), storage_keys.clone()).await?; let storage_proof = - UntrustedVecDb::try_new::>(read_proof, root, storage_keys) - .map_err(|e| { - SubstrateError::Custom(format!( - "Error generating messages delivery confirmation storage: {:?}", - e - )) - })?; + self.target_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: id.1, storage_proof, diff --git a/bridges/relays/lib-substrate-relay/src/parachains/source.rs b/bridges/relays/lib-substrate-relay/src/parachains/source.rs index 11b9d6dbf5bd..4ee41c45fafa 100644 --- a/bridges/relays/lib-substrate-relay/src/parachains/source.rs +++ b/bridges/relays/lib-substrate-relay/src/parachains/source.rs @@ -153,12 +153,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 +175,6 @@ where })?; let parachain_head_hash = parachain_head.hash(); - Ok((ParaHeadsProof { storage_proof: parachain_heads_proof }, parachain_head_hash)) + Ok((ParaHeadsProof { storage_proof }, parachain_head_hash)) } } diff --git a/bridges/relays/parachains/src/parachains_loop.rs b/bridges/relays/parachains/src/parachains_loop.rs index fd73ca2d46c0..0fd1d72c7075 100644 --- a/bridges/relays/parachains/src/parachains_loop.rs +++ b/bridges/relays/parachains/src/parachains_loop.rs @@ -680,7 +680,6 @@ impl SubmittedHeadsTracker

{ 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::::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) } } From 11cd08c8ee2ca5a3136058cf96b1c47b83ce89a5 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 16 Jun 2023 12:59:40 +0300 Subject: [PATCH 10/58] prune messages from confirmation tx, not from the on_idle (#2211) --- bridges/modules/messages/src/lib.rs | 35 --- bridges/modules/messages/src/outbound_lane.rs | 129 ++++------- .../messages/src/tests/pallet_tests.rs | 124 ----------- bridges/modules/messages/src/weights.rs | 204 ++++++++++-------- 4 files changed, 157 insertions(+), 335 deletions(-) diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 60c65641d947..1a20d4b38174 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -70,7 +70,6 @@ use bp_runtime::{ }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound}; -use sp_runtime::traits::UniqueSaturatedFrom; use sp_std::{marker::PhantomData, prelude::*}; mod inbound_lane; @@ -153,40 +152,6 @@ pub mod pallet { type OperatingModeStorage = PalletOperatingMode; } - #[pallet::hooks] - impl, I: 'static> Hooks> for Pallet - where - u32: TryFrom>, - { - fn on_idle(_block: BlockNumberFor, remaining_weight: Weight) -> Weight { - // we'll need at least to read outbound lane state, kill a message and update lane state - let db_weight = T::DbWeight::get(); - if !remaining_weight.all_gte(db_weight.reads_writes(1, 2)) { - return Weight::zero() - } - - // messages from lane with index `i` in `ActiveOutboundLanes` are pruned when - // `System::block_number() % lanes.len() == i`. Otherwise we need to read lane states on - // every block, wasting the whole `remaining_weight` for nothing and causing starvation - // of the last lane pruning - let active_lanes = T::ActiveOutboundLanes::get(); - let active_lanes_len = (active_lanes.len() as u32).into(); - let active_lane_index = u32::unique_saturated_from( - frame_system::Pallet::::block_number() % active_lanes_len, - ); - let active_lane_id = active_lanes[active_lane_index as usize]; - - // first db read - outbound lane state - let mut active_lane = outbound_lane::(active_lane_id); - let mut used_weight = db_weight.reads(1); - // and here we'll have writes - used_weight += active_lane.prune_messages(db_weight, remaining_weight - used_weight); - - // we already checked we have enough `remaining_weight` to cover this `used_weight` - used_weight - } - } - #[pallet::call] impl, I: 'static> Pallet { /// Change `PalletOwner`. diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index 2508ea9a4c41..0ad3e041800b 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -22,12 +22,7 @@ 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 frame_support::{traits::Get, BoundedVec, PalletError}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData}; @@ -144,41 +139,17 @@ impl OutboundLane { ensure_unrewarded_relayers_are_correct(confirmed_messages.end, relayers)?; + // prune all confirmed messages + for nonce in confirmed_messages.begin..=confirmed_messages.end { + self.storage.remove_message(&nonce); + } + data.latest_received_nonce = confirmed_messages.end; + data.oldest_unpruned_nonce = data.latest_received_nonce.saturating_add(1); self.storage.set_data(data); Ok(Some(confirmed_messages)) } - - /// Prune at most `max_messages_to_prune` already received messages. - /// - /// Returns weight, consumed by messages pruning and lane state update. - pub fn prune_messages( - &mut self, - db_weight: RuntimeDbWeight, - mut remaining_weight: Weight, - ) -> Weight { - let write_weight = db_weight.writes(1); - let two_writes_weight = write_weight + write_weight; - let mut spent_weight = Weight::zero(); - let mut data = self.storage.data(); - while remaining_weight.all_gte(two_writes_weight) && - data.oldest_unpruned_nonce <= data.latest_received_nonce - { - self.storage.remove_message(&data.oldest_unpruned_nonce); - - spent_weight += write_weight; - remaining_weight -= write_weight; - data.oldest_unpruned_nonce += 1; - } - - if !spent_weight.is_zero() { - spent_weight += write_weight; - self.storage.set_data(data); - } - - spent_weight - } } /// Verifies unrewarded relayers vec. @@ -222,7 +193,6 @@ mod tests { REGULAR_PAYLOAD, TEST_LANE_ID, }, }; - use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; fn unrewarded_relayers( @@ -275,12 +245,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, 4); + }); + } + + #[test] + fn confirm_partial_delivery_works() { + run_test(|| { + let mut lane = outbound_lane::(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, 3); + + 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, 4); }); } @@ -293,6 +294,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))), @@ -300,10 +302,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, 4); 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, 4); }); } @@ -361,57 +365,6 @@ mod tests { ); } - #[test] - fn prune_messages_works() { - run_test(|| { - let mut lane = outbound_lane::(TEST_LANE_ID); - // when lane is empty, nothing is pruned - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - Weight::zero() - ); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); - // when nothing is confirmed, nothing is pruned - lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); - lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); - lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); - assert!(lane.storage.message(&1).is_some()); - assert!(lane.storage.message(&2).is_some()); - assert!(lane.storage.message(&3).is_some()); - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - Weight::zero() - ); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); - // after confirmation, some messages are received - assert_eq!( - lane.confirm_delivery(2, 2, &unrewarded_relayers(1..=2)), - Ok(Some(delivered_messages(1..=2))), - ); - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - RocksDbWeight::get().writes(3), - ); - assert!(lane.storage.message(&1).is_none()); - assert!(lane.storage.message(&2).is_none()); - assert!(lane.storage.message(&3).is_some()); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 3); - // after last message is confirmed, everything is pruned - assert_eq!( - lane.confirm_delivery(1, 3, &unrewarded_relayers(3..=3)), - Ok(Some(delivered_messages(3..=3))), - ); - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - RocksDbWeight::get().writes(2), - ); - assert!(lane.storage.message(&1).is_none()); - assert!(lane.storage.message(&2).is_none()); - assert!(lane.storage.message(&3).is_none()); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4); - }); - } - #[test] fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index be52d12cc390..0b4715f6902d 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -41,7 +41,6 @@ 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}; @@ -834,129 +833,6 @@ fn inbound_message_details_works() { }); } -#[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::::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::(TEST_LANE_ID).data().latest_received_nonce, 4); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); - System::::set_block_number(2); - - // if passed wight is too low to do anything - let dbw = DbWeight::get(); - assert_eq!(Pallet::::on_idle(0, dbw.reads_writes(1, 1)), Weight::zero(),); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); - - // if passed wight is enough to prune single message - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 2)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); - - // if passed wight is enough to prune two more messages - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 3)), - dbw.reads_writes(1, 3), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 4); - - // if passed wight is enough to prune many messages - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, 1); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, - 1 - ); - assert_eq!( - outbound_lane::(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::::set_block_number(2); - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 1 - ); - - // in block#3.on_idle lane messages of lane 2 are pruned - System::::set_block_number(3); - - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 2 - ); - }); -} - #[test] fn outbound_message_from_unconfigured_lane_is_rejected() { run_test(|| { diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index 530026120996..cfa869df1e72 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-06-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-06-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `serban-ROG-Zephyrus`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` +//! HOSTNAME: `covid`, CPU: `11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: @@ -83,37 +83,37 @@ impl WeightInfo for BridgeWeight { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 32_573 nanoseconds. - Weight::from_parts(35_227_000, 52645) + // Minimum execution time: 46_346 nanoseconds. + Weight::from_parts(47_766_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: BridgeRialtoMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoParachainMessages PalletOperatingMode (r:1 w:0) /// - /// Proof: BridgeRialtoMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), - /// added: 497, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages PalletOperatingMode (max_values: Some(1), max_size: + /// Some(2), added: 497, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoGrandpa ImportedHeaders (r:1 w:0) + /// Storage: BridgeRialtoParachains ImportedParaHeads (r:1 w:0) /// - /// Proof: BridgeRialtoGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), - /// added: 2048, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachains ImportedParaHeads (max_values: Some(1024), max_size: + /// Some(196), added: 1681, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) + /// Storage: BridgeRialtoParachainMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), + /// added: 51655, 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: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 35_330 nanoseconds. - Weight::from_parts(27_526_047, 52645) - // Standard Error: 2_681 - .saturating_add(Weight::from_parts(7_412_923, 0).saturating_mul(n.into())) + // Minimum execution time: 46_863 nanoseconds. + Weight::from_parts(48_196_000, 52645) + // Standard Error: 75_174 + .saturating_add(Weight::from_parts(10_933_295, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -133,10 +133,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 41_123 nanoseconds. - Weight::from_parts(43_023_000, 52645) + // Minimum execution time: 55_928 nanoseconds. + Weight::from_parts(57_684_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -156,16 +156,14 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16]`. - /// - /// The range of component `n` is `[1, 16]`. fn receive_single_message_n_kb_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 36_301 nanoseconds. - Weight::from_parts(37_103_459, 52645) - // Standard Error: 4_645 - .saturating_add(Weight::from_parts(1_172_720, 0).saturating_mul(n.into())) + // Minimum execution time: 48_899 nanoseconds. + Weight::from_parts(50_220_157, 52645) + // Standard Error: 5_477 + .saturating_add(Weight::from_parts(1_351_936, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -188,14 +186,19 @@ impl WeightInfo for BridgeWeight { /// /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:1) + /// + /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: + /// Some(2621472), added: 2623947, mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `515` + // Measured: `453` // Estimated: `3530` - // Minimum execution time: 33_941 nanoseconds. - Weight::from_parts(35_252_000, 3530) + // Minimum execution time: 43_135 nanoseconds. + Weight::from_parts(44_343_000, 3530) .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) /// @@ -216,14 +219,19 @@ impl WeightInfo for BridgeWeight { /// /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: + /// Some(2621472), added: 2623947, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `532` + // Measured: `470` // Estimated: `3530` - // Minimum execution time: 33_259 nanoseconds. - Weight::from_parts(34_558_000, 3530) + // Minimum execution time: 43_636 nanoseconds. + Weight::from_parts(44_824_000, 3530) .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) /// @@ -244,14 +252,19 @@ impl WeightInfo for BridgeWeight { /// /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: + /// Some(2621472), added: 2623947, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `532` + // Measured: `470` // Estimated: `6070` - // Minimum execution time: 35_199 nanoseconds. - Weight::from_parts(36_989_000, 6070) + // Minimum execution time: 46_915 nanoseconds. + Weight::from_parts(48_164_000, 6070) .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) /// @@ -271,12 +284,12 @@ impl WeightInfo for BridgeWeight { /// The range of component `n` is `[128, 2048]`. fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 75_228 nanoseconds. - Weight::from_parts(62_255_691, 52645) - // Standard Error: 2_005 - .saturating_add(Weight::from_parts(353_141, 0).saturating_mul(n.into())) + // Minimum execution time: 103_129 nanoseconds. + Weight::from_parts(89_692_354, 52645) + // Standard Error: 2_329 + .saturating_add(Weight::from_parts(430_468, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -300,39 +313,39 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 34_644 nanoseconds. - Weight::from_parts(36_135_000, 52645) + // Minimum execution time: 46_346 nanoseconds. + Weight::from_parts(47_766_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: BridgeRialtoMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoParachainMessages PalletOperatingMode (r:1 w:0) /// - /// Proof: BridgeRialtoMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), - /// added: 497, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages PalletOperatingMode (max_values: Some(1), max_size: + /// Some(2), added: 497, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoGrandpa ImportedHeaders (r:1 w:0) + /// Storage: BridgeRialtoParachains ImportedParaHeads (r:1 w:0) /// - /// Proof: BridgeRialtoGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), - /// added: 2048, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachains ImportedParaHeads (max_values: Some(1024), max_size: + /// Some(196), added: 1681, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) + /// Storage: BridgeRialtoParachainMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), + /// added: 51655, 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: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 35_330 nanoseconds. - Weight::from_parts(27_526_047, 52645) - // Standard Error: 2_681 - .saturating_add(Weight::from_parts(7_412_923, 0).saturating_mul(n.into())) + // Minimum execution time: 46_863 nanoseconds. + Weight::from_parts(48_196_000, 52645) + // Standard Error: 75_174 + .saturating_add(Weight::from_parts(10_933_295, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -352,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: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 41_123 nanoseconds. - Weight::from_parts(43_023_000, 52645) + // Minimum execution time: 55_928 nanoseconds. + Weight::from_parts(57_684_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -371,20 +384,20 @@ impl WeightInfo for () { /// /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), + /// added: 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16]`. /// /// The range of component `n` is `[1, 16]`. fn receive_single_message_n_kb_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` + // Measured: `428` // Estimated: `52645` - // Minimum execution time: 36_301 nanoseconds. - Weight::from_parts(37_103_459, 52645) - // Standard Error: 4_645 - .saturating_add(Weight::from_parts(1_172_720, 0).saturating_mul(n.into())) + // Minimum execution time: 48_899 nanoseconds. + Weight::from_parts(50_220_157, 52645) + // Standard Error: 5_477 + .saturating_add(Weight::from_parts(1_351_936, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -407,14 +420,19 @@ impl WeightInfo for () { /// /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:1) + /// + /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: + /// Some(2621472), added: 2623947, mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `515` + // Measured: `453` // Estimated: `3530` - // Minimum execution time: 33_941 nanoseconds. - Weight::from_parts(35_252_000, 3530) + // Minimum execution time: 43_135 nanoseconds. + Weight::from_parts(44_343_000, 3530) .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) /// @@ -435,14 +453,19 @@ impl WeightInfo for () { /// /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: + /// Some(2621472), added: 2623947, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `532` + // Measured: `470` // Estimated: `3530` - // Minimum execution time: 33_259 nanoseconds. - Weight::from_parts(34_558_000, 3530) + // Minimum execution time: 43_636 nanoseconds. + Weight::from_parts(44_824_000, 3530) .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) /// @@ -463,14 +486,19 @@ impl WeightInfo for () { /// /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) + /// + /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// + /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: + /// Some(2621472), added: 2623947, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `532` + // Measured: `470` // Estimated: `6070` - // Minimum execution time: 35_199 nanoseconds. - Weight::from_parts(36_989_000, 6070) + // Minimum execution time: 46_915 nanoseconds. + Weight::from_parts(48_164_000, 6070) .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) /// @@ -492,10 +520,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `428` // Estimated: `52645` - // Minimum execution time: 76_504 nanoseconds. - Weight::from_parts(75_331_522, 52645) - // Standard Error: 1_440 - .saturating_add(Weight::from_parts(302_158, 0).saturating_mul(n.into())) + // Minimum execution time: 103_129 nanoseconds. + Weight::from_parts(89_692_354, 52645) + // Standard Error: 2_329 + .saturating_add(Weight::from_parts(430_468, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } From e5acef8ba426933d2e168b35386dbce6b7f7f219 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 19 Jun 2023 16:02:39 +0300 Subject: [PATCH 11/58] Fix maximal message dispatch weight (#2219) * add test for maximal message dispatch weight * fixed weight computations - use kb for both size-related benchmarks * fix typo in weight formula * decreased maximal message size to 64Kb --- bridges/bin/runtime-common/src/integrity.rs | 6 + bridges/modules/messages/src/benchmarking.rs | 10 +- bridges/modules/messages/src/lib.rs | 4 +- bridges/modules/messages/src/weights.rs | 214 +++++++++---------- bridges/modules/messages/src/weights_ext.rs | 29 ++- bridges/modules/xcm-bridge-hub/src/mock.rs | 2 +- bridges/primitives/messages/src/lib.rs | 12 +- 7 files changed, 152 insertions(+), 125 deletions(-) diff --git a/bridges/bin/runtime-common/src/integrity.rs b/bridges/bin/runtime-common/src/integrity.rs index 3ea5222d2329..f661db8a2205 100644 --- a/bridges/bin/runtime-common/src/integrity.rs +++ b/bridges/bin/runtime-common/src/integrity.rs @@ -293,6 +293,12 @@ pub fn check_message_lane_weights< // check basic weight assumptions pallet_bridge_messages::ensure_weights_are_correct::>(); + // check that the maximal message dispatch weight is below hardcoded limit + pallet_bridge_messages::ensure_maximal_message_dispatch::>( + 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(C::maximal_incoming_message_size()); diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 9f1b985f23e1..1dfaa5b00285 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -302,9 +302,9 @@ mod benchmarks { // * message is dispatched (reminder: dispatch weight should be minimal); // * message requires all heavy checks done by dispatcher. #[benchmark] - fn receive_single_message_n_kb_proof( + fn receive_single_message_n_bytes_proof( /// Proof size in KB - n: Linear<1, 16>, + n: Linear<1, { 16 * 1024 }>, ) { // setup code let setup = ReceiveMessagesProofSetup::::new(1); @@ -313,7 +313,7 @@ mod benchmarks { message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: false, - size: StorageProofSize::Minimal(n * 1024), + size: StorageProofSize::Minimal(n), }); #[extrinsic_call] @@ -491,8 +491,8 @@ mod benchmarks { // #[benchmark(extra)] #[benchmark] fn receive_single_message_n_bytes_proof_with_dispatch( - /// Proof size in bytes - n: Linear, + /// Proof size in KB + n: Linear<1, { 16 * 1024 }>, ) { // setup code let setup = ReceiveMessagesProofSetup::::new(1); diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 1a20d4b38174..25278714666c 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::{ diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index cfa869df1e72..6c77fe19d9c4 100644 --- a/bridges/modules/messages/src/weights.rs +++ b/bridges/modules/messages/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for pallet_bridge_messages //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-06-19, 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` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -53,7 +53,7 @@ pub trait WeightInfo { fn receive_single_message_proof() -> Weight; fn receive_n_messages_proof(n: u32) -> Weight; fn receive_single_message_proof_with_outbound_lane_state() -> Weight; - fn receive_single_message_n_kb_proof(n: u32) -> Weight; + fn receive_single_message_n_bytes_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; @@ -81,39 +81,39 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 46_346 nanoseconds. - Weight::from_parts(47_766_000, 52645) + // Minimum execution time: 46_942 nanoseconds. + Weight::from_parts(49_198_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: BridgeRialtoParachainMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoMessages PalletOperatingMode (r:1 w:0) /// - /// Proof: BridgeRialtoParachainMessages PalletOperatingMode (max_values: Some(1), max_size: - /// Some(2), added: 497, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), + /// added: 497, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachains ImportedParaHeads (r:1 w:0) + /// Storage: BridgeRialtoGrandpa ImportedHeaders (r:1 w:0) /// - /// Proof: BridgeRialtoParachains ImportedParaHeads (max_values: Some(1024), max_size: - /// Some(196), added: 1681, mode: MaxEncodedLen) + /// Proof: BridgeRialtoGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), + /// added: 2048, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages InboundLanes (r:1 w:1) + /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), - /// added: 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: + /// 51655, 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: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 46_863 nanoseconds. - Weight::from_parts(48_196_000, 52645) - // Standard Error: 75_174 - .saturating_add(Weight::from_parts(10_933_295, 0).saturating_mul(n.into())) + // Minimum execution time: 47_880 nanoseconds. + Weight::from_parts(49_410_000, 52645) + // Standard Error: 62_811 + .saturating_add(Weight::from_parts(11_128_145, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -133,10 +133,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 55_928 nanoseconds. - Weight::from_parts(57_684_000, 52645) + // Minimum execution time: 56_275 nanoseconds. + Weight::from_parts(58_324_000, 52645) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -155,15 +155,15 @@ impl WeightInfo for BridgeWeight { /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) /// - /// The range of component `n` is `[1, 16]`. - fn receive_single_message_n_kb_proof(n: u32) -> Weight { + /// The range of component `n` is `[1, 16384]`. + fn receive_single_message_n_bytes_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 48_899 nanoseconds. - Weight::from_parts(50_220_157, 52645) - // Standard Error: 5_477 - .saturating_add(Weight::from_parts(1_351_936, 0).saturating_mul(n.into())) + // Minimum execution time: 47_796 nanoseconds. + Weight::from_parts(51_176_451, 52645) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_303, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -187,16 +187,16 @@ impl WeightInfo for BridgeWeight { /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:1) + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:1) /// - /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: - /// Some(2621472), added: 2623947, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65568), + /// added: 68043, mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `453` + // Measured: `515` // Estimated: `3530` - // Minimum execution time: 43_135 nanoseconds. - Weight::from_parts(44_343_000, 3530) + // Minimum execution time: 43_987 nanoseconds. + Weight::from_parts(46_149_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -220,16 +220,16 @@ impl WeightInfo for BridgeWeight { /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) /// - /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: - /// Some(2621472), added: 2623947, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65568), + /// added: 68043, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `3530` - // Minimum execution time: 43_636 nanoseconds. - Weight::from_parts(44_824_000, 3530) + // Minimum execution time: 44_871 nanoseconds. + Weight::from_parts(46_068_000, 3530) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -253,16 +253,16 @@ impl WeightInfo for BridgeWeight { /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) /// - /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: - /// Some(2621472), added: 2623947, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65568), + /// added: 68043, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `6070` - // Minimum execution time: 46_915 nanoseconds. - Weight::from_parts(48_164_000, 6070) + // Minimum execution time: 48_361 nanoseconds. + Weight::from_parts(49_654_000, 6070) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -281,15 +281,15 @@ impl WeightInfo for BridgeWeight { /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) /// - /// The range of component `n` is `[128, 2048]`. + /// The range of component `n` is `[1, 16384]`. fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 103_129 nanoseconds. - Weight::from_parts(89_692_354, 52645) - // Standard Error: 2_329 - .saturating_add(Weight::from_parts(430_468, 0).saturating_mul(n.into())) + // Minimum execution time: 47_017 nanoseconds. + Weight::from_parts(48_876_000, 52645) + // Standard Error: 686 + .saturating_add(Weight::from_parts(498_597, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -313,39 +313,39 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 46_346 nanoseconds. - Weight::from_parts(47_766_000, 52645) + // Minimum execution time: 46_942 nanoseconds. + Weight::from_parts(49_198_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: BridgeRialtoParachainMessages PalletOperatingMode (r:1 w:0) + /// Storage: BridgeRialtoMessages PalletOperatingMode (r:1 w:0) /// - /// Proof: BridgeRialtoParachainMessages PalletOperatingMode (max_values: Some(1), max_size: - /// Some(2), added: 497, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages PalletOperatingMode (max_values: Some(1), max_size: Some(2), + /// added: 497, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachains ImportedParaHeads (r:1 w:0) + /// Storage: BridgeRialtoGrandpa ImportedHeaders (r:1 w:0) /// - /// Proof: BridgeRialtoParachains ImportedParaHeads (max_values: Some(1024), max_size: - /// Some(196), added: 1681, mode: MaxEncodedLen) + /// Proof: BridgeRialtoGrandpa ImportedHeaders (max_values: Some(14400), max_size: Some(68), + /// added: 2048, mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages InboundLanes (r:1 w:1) + /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), - /// added: 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: + /// 51655, 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: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 46_863 nanoseconds. - Weight::from_parts(48_196_000, 52645) - // Standard Error: 75_174 - .saturating_add(Weight::from_parts(10_933_295, 0).saturating_mul(n.into())) + // Minimum execution time: 47_880 nanoseconds. + Weight::from_parts(49_410_000, 52645) + // Standard Error: 62_811 + .saturating_add(Weight::from_parts(11_128_145, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -365,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: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 55_928 nanoseconds. - Weight::from_parts(57_684_000, 52645) + // Minimum execution time: 56_275 nanoseconds. + Weight::from_parts(58_324_000, 52645) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -384,20 +384,20 @@ impl WeightInfo for () { /// /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoParachainMessages InboundLanes (max_values: None, max_size: Some(49180), - /// added: 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: + /// 51655, mode: MaxEncodedLen) /// - /// The range of component `n` is `[1, 16]`. + /// The range of component `n` is `[1, 16384]`. /// - /// The range of component `n` is `[1, 16]`. - fn receive_single_message_n_kb_proof(n: u32) -> Weight { + /// The range of component `n` is `[1, 16384]`. + fn receive_single_message_n_bytes_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 48_899 nanoseconds. - Weight::from_parts(50_220_157, 52645) - // Standard Error: 5_477 - .saturating_add(Weight::from_parts(1_351_936, 0).saturating_mul(n.into())) + // Minimum execution time: 47_796 nanoseconds. + Weight::from_parts(51_176_451, 52645) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_303, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -421,16 +421,16 @@ impl WeightInfo for () { /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:1) + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:1) /// - /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: - /// Some(2621472), added: 2623947, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65568), + /// added: 68043, mode: MaxEncodedLen) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `453` + // Measured: `515` // Estimated: `3530` - // Minimum execution time: 43_135 nanoseconds. - Weight::from_parts(44_343_000, 3530) + // Minimum execution time: 43_987 nanoseconds. + Weight::from_parts(46_149_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -454,16 +454,16 @@ impl WeightInfo for () { /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) /// - /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: - /// Some(2621472), added: 2623947, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65568), + /// added: 68043, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `3530` - // Minimum execution time: 43_636 nanoseconds. - Weight::from_parts(44_824_000, 3530) + // Minimum execution time: 44_871 nanoseconds. + Weight::from_parts(46_068_000, 3530) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -487,16 +487,16 @@ impl WeightInfo for () { /// Proof: BridgeRelayers RelayerRewards (max_values: None, max_size: Some(65), added: 2540, /// mode: MaxEncodedLen) /// - /// Storage: BridgeRialtoParachainMessages OutboundMessages (r:0 w:2) + /// Storage: BridgeRialtoMessages OutboundMessages (r:0 w:2) /// - /// Proof: BridgeRialtoParachainMessages OutboundMessages (max_values: None, max_size: - /// Some(2621472), added: 2623947, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages OutboundMessages (max_values: None, max_size: Some(65568), + /// added: 68043, mode: MaxEncodedLen) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `470` + // Measured: `532` // Estimated: `6070` - // Minimum execution time: 46_915 nanoseconds. - Weight::from_parts(48_164_000, 6070) + // Minimum execution time: 48_361 nanoseconds. + Weight::from_parts(49_654_000, 6070) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -515,15 +515,15 @@ impl WeightInfo for () { /// Proof: BridgeUnknownMessages InboundLanes (max_values: None, max_size: Some(49180), added: /// 51655, mode: MaxEncodedLen) /// - /// The range of component `n` is `[128, 2048]`. + /// The range of component `n` is `[1, 16384]`. fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `428` + // Measured: `490` // Estimated: `52645` - // Minimum execution time: 103_129 nanoseconds. - Weight::from_parts(89_692_354, 52645) - // Standard Error: 2_329 - .saturating_add(Weight::from_parts(430_468, 0).saturating_mul(n.into())) + // Minimum execution time: 47_017 nanoseconds. + Weight::from_parts(48_876_000, 52645) + // Standard Error: 686 + .saturating_add(Weight::from_parts(498_597, 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 cb0bcd3d3da4..0e0450ed1fb6 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -79,6 +79,19 @@ pub fn ensure_weights_are_correct() { total_messages_in_delivery_proof_does_not_affect_proof_size::(); } +/// Ensure that we are able to dispatch maximal size messages. +pub fn ensure_maximal_message_dispatch( + 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( max_extrinsic_size: u32, @@ -91,7 +104,8 @@ pub fn ensure_able_to_receive_message( 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 @@ -397,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_n_kb_proof(2) - - Self::receive_single_message_n_kb_proof(1)) / - 1024; + let byte_weight = Self::receive_single_message_n_bytes_proof(2) - + Self::receive_single_message_n_bytes_proof(1); proof_size_in_bytes * byte_weight } @@ -411,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_n_bytes_proof_with_dispatch(message_size) - .saturating_sub(Self::receive_single_message_proof()) + let message_size_in_bytes = message_size; + Self::receive_single_message_n_bytes_proof_with_dispatch(message_size_in_bytes) + .saturating_sub(Self::receive_single_message_n_bytes_proof(message_size_in_bytes)) } } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 434f4295691e..6f022533b0a8 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -110,7 +110,7 @@ impl pallet_bridge_messages::WeightInfo for TestMessagesWeights { fn receive_single_message_proof_with_outbound_lane_state() -> Weight { Weight::zero() } - fn receive_single_message_n_kb_proof(_: u32) -> Weight { + fn receive_single_message_n_bytes_proof(_: u32) -> Weight { Weight::zero() } fn receive_delivery_proof_for_single_message() -> Weight { diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index e6540dc33af6..61d30d2aa74d 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 @@ -97,7 +100,14 @@ pub fn maximal_incoming_message_size(max_extrinsic_size: u32) -> u32 { // 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. - max_extrinsic_size / 3 * 2 + // + // **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 ChainWithMessages for T From 5303b2c8a78921e4913a8ae27fbb5b67f2ce2b35 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 20 Jun 2023 16:07:28 +0300 Subject: [PATCH 12/58] Box messages proof argument in receive_messages_proof call (#2222) * Box messages proof argument in receive_messages_proof call * fix benchmark tests --- .../src/extensions/refund_relayer_extension.rs | 4 ++-- bridges/bin/runtime-common/src/messages_call_ext.rs | 4 ++-- bridges/modules/messages/src/benchmarking.rs | 10 +++++----- bridges/modules/messages/src/lib.rs | 8 ++++---- bridges/modules/messages/src/tests/mock.rs | 8 ++++---- bridges/modules/messages/src/tests/pallet_tests.rs | 6 +++--- bridges/relays/lib-substrate-relay/src/messages/mod.rs | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) 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 24b9ce9b34c2..3ba20ef018df 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -1142,7 +1142,7 @@ 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: Default::default(), lane: TestLaneId::get(), @@ -1152,7 +1152,7 @@ pub(crate) mod tests { .last_delivered_nonce() + 1, nonces_end: best_message, - }, + }), messages_count: 1, dispatch_weight: Weight::zero(), }) diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index 8fc0d5794fd9..6d14842f8c99 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -402,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: Default::default(), lane: LaneId([0, 0, 0, 0]), nonces_start, nonces_end, - }, + }), }, ) .check_obsolete_call() diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 1dfaa5b00285..1b426ce16029 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -214,7 +214,7 @@ mod benchmarks { receive_messages_proof( RawOrigin::Signed(setup.relayer_id_on_tgt()), setup.relayer_id_on_src(), - proof, + Box::new(proof), setup.msgs_count, dispatch_weight, ); @@ -245,7 +245,7 @@ mod benchmarks { receive_messages_proof( RawOrigin::Signed(setup.relayer_id_on_tgt()), setup.relayer_id_on_src(), - proof, + Box::new(proof), setup.msgs_count, dispatch_weight, ); @@ -285,7 +285,7 @@ mod benchmarks { receive_messages_proof( RawOrigin::Signed(setup.relayer_id_on_tgt()), setup.relayer_id_on_src(), - proof, + Box::new(proof), setup.msgs_count, dispatch_weight, ); @@ -320,7 +320,7 @@ mod benchmarks { receive_messages_proof( RawOrigin::Signed(setup.relayer_id_on_tgt()), setup.relayer_id_on_src(), - proof, + Box::new(proof), setup.msgs_count, dispatch_weight, ); @@ -508,7 +508,7 @@ mod benchmarks { receive_messages_proof( RawOrigin::Signed(setup.relayer_id_on_tgt()), setup.relayer_id_on_src(), - proof, + Box::new(proof), setup.msgs_count, dispatch_weight, ); diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 25278714666c..83c095341848 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -197,11 +197,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, relayer_id_at_bridged_chain: AccountIdOf>, - proof: FromBridgedChainMessagesProof>>, + proof: Box>>>, messages_count: u32, dispatch_weight: Weight, ) -> DispatchResultWithPostInfo { @@ -229,14 +229,14 @@ 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::(proof, messages_count) + let messages = verify_and_decode_messages_proof::(*proof, messages_count) .map_err(|err| { log::trace!(target: LOG_TARGET, "Rejecting invalid messages proof: {:?}", err,); diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index e6d29b62e4e7..78d921f38191 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -225,7 +225,7 @@ impl crate::benchmarking::Config<()> for TestRuntime { let dispatch_weight = REGULAR_PAYLOAD.declared_weight * params.message_nonces.checked_len().unwrap_or(0); ( - prepare_messages_proof( + *prepare_messages_proof( params.message_nonces.into_iter().map(|n| message(n, REGULAR_PAYLOAD)).collect(), params.outbound_lane_data, ), @@ -463,7 +463,7 @@ pub fn run_test(test: impl FnOnce() -> T) -> T { pub fn prepare_messages_proof( messages: Vec, outbound_lane_data: Option, -) -> FromBridgedChainMessagesProof { +) -> Box> { // first - let's generate storage proof let lane = messages.first().unwrap().key.lane_id; let nonces_start = messages.first().unwrap().key.nonce; @@ -487,13 +487,13 @@ pub fn prepare_messages_proof( StoredHeaderData { number: 0, state_root: storage_root }, ); - FromBridgedChainMessagesProof:: { + Box::new(FromBridgedChainMessagesProof:: { bridged_header_hash, storage, lane, nonces_start, nonces_end, - } + }) } /// Prepare valid storage proof for given messages and insert appropriate header to the diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index 0b4715f6902d..b2f7bb1c4a65 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -643,7 +643,7 @@ fn ref_time_refund_from_receive_messages_proof_works() { let messages_count = 1; let pre_dispatch_weight = ::WeightInfo::receive_messages_proof_weight( - &proof, + &*proof, messages_count, REGULAR_PAYLOAD.declared_weight, ); @@ -698,7 +698,7 @@ fn proof_size_refund_from_receive_messages_proof_works() { let messages_count = 1; let pre_dispatch_weight = ::WeightInfo::receive_messages_proof_weight( - &proof, + &*proof, messages_count, REGULAR_PAYLOAD.declared_weight, ); @@ -878,7 +878,7 @@ fn test_bridge_messages_call_is_correctly_defined() { FromBridgedChainMessagesDeliveryProof, >::receive_messages_proof { relayer_id_at_bridged_chain: account_id, - proof: message_proof, + proof: *message_proof, messages_count: 1, dispatch_weight: REGULAR_PAYLOAD.declared_weight, }; diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index 982795ee3e0e..b58838e5dcf9 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -403,7 +403,7 @@ where ) -> CallOf { let call: CallOf = BridgeMessagesCall::::receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_source, - proof: proof.1, + proof: Box::new(proof.1), messages_count, dispatch_weight, } From 6019c51aba476909f07910698dbe0763b71e1cc2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 21 Jun 2023 13:59:51 +0300 Subject: [PATCH 13/58] bump Substrate, Polkadot and Cumulus (#2223) --- bridges/primitives/messages/src/lib.rs | 14 +++++++++++++- bridges/primitives/runtime/src/storage_proof.rs | 8 ++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 61d30d2aa74d..208d252e816f 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -167,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]); diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index abc5a8d86544..e5207d79266c 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -25,10 +25,9 @@ use sp_trie::{ TrieDBBuilder, TrieHash, }; -use codec::{Codec, Decode, Encode}; +use codec::{Decode, Encode}; use hash_db::Hasher; use scale_info::TypeInfo; -use sp_state_machine::TrieBackend; use trie_db::{DBValue, Recorder, Trie}; use crate::Size; @@ -102,12 +101,13 @@ impl UnverifiedStorageProof { entries: &[(RawStorageKey, Option)], ) -> Result<(H::Out, UnverifiedStorageProof), StorageProofError> where - H::Out: Codec, + H::Out: codec::Codec, { let keys: Vec<_> = entries.iter().map(|(key, _)| key.clone()).collect(); let entries: Vec<_> = entries.iter().cloned().map(|(key, val)| (None, vec![(key, val)])).collect(); - let backend = TrieBackend::, H>::from((entries, state_version)); + let backend = + sp_state_machine::TrieBackend::, H>::from((entries, state_version)); let root = *backend.root(); Ok((root, UnverifiedStorageProof::try_from_db(backend.backend_storage(), root, keys)?)) From 4cbee73ceffe3ff11f6cb64fc3454797df3b8011 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Wed, 21 Jun 2023 14:40:08 +0300 Subject: [PATCH 14/58] Add test method for growing storage proof size (#2224) --- bridges/modules/messages/Cargo.toml | 2 + bridges/primitives/runtime/Cargo.toml | 1 + bridges/primitives/runtime/src/lib.rs | 7 +-- .../primitives/runtime/src/storage_proof.rs | 58 ++++++++++++++++++- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index 63a2dc255f7b..1587093d749c 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -30,6 +30,7 @@ sp-std = { workspace = true } sp-trie = { optional = true, workspace = true } [dev-dependencies] +bp-runtime = { features = ["test-helpers"], workspace = true } bp-test-utils = { workspace = true } pallet-balances = { workspace = true } pallet-bridge-grandpa = { workspace = true } @@ -68,4 +69,5 @@ try-runtime = [ ] test-helpers = [ "sp-trie", + "bp-runtime/test-helpers" ] diff --git a/bridges/primitives/runtime/Cargo.toml b/bridges/primitives/runtime/Cargo.toml index 5fa35e688996..117409b37b94 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/lib.rs b/bridges/primitives/runtime/src/lib.rs index 592242030b25..4b5a24b38078 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -40,10 +40,9 @@ pub use chain::{ }; pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; -pub use storage_proof::{ - grow_storage_value, StorageProofError, StorageProofSize, UnverifiedStorageProof, - VerifiedStorageProof, -}; +#[cfg(feature = "test-helpers")] +pub use storage_proof::{grow_storage_proof, grow_storage_value, StorageProofSize}; +pub use storage_proof::{StorageProofError, UnverifiedStorageProof, VerifiedStorageProof}; pub use storage_types::BoundedStorageValue; pub mod extensions; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index e5207d79266c..5875639dbf69 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -29,6 +29,8 @@ use codec::{Decode, Encode}; use hash_db::Hasher; use scale_info::TypeInfo; use trie_db::{DBValue, Recorder, Trie}; +#[cfg(feature = "test-helpers")] +use trie_db::{TrieConfiguration, TrieDBMut}; use crate::Size; @@ -95,7 +97,7 @@ impl UnverifiedStorageProof { /// Creates a new instance of `UnverifiedStorageProof` from the provided entries. /// /// **This function is used only in tests and benchmarks.** - #[cfg(feature = "std")] + #[cfg(any(all(feature = "std", feature = "test-helpers"), test))] pub fn try_from_entries( state_version: StateVersion, entries: &[(RawStorageKey, Option)], @@ -116,6 +118,7 @@ impl UnverifiedStorageProof { /// Creates a new instance of `UnverifiedStorageProof` from the provided db. /// /// **This function is used only in tests and benchmarks.** + #[cfg(any(feature = "test-helpers", test))] pub fn try_from_db( db: &DB, root: H::Out, @@ -249,6 +252,7 @@ impl VerifiedStorageProof { /// Storage proof size requirements. /// /// This is currently used by benchmarks when generating storage proofs. +#[cfg(feature = "test-helpers")] #[derive(Clone, Copy, Debug)] pub enum StorageProofSize { /// The storage proof is expected to be minimal. If value size may be changed, then it is @@ -260,6 +264,7 @@ pub enum StorageProofSize { } /// 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, size: StorageProofSize) -> Vec { match size { StorageProofSize::Minimal(_) => (), @@ -271,6 +276,57 @@ pub fn grow_storage_value(mut value: Vec, size: StorageProofSize) -> Vec 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( + trie: &mut TrieDBMut, + prefix: Vec, + 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) +} + #[cfg(test)] mod tests { use super::*; From 1265806d45f1047cc0cef2cc497788ca5f25968c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 22 Jun 2023 10:32:16 +0300 Subject: [PATCH 15/58] fix some nightly errors (#2225) --- bridges/modules/messages/Cargo.toml | 1 + bridges/primitives/runtime/src/storage_proof.rs | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index 1587093d749c..3b3108238faa 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -55,6 +55,7 @@ std = [ "sp-trie/std" ] runtime-benchmarks = [ + "bp-runtime/test-helpers", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 5875639dbf69..a780a508bdd3 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -19,7 +19,7 @@ use frame_support::PalletError; use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; use sp_runtime::{SaturatedConversion, StateVersion}; -use sp_std::{collections::btree_set::BTreeSet, default::Default, vec, vec::Vec}; +use sp_std::{default::Default, vec, vec::Vec}; use sp_trie::{ generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, PrefixedMemoryDB, StorageProof, TrieDBBuilder, TrieHash, @@ -28,7 +28,7 @@ use sp_trie::{ use codec::{Decode, Encode}; use hash_db::Hasher; use scale_info::TypeInfo; -use trie_db::{DBValue, Recorder, Trie}; +use trie_db::{DBValue, Trie}; #[cfg(feature = "test-helpers")] use trie_db::{TrieConfiguration, TrieDBMut}; @@ -127,6 +127,9 @@ impl UnverifiedStorageProof { where DB: hash_db::HashDBRef, { + use sp_std::collections::btree_set::BTreeSet; + use trie_db::Recorder; + let mut recorder = Recorder::>::new(); let trie = TrieDBBuilder::>::new(db, &root) .with_recorder(&mut recorder) From 8a1d0065c72fe702ea448315872488bfe62faf9c Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Thu, 22 Jun 2023 17:30:34 +0300 Subject: [PATCH 16/58] Renamings (#2226) * StorageProofSize -> StorageSize * Rename benchmarks * StorageSize -> UnverifiedStorageProofParams * Fix clippy * Fix priority boost --- .../src/messages_benchmarking.rs | 16 +- .../src/parachains_benchmarking.rs | 12 +- bridges/modules/messages/src/benchmarking.rs | 32 +-- bridges/modules/messages/src/proofs.rs | 2 +- .../messages/src/tests/messages_generation.rs | 24 +- bridges/modules/messages/src/tests/mock.rs | 16 +- bridges/modules/messages/src/weights.rs | 212 +++++++++--------- bridges/modules/messages/src/weights_ext.rs | 8 +- .../modules/parachains/src/benchmarking.rs | 10 +- bridges/modules/parachains/src/mock.rs | 2 +- bridges/modules/parachains/src/weights.rs | 60 +++-- bridges/modules/xcm-bridge-hub/src/mock.rs | 5 +- bridges/primitives/runtime/src/lib.rs | 2 +- .../primitives/runtime/src/storage_proof.rs | 34 +-- 14 files changed, 219 insertions(+), 216 deletions(-) diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index b339605554da..f39c9ee74894 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -24,7 +24,7 @@ use bp_messages::{ target_chain::FromBridgedChainMessagesProof, MessagePayload, }; use bp_polkadot_core::parachains::ParaHash; -use bp_runtime::{AccountIdOf, Chain, HashOf, Parachain, StorageProofSize}; +use bp_runtime::{AccountIdOf, Chain, HashOf, Parachain}; use codec::Encode; use frame_support::weights::Weight; use pallet_bridge_messages::{ @@ -44,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 { @@ -93,7 +89,7 @@ where params.lane, params.message_nonces.clone(), params.outbound_lane_data.clone(), - params.size, + params.proof_params, |_| prepare_inbound_message(¶ms, &message_generator), encode_all_messages, encode_lane_data, @@ -140,7 +136,7 @@ where params.lane, params.message_nonces.clone(), params.outbound_lane_data.clone(), - params.size, + params.proof_params, |_| prepare_inbound_message(¶ms, &message_generator), encode_all_messages, encode_lane_data, @@ -186,7 +182,7 @@ where let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< BridgedChainOf, ThisChainOf, - >(params.lane, params.inbound_lane_data, params.size); + >(params.lane, params.inbound_lane_data, params.proof_params); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::(state_root); @@ -217,7 +213,7 @@ where let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< BridgedChainOf, ThisChainOf, - >(params.lane, params.inbound_lane_data, params.size); + >(params.lane, params.inbound_lane_data, params.proof_params); // update runtime storage let (_, bridged_header_hash) = diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index 045653551706..e64b6fc22392 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -22,7 +22,7 @@ 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::{grow_storage_value, Chain, StorageProofSize, UnverifiedStorageProof}; +use bp_runtime::{grow_storage_value, Chain, UnverifiedStorageProof, UnverifiedStorageProofParams}; use codec::Encode; use frame_support::{sp_runtime::StateVersion, traits::Get}; use pallet_bridge_grandpa::BridgedChain; @@ -37,7 +37,7 @@ use sp_trie::{LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, TrieDBMutBuilder, pub fn prepare_parachain_heads_proof( parachains: &[ParaId], parachain_head_size: u32, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) where R: pallet_bridge_parachains::Config @@ -50,12 +50,12 @@ where StateVersion::V0 => do_prepare_parachain_heads_proof::>( parachains, parachain_head_size, - size, + proof_params, ), StateVersion::V1 => do_prepare_parachain_heads_proof::>( parachains, parachain_head_size, - size, + proof_params, ), } } @@ -63,7 +63,7 @@ where fn do_prepare_parachain_heads_proof( parachains: &[ParaId], parachain_head_size: u32, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) where R: pallet_bridge_parachains::Config @@ -88,7 +88,7 @@ where let storage_key = parachain_head_storage_key_at_source(R::ParasPalletName::get(), *parachain); let leaf_data = if i == 0 { - grow_storage_value(parachain_head.encode(), size) + grow_storage_value(parachain_head.encode(), &proof_params) } else { parachain_head.encode() }; diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 1b426ce16029..a088829bd485 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -29,7 +29,7 @@ use bp_messages::{ InboundLaneData, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; -use bp_runtime::{AccountIdOf, HashOf, StorageProofSize}; +use bp_runtime::{AccountIdOf, HashOf, UnverifiedStorageProofParams}; use codec::Decode; use frame_benchmarking::{account, v2::*}; use frame_support::weights::Weight; @@ -57,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. @@ -68,7 +68,7 @@ pub struct MessageDeliveryProofParams { /// The proof needs to include this inbound lane data. pub inbound_lane_data: InboundLaneData, /// Proof size requirements. - pub size: StorageProofSize, + pub proof_params: UnverifiedStorageProofParams, } /// Trait that must be implemented by runtime. @@ -207,7 +207,9 @@ mod benchmarks { 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, + ), }); #[extrinsic_call] @@ -238,7 +240,9 @@ mod benchmarks { 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, + ), }); #[extrinsic_call] @@ -278,7 +282,9 @@ mod benchmarks { 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, + ), }); #[extrinsic_call] @@ -302,7 +308,7 @@ mod benchmarks { // * message is dispatched (reminder: dispatch weight should be minimal); // * message requires all heavy checks done by dispatcher. #[benchmark] - fn receive_single_message_n_bytes_proof( + fn receive_single_n_bytes_message_proof( /// Proof size in KB n: Linear<1, { 16 * 1024 }>, ) { @@ -313,7 +319,7 @@ mod benchmarks { message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: false, - size: StorageProofSize::Minimal(n), + proof_params: UnverifiedStorageProofParams::from_db_size(n), }); #[extrinsic_call] @@ -358,7 +364,7 @@ mod benchmarks { .collect(), last_confirmed_nonce: 0, }, - size: StorageProofSize::Minimal(0), + proof_params: UnverifiedStorageProofParams::default(), }); #[extrinsic_call] @@ -406,7 +412,7 @@ mod benchmarks { .collect(), last_confirmed_nonce: 0, }, - size: StorageProofSize::Minimal(0), + proof_params: UnverifiedStorageProofParams::default(), }); #[extrinsic_call] @@ -459,7 +465,7 @@ mod benchmarks { .collect(), last_confirmed_nonce: 0, }, - size: StorageProofSize::Minimal(0), + proof_params: UnverifiedStorageProofParams::default(), }); #[extrinsic_call] @@ -490,7 +496,7 @@ mod benchmarks { // * message requires all heavy checks done by dispatcher. // #[benchmark(extra)] #[benchmark] - fn receive_single_message_n_bytes_proof_with_dispatch( + fn receive_single_n_bytes_message_proof_with_dispatch( /// Proof size in KB n: Linear<1, { 16 * 1024 }>, ) { @@ -501,7 +507,7 @@ mod benchmarks { message_nonces: setup.nonces(), outbound_lane_data: None, is_successful_dispatch_expected: true, - size: StorageProofSize::Minimal(n), + proof_params: UnverifiedStorageProofParams::from_db_size(n), }); #[extrinsic_call] diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index f2bf1d1b0821..adcbd4128616 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -186,7 +186,7 @@ mod tests { TEST_LANE_ID, 1..=nonces_end, outbound_lane_data, - bp_runtime::StorageProofSize::Minimal(0), + bp_runtime::UnverifiedStorageProofParams::default(), generate_dummy_message, encode_message, encode_outbound_lane_data, diff --git a/bridges/modules/messages/src/tests/messages_generation.rs b/bridges/modules/messages/src/tests/messages_generation.rs index 56df19cf8809..5e078e262e0e 100644 --- a/bridges/modules/messages/src/tests/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -21,8 +21,8 @@ use bp_messages::{ MessagePayload, OutboundLaneData, }; use bp_runtime::{ - grow_storage_value, AccountIdOf, Chain, HashOf, HasherOf, RangeInclusiveExt, StorageProofSize, - UnverifiedStorageProof, + grow_storage_value, AccountIdOf, Chain, HashOf, HasherOf, RangeInclusiveExt, + UnverifiedStorageProof, UnverifiedStorageProofParams, }; use codec::Encode; use frame_support::sp_runtime::StateVersion; @@ -52,7 +52,7 @@ pub fn prepare_messages_storage_proof, outbound_lane_data: Option, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, generate_message: impl Fn(MessageNonce) -> MessagePayload, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, @@ -71,7 +71,7 @@ where lane, message_nonces, outbound_lane_data, - size, + proof_params, generate_message, encode_message, encode_outbound_lane_data, @@ -86,7 +86,7 @@ where lane, message_nonces, outbound_lane_data, - size, + proof_params, generate_message, encode_message, encode_outbound_lane_data, @@ -100,7 +100,7 @@ where pub fn prepare_message_delivery_storage_proof( lane: LaneId, inbound_lane_data: InboundLaneData>, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, ) -> (HashOf, UnverifiedStorageProof) where HashOf: Copy + Default, @@ -110,12 +110,12 @@ where BridgedChain, ThisChain, LayoutV0>, - >(lane, inbound_lane_data, size), + >(lane, inbound_lane_data, proof_params), StateVersion::V1 => do_prepare_message_delivery_storage_proof::< BridgedChain, ThisChain, LayoutV1>, - >(lane, inbound_lane_data, size), + >(lane, inbound_lane_data, proof_params), } } @@ -127,7 +127,7 @@ fn do_prepare_messages_storage_proof, outbound_lane_data: Option, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, generate_message: impl Fn(MessageNonce) -> MessagePayload, encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, @@ -152,7 +152,7 @@ where let message_payload = match encode_message(nonce, &generate_message(nonce)) { Some(message_payload) => if i == 0 { - grow_storage_value(message_payload, size) + grow_storage_value(message_payload, &proof_params) } else { message_payload }, @@ -212,7 +212,7 @@ where fn do_prepare_message_delivery_storage_proof( lane: LaneId, inbound_lane_data: InboundLaneData>, - size: StorageProofSize, + proof_params: UnverifiedStorageProofParams, ) -> (HashOf, UnverifiedStorageProof) where L: TrieConfiguration>, @@ -225,7 +225,7 @@ where let mut mdb = MemoryDB::default(); { let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut root).build(); - let inbound_lane_data = grow_storage_value(inbound_lane_data.encode(), size); + 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"); diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 78d921f38191..de730d1d25f9 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -38,7 +38,9 @@ use bp_messages::{ ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; -use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Size, StorageProofSize}; +use bp_runtime::{ + messages::MessageDispatchResult, Chain, ChainId, Size, UnverifiedStorageProofParams, +}; use codec::{Decode, Encode}; use frame_support::{ derive_impl, parameter_types, @@ -472,7 +474,7 @@ pub fn prepare_messages_proof( TEST_LANE_ID, nonces_start..=nonces_end, outbound_lane_data, - StorageProofSize::Minimal(0), + UnverifiedStorageProofParams::default(), |nonce| messages[(nonce - nonces_start) as usize].payload.clone(), encode_all_messages, encode_lane_data, @@ -506,10 +508,12 @@ pub fn prepare_messages_delivery_proof( inbound_lane_data: InboundLaneData, ) -> FromBridgedChainMessagesDeliveryProof { // first - let's generate storage proof - let (storage_root, storage_proof) = prepare_message_delivery_storage_proof::< - BridgedChain, - ThisChain, - >(lane, inbound_lane_data, StorageProofSize::Minimal(0)); + let (storage_root, storage_proof) = + prepare_message_delivery_storage_proof::( + lane, + inbound_lane_data, + UnverifiedStorageProofParams::default(), + ); // let's now insert bridged chain header into the storage let bridged_header_hash = Default::default(); diff --git a/bridges/modules/messages/src/weights.rs b/bridges/modules/messages/src/weights.rs index 6c77fe19d9c4..72a06599b165 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-06-19, 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: @@ -53,11 +53,11 @@ pub trait WeightInfo { fn receive_single_message_proof() -> Weight; fn receive_n_messages_proof(n: u32) -> Weight; fn receive_single_message_proof_with_outbound_lane_state() -> Weight; - fn receive_single_message_n_bytes_proof(n: u32) -> 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_n_bytes_proof_with_dispatch(n: 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. @@ -81,10 +81,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 46_942 nanoseconds. - Weight::from_parts(49_198_000, 52645) + // 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)) } @@ -100,20 +100,20 @@ impl WeightInfo for BridgeWeight { /// /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) + /// 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: `490` - // Estimated: `52645` - // Minimum execution time: 47_880 nanoseconds. - Weight::from_parts(49_410_000, 52645) - // Standard Error: 62_811 - .saturating_add(Weight::from_parts(11_128_145, 0).saturating_mul(n.into())) + // 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)) } @@ -133,10 +133,10 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 56_275 nanoseconds. - Weight::from_parts(58_324_000, 52645) + // 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)) } @@ -156,14 +156,14 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16384]`. - fn receive_single_message_n_bytes_proof(n: u32) -> Weight { + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 47_796 nanoseconds. - Weight::from_parts(51_176_451, 52645) + // 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_303, 0).saturating_mul(n.into())) + .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)) } @@ -184,19 +184,19 @@ impl WeightInfo for BridgeWeight { /// /// 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(65568), - /// added: 68043, mode: MaxEncodedLen) + /// 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: `515` - // Estimated: `3530` - // Minimum execution time: 43_987 nanoseconds. - Weight::from_parts(46_149_000, 3530) + // 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(3_u64)) } @@ -217,19 +217,19 @@ impl WeightInfo for BridgeWeight { /// /// 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(65568), - /// added: 68043, mode: MaxEncodedLen) + /// 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: `532` - // Estimated: `3530` - // Minimum execution time: 44_871 nanoseconds. - Weight::from_parts(46_068_000, 3530) + // 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(4_u64)) } @@ -250,19 +250,19 @@ impl WeightInfo for BridgeWeight { /// /// 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(65568), - /// added: 68043, mode: MaxEncodedLen) + /// 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: `532` - // Estimated: `6070` - // Minimum execution time: 48_361 nanoseconds. - Weight::from_parts(49_654_000, 6070) + // 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(5_u64)) } @@ -282,14 +282,14 @@ impl WeightInfo for BridgeWeight { /// 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16384]`. - fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 47_017 nanoseconds. - Weight::from_parts(48_876_000, 52645) - // Standard Error: 686 - .saturating_add(Weight::from_parts(498_597, 0).saturating_mul(n.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)) } @@ -313,10 +313,10 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 46_942 nanoseconds. - Weight::from_parts(49_198_000, 52645) + // 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)) } @@ -332,20 +332,20 @@ impl WeightInfo for () { /// /// Storage: BridgeRialtoMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) + /// 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: `490` - // Estimated: `52645` - // Minimum execution time: 47_880 nanoseconds. - Weight::from_parts(49_410_000, 52645) - // Standard Error: 62_811 - .saturating_add(Weight::from_parts(11_128_145, 0).saturating_mul(n.into())) + // 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)) } @@ -365,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: `490` - // Estimated: `52645` - // Minimum execution time: 56_275 nanoseconds. - Weight::from_parts(58_324_000, 52645) + // 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)) } @@ -384,20 +384,20 @@ impl WeightInfo for () { /// /// Storage: BridgeUnknownMessages InboundLanes (r:1 w:1) /// - /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49180), added: - /// 51655, mode: MaxEncodedLen) + /// Proof: BridgeRialtoMessages InboundLanes (max_values: None, max_size: Some(49208), added: + /// 51683, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16384]`. /// /// The range of component `n` is `[1, 16384]`. - fn receive_single_message_n_bytes_proof(n: u32) -> Weight { + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 47_796 nanoseconds. - Weight::from_parts(51_176_451, 52645) + // 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_303, 0).saturating_mul(n.into())) + .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)) } @@ -418,19 +418,19 @@ 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(65568), - /// added: 68043, mode: MaxEncodedLen) + /// 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: `515` - // Estimated: `3530` - // Minimum execution time: 43_987 nanoseconds. - Weight::from_parts(46_149_000, 3530) + // 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(3_u64)) } @@ -451,19 +451,19 @@ 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(65568), - /// added: 68043, mode: MaxEncodedLen) + /// 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: `532` - // Estimated: `3530` - // Minimum execution time: 44_871 nanoseconds. - Weight::from_parts(46_068_000, 3530) + // 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(4_u64)) } @@ -484,19 +484,19 @@ 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(65568), - /// added: 68043, mode: MaxEncodedLen) + /// 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: `532` - // Estimated: `6070` - // Minimum execution time: 48_361 nanoseconds. - Weight::from_parts(49_654_000, 6070) + // 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(5_u64)) } @@ -516,14 +516,14 @@ impl WeightInfo for () { /// 51655, mode: MaxEncodedLen) /// /// The range of component `n` is `[1, 16384]`. - fn receive_single_message_n_bytes_proof_with_dispatch(n: u32) -> Weight { + fn receive_single_n_bytes_message_proof_with_dispatch(n: u32) -> Weight { // Proof Size summary in bytes: - // Measured: `490` - // Estimated: `52645` - // Minimum execution time: 47_017 nanoseconds. - Weight::from_parts(48_876_000, 52645) - // Standard Error: 686 - .saturating_add(Weight::from_parts(498_597, 0).saturating_mul(n.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 0e0450ed1fb6..7711e212efb0 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -411,8 +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_n_bytes_proof(2) - - Self::receive_single_message_n_bytes_proof(1); + 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 } @@ -425,8 +425,8 @@ pub trait WeightInfoExt: WeightInfo { /// details. fn message_dispatch_weight(message_size: u32) -> Weight { let message_size_in_bytes = message_size; - Self::receive_single_message_n_bytes_proof_with_dispatch(message_size_in_bytes) - .saturating_sub(Self::receive_single_message_n_bytes_proof(message_size_in_bytes)) + 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)) } } diff --git a/bridges/modules/parachains/src/benchmarking.rs b/bridges/modules/parachains/src/benchmarking.rs index 27e06a12a1d9..92ece6d688cb 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: crate::Config { 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/mock.rs b/bridges/modules/parachains/src/mock.rs index d5fdf37e36fd..746b65c435c3 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -230,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, diff --git a/bridges/modules/parachains/src/weights.rs b/bridges/modules/parachains/src/weights.rs index abddc8768947..1f92b7ff763c 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 WeightInfo for BridgeWeight { /// 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 WeightInfo for BridgeWeight { /// 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 WeightInfo for BridgeWeight { /// 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/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 6f022533b0a8..43a5536ecfed 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -110,7 +110,7 @@ impl pallet_bridge_messages::WeightInfo for TestMessagesWeights { fn receive_single_message_proof_with_outbound_lane_state() -> Weight { Weight::zero() } - fn receive_single_message_n_bytes_proof(_: u32) -> Weight { + fn receive_single_n_bytes_message_proof(_: u32) -> Weight { Weight::zero() } fn receive_delivery_proof_for_single_message() -> Weight { @@ -122,8 +122,7 @@ impl pallet_bridge_messages::WeightInfo for TestMessagesWeights { fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { Weight::zero() } - - fn receive_single_message_n_bytes_proof_with_dispatch(_: u32) -> Weight { + fn receive_single_n_bytes_message_proof_with_dispatch(_: u32) -> Weight { Weight::zero() } } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 4b5a24b38078..1c7e153dc6a5 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -41,7 +41,7 @@ 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 = "test-helpers")] -pub use storage_proof::{grow_storage_proof, grow_storage_value, StorageProofSize}; +pub use storage_proof::{grow_storage_proof, grow_storage_value, UnverifiedStorageProofParams}; pub use storage_proof::{StorageProofError, UnverifiedStorageProof, VerifiedStorageProof}; pub use storage_types::BoundedStorageValue; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index a780a508bdd3..72a2632f1de4 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -252,29 +252,31 @@ impl VerifiedStorageProof { } } -/// Storage proof size requirements. +/// Storage values size requirements. /// /// This is currently used by benchmarks when generating storage proofs. #[cfg(feature = "test-helpers")] -#[derive(Clone, Copy, Debug)] -pub enum StorageProofSize { - /// The storage proof is expected to be minimal. If value size may be changed, then it is - /// expected to have given size. - Minimal(u32), - /// The storage proof is expected to have at least given size and grow by increasing value that - /// is stored in the trie. - HasLargeLeaf(u32), +#[derive(Clone, Copy, Debug, Default)] +pub struct UnverifiedStorageProofParams { + #[allow(missing_docs)] + pub db_size: Option, +} + +#[cfg(feature = "test-helpers")] +impl UnverifiedStorageProofParams { + #[allow(missing_docs)] + pub fn from_db_size(db_size: u32) -> Self { + Self { db_size: Some(db_size) } + } } /// 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, size: StorageProofSize) -> Vec { - 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(_) => (), +pub fn grow_storage_value(mut value: Vec, params: &UnverifiedStorageProofParams) -> Vec { + 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 } From ccf29194c8a83007d61badc11b925d84d7c8e98d Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 4 Jul 2023 10:12:08 +0300 Subject: [PATCH 17/58] Fix clippy (#2240) * update async-trait to 0.1.69 * more clippy fixes --- bridges/modules/messages/src/outbound_lane.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index 0ad3e041800b..788a13e82b1b 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -326,8 +326,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), @@ -342,8 +342,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), @@ -357,8 +357,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), From 37225c0736b97c5c2fa210f6716c4e8db5ec3110 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 17 Jul 2023 12:26:09 +0300 Subject: [PATCH 18/58] Some code grooming (#2276) * some code grooming: enable warn(missing_docs) for all piblic crates + added missing documentation + removed obsolete clippy/deny workarounds * removed strange allow + added comment related to other allow * removed incorrect_clone_impl_on_copy_type which is unknown to CI clippy --- bridges/primitives/runtime/src/lib.rs | 32 ------------------- .../primitives/runtime/src/storage_proof.rs | 4 +-- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 1c7e153dc6a5..ca709caad7fb 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -457,38 +457,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 { - _phantom_data: sp_std::marker::PhantomData, - #[codec(skip)] - #[cfg(feature = "std")] - message: String, -} - -impl From for StrippableError { - fn from(_err: T) -> Self { - Self { - _phantom_data: Default::default(), - #[cfg(feature = "std")] - message: format!("{:?}", _err), - } - } -} - -impl Debug for StrippableError { - #[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 { /// 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 72a2632f1de4..ae222d0ae582 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -258,13 +258,13 @@ impl VerifiedStorageProof { #[cfg(feature = "test-helpers")] #[derive(Clone, Copy, Debug, Default)] pub struct UnverifiedStorageProofParams { - #[allow(missing_docs)] + /// Expected storage proof size in bytes. pub db_size: Option, } #[cfg(feature = "test-helpers")] impl UnverifiedStorageProofParams { - #[allow(missing_docs)] + /// 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) } } From f06c39f2f809d03a7a7f9e2aa736501e1478c1db Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 13 Jun 2024 11:15:32 +0200 Subject: [PATCH 19/58] Set `test-helpers` for `bp-runtime` --- bridges/modules/messages/src/lib.rs | 932 ------------------ bridges/modules/xcm-bridge-hub/src/mock.rs | 8 +- .../primitives/runtime/src/storage_proof.rs | 10 +- .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 2 +- .../bridge-hubs/bridge-hub-westend/Cargo.toml | 2 +- 5 files changed, 9 insertions(+), 945 deletions(-) diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 83c095341848..b3c56cfd858b 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -830,235 +830,6 @@ fn verify_and_decode_messages_proof, I: 'static>( }) } -// #[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::::set_block_number(1); -// System::::reset_events(); -// } -// -// fn send_regular_message(lane_id: LaneId) { -// get_ready_for_events(); -// -// let outbound_lane = outbound_lane::(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::::validate_message(lane_id, ®ULAR_PAYLOAD) -// .expect("validate_message has failed"); -// let artifacts = Pallet::::send_message(valid_message); -// assert_eq!(artifacts.enqueued_messages, prev_enqueued_messages + 1); -// -// // check event with assigned nonce -// assert_eq!( -// System::::events(), -// vec![EventRecord { -// phase: Phase::Initialization, -// event: TestEvent::Messages(Event::MessageAccepted { -// lane_id, -// nonce: message_nonce -// }), -// topics: vec![], -// }], -// ); -// } -// -// fn receive_messages_delivery_proof() { -// System::::set_block_number(1); -// System::::reset_events(); -// -// assert_ok!(Pallet::::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::::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::::put(MessagesOperatingMode::Basic( -// BasicOperatingMode::Halted, -// )); -// -// assert_noop!( -// Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), -// Error::::NotOperatingNormally, -// ); -// -// assert_noop!( -// Pallet::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Ok(vec![message(2, REGULAR_PAYLOAD)]).into(), -// 1, -// REGULAR_PAYLOAD.declared_weight, -// ), -// Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), -// ); -// -// assert_noop!( -// Pallet::::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::::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::::put( -// MessagesOperatingMode::RejectingOutboundMessages, -// ); -// -// assert_noop!( -// Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), -// Error::::NotOperatingNormally, -// ); -// -// assert_ok!(Pallet::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), -// 1, -// REGULAR_PAYLOAD.declared_weight, -// ),); -// -// assert_ok!(Pallet::::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::::validate_message(TEST_LANE_ID, &message_payload.clone(),), -// Error::::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::::validate_message(TEST_LANE_ID, &message_payload) -// .expect("validate_message has failed"); -// Pallet::::send_message(valid_message); -// }) -// } -// // #[test] // fn chain_verifier_rejects_invalid_message_in_send_message() { // run_test(|| { @@ -1076,87 +847,6 @@ fn verify_and_decode_messages_proof, I: 'static>( // } // // #[test] -// fn receive_messages_proof_works() { -// run_test(|| { -// assert_ok!(Pallet::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), -// 1, -// REGULAR_PAYLOAD.declared_weight, -// )); -// -// assert_eq!(InboundLanes::::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::::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::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// message_proof, -// 1, -// REGULAR_PAYLOAD.declared_weight, -// )); -// -// assert_eq!( -// InboundLanes::::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(); @@ -1174,293 +864,6 @@ fn verify_and_decode_messages_proof, I: 'static>( // } // // #[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::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), -// 1, -// declared_weight, -// ), -// Error::::InsufficientDispatchWeight -// ); -// assert_eq!(InboundLanes::::get(TEST_LANE_ID).last_delivered_nonce(), 0); -// }); -// } -// -// #[test] -// fn receive_messages_proof_rejects_invalid_proof() { -// run_test(|| { -// assert_noop!( -// Pallet::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Err(()).into(), -// 1, -// Weight::zero(), -// ), -// Error::::InvalidMessagesProof, -// ); -// }); -// } -// -// #[test] -// fn receive_messages_proof_rejects_proof_with_too_many_messages() { -// run_test(|| { -// assert_noop!( -// Pallet::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), -// u32::MAX, -// Weight::zero(), -// ), -// Error::::TooManyMessagesInTheProof, -// ); -// }); -// } -// -// #[test] -// fn receive_messages_delivery_proof_works() { -// run_test(|| { -// send_regular_message(TEST_LANE_ID); -// receive_messages_delivery_proof(); -// -// assert_eq!( -// OutboundLanes::::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::::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::::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::::receive_messages_delivery_proof( -// RuntimeOrigin::signed(1), -// TestMessagesDeliveryProof(Err(())), -// Default::default(), -// ), -// Error::::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::::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::::InvalidUnrewardedRelayersState, -// ); -// -// // when number of messages is invalid -// assert_noop!( -// Pallet::::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::::InvalidUnrewardedRelayersState, -// ); -// -// // when last delivered nonce is invalid -// assert_noop!( -// Pallet::::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::::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::::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::::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::::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::::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)); @@ -1483,148 +886,6 @@ fn verify_and_decode_messages_proof, I: 'static>( // } // // #[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 = -// ::WeightInfo::receive_messages_proof_weight( -// &proof, -// messages_count, -// REGULAR_PAYLOAD.declared_weight, -// ); -// let result = Pallet::::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 = -// ::WeightInfo::receive_messages_proof_weight( -// &proof, -// messages_count, -// REGULAR_PAYLOAD.declared_weight, -// ); -// InboundLanes::::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::::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::::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::::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); @@ -1684,75 +945,6 @@ fn verify_and_decode_messages_proof, I: 'static>( // } // // #[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::::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::::ReceptionConfirmation( -// ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected -// ), -// ); -// }); -// } -// -// #[test] -// fn storage_keys_computed_properly() { -// assert_eq!( -// PalletOperatingMode::::storage_value_final_key().to_vec(), -// bp_messages::storage_keys::operating_mode_key("Messages").0, -// ); -// -// assert_eq!( -// OutboundMessages::::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::::storage_map_final_key(TEST_LANE_ID), -// bp_messages::storage_keys::outbound_lane_data_key("Messages", &TEST_LANE_ID).0, -// ); -// -// assert_eq!( -// InboundLanes::::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::::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); @@ -1911,127 +1103,3 @@ fn verify_and_decode_messages_proof, I: 'static>( // ); // }); // } -// -// #[test] -// fn outbound_message_from_unconfigured_lane_is_rejected() { -// run_test(|| { -// assert_noop!( -// Pallet::::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), -// Error::::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::::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::::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 { -// UnrewardedRelayer { relayer: 42u64, messages: DeliveredMessages { begin: 0, end: 100 } } -// } -// -// fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage { -// 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::::get(), -// Some(mock::ActiveOutboundLanes::get().len() as u32) -// ); -// } -// } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 43a5536ecfed..df72e7a3c4fc 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -23,13 +23,7 @@ use bp_messages::{ ChainWithMessages, LaneId, MessageNonce, }; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; -use bridge_runtime_common::{ - // messages::{ - // source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, - // BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, - // }, - messages_xcm_extension::{SenderAndLane, XcmBlobHauler}, -}; +use bridge_runtime_common::messages_xcm_extension::{SenderAndLane, XcmBlobHauler}; use codec::Encode; use frame_support::{derive_impl, parameter_types, weights::RuntimeDbWeight}; use sp_core::H256; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index ae222d0ae582..48b766fda1df 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -21,8 +21,8 @@ use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; use sp_runtime::{SaturatedConversion, StateVersion}; use sp_std::{default::Default, vec, vec::Vec}; use sp_trie::{ - generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, PrefixedMemoryDB, StorageProof, - TrieDBBuilder, TrieHash, + generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, StorageProof, TrieDBBuilder, + TrieHash, }; use codec::{Decode, Encode}; @@ -108,8 +108,10 @@ impl UnverifiedStorageProof { let keys: Vec<_> = entries.iter().map(|(key, _)| key.clone()).collect(); let entries: Vec<_> = entries.iter().cloned().map(|(key, val)| (None, vec![(key, val)])).collect(); - let backend = - sp_state_machine::TrieBackend::, H>::from((entries, state_version)); + let backend = sp_state_machine::TrieBackend::, H>::from(( + entries, + state_version, + )); let root = *backend.root(); Ok((root, UnverifiedStorageProof::try_from_db(backend.backend_storage(), root, keys)?)) 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 1ac31efaf912..987372984682 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-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index c18d5036e06a..e2671d3d606d 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 } From e2e7be3bb35fb86452ab9b610355fb97ee7d1f07 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 13 Jun 2024 16:57:31 +0200 Subject: [PATCH 20/58] Adjusted BH runtimes to the latest vogue --- .../chains/chain-bridge-hub-rococo/src/lib.rs | 8 +- .../chain-bridge-hub-westend/src/lib.rs | 4 +- bridges/modules/messages/Cargo.toml | 6 +- bridges/primitives/test-utils/Cargo.toml | 2 +- .../src/bridge_common_config.rs | 19 +- .../src/bridge_to_bulletin_config.rs | 67 ++----- .../src/bridge_to_westend_config.rs | 102 +++------- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 12 +- ...idge_messages_rococo_to_rococo_bulletin.rs | 104 +++------- ...allet_bridge_messages_rococo_to_westend.rs | 104 ++-------- .../bridge-hub-rococo/tests/tests.rs | 49 +---- .../src/bridge_to_rococo_config.rs | 107 +++------- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 8 +- .../src/weights/pallet_bridge_messages.rs | 110 +++-------- .../bridge-hub-westend/tests/tests.rs | 5 +- .../bridge-hubs/test-utils/Cargo.toml | 2 +- .../src/test_cases/from_grandpa_chain.rs | 128 ++++-------- .../src/test_cases/from_parachain.rs | 135 ++++--------- .../test-utils/src/test_cases/helpers.rs | 9 +- .../src/test_data/from_grandpa_chain.rs | 184 ++++++++---------- .../src/test_data/from_parachain.rs | 182 +++++++++-------- 21 files changed, 402 insertions(+), 945 deletions(-) diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index b37a61f7de5c..c41f9cc1defc 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -107,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%`) - pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 314_037_860; + /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) + pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 82_023_783; /// 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%`) - pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 57_414_813; + /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`) + pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 58_434_469; } diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index 17ff2c858a1d..5b7fd2174053 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -97,9 +97,9 @@ frame_support::parameter_types! { /// Transaction fee that is paid at the Westend BridgeHub for delivering single inbound message. /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) - pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 94_211_536_452; + pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 94_661_076_452; /// Transaction fee that is paid at the Westend BridgeHub for delivering single outbound message confirmation. /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`) - pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_224_486_452; + pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_530_386_452; } diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index 3b3108238faa..1136dd6603a4 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -52,7 +52,7 @@ std = [ "scale-info/std", "sp-runtime/std", "sp-std/std", - "sp-trie/std" + "sp-trie/std", ] runtime-benchmarks = [ "bp-runtime/test-helpers", @@ -60,15 +60,17 @@ 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", - "bp-runtime/test-helpers" ] diff --git a/bridges/primitives/test-utils/Cargo.toml b/bridges/primitives/test-utils/Cargo.toml index 0b7fb3fec077..5e6e38933935 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/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 5551b05e2025..779cc537ee96 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 for Runt // weights are also the same for both bridges. type WeightInfo = weights::pallet_bridge_grandpa::WeightInfo; } - -/// 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 94b936889b77..39ea63692552 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; -/// 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; - -/// 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 for Runt type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_bridge_messages_rococo_to_rococo_bulletin::WeightInfo; - 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; type DeliveryConfirmationPayments = (); - type SourceHeaderChain = SourceHeaderChainAdapter; type MessageDispatch = XcmBlobMessageDispatch; 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 1681ac7f4687..383db80bfa15 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(::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; pub WestendGlobalConsensusNetworkLocation: Location = Location::new( @@ -70,7 +59,7 @@ parameter_types! { // see the `FEE_BOOST_PER_PARACHAIN_HEADER` constant get the meaning of this value pub PriorityBoostPerParachainHeader: u64 = 1_396_340_903_540_903; // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value - pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; + pub PriorityBoostPerMessage: u64 = 2_222_542_612_942_613; pub AssetHubRococoParaId: cumulus_primitives_core::ParaId = bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID.into(); pub AssetHubWestendParaId: cumulus_primitives_core::ParaId = bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID.into(); @@ -148,34 +137,6 @@ impl XcmBlobHauler for ToBridgeHubWestendXcmBlobHauler { type OnMessagesDeliveredFromWestend = XcmBlobHaulerAdapter; -/// 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; - -/// 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 for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_bridge_messages_rococo_to_westend::WeightInfo; - 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; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubWestendMessagesInstance, DeliveryRewardInBalance, >; - type SourceHeaderChain = SourceHeaderChainAdapter; 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, + RefundableParachain, 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 9aa1eeb1a4bb..a423983410b1 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::( parachains, parachain_head_size, - proof_size, + proof_params, ) } } 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 d3255ab3875d..2202d884ea9d 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 @@ -66,23 +66,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(4)) .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`) - /// 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 { + fn receive_n_messages_proof(n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights // Proof Size summary in bytes: - // Measured: `621` - // Estimated: `52645` - // Minimum execution time: 47_599_000 picoseconds. - Weight::from_parts(49_731_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)) + // 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)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -102,37 +96,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(4)) .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_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `589` - // Estimated: `52645` - // Minimum execution time: 36_072_000 picoseconds. - Weight::from_parts(37_260_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 { + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights // Proof Size summary in bytes: - // Measured: `589` - // Estimated: `52645` - // Minimum execution time: 66_995_000 picoseconds. - Weight::from_parts(68_661_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + // 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)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -182,40 +156,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .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`) - /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) - /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `PolkadotXcm::SupportedVersion` (r:1 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) - /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// 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`) - /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) - /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// 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 { - // Proof Size summary in bytes: - // Measured: `780` - // Estimated: `52645` - // Minimum execution time: 64_219_000 picoseconds. - Weight::from_parts(65_848_290, 0) - .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 43 - .saturating_add(Weight::from_parts(7_577, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(4)) + fn receive_single_n_bytes_message_proof_with_dispatch(_n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights + Weight::from_parts(1, 1) } } 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 30ea9eed4a5b..fbe2bf21c5b3 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 @@ -68,25 +68,9 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(5)) .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`: None, mode: `Measured`) - /// 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`) - /// 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 { - // Proof Size summary in bytes: - // Measured: `605` - // Estimated: `52645` - // Minimum execution time: 50_514_000 picoseconds. - Weight::from_parts(52_254_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(1)) + fn receive_n_messages_proof(_n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights + Weight::from_parts(1, 1) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -108,41 +92,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(5)) .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`: None, mode: `Measured`) - /// 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_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `573` - // Estimated: `52645` - // Minimum execution time: 39_098_000 picoseconds. - Weight::from_parts(40_577_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`: None, mode: `Measured`) - /// 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 { + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights // Proof Size summary in bytes: - // Measured: `573` - // Estimated: `52645` - // Minimum execution time: 69_120_000 picoseconds. - Weight::from_parts(71_810_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)) + // 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)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -204,40 +164,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// 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:1) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// 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`) - /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) - /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `PolkadotXcm::SupportedVersion` (r:1 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) - /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0) - /// 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`: None, mode: `Measured`) - /// 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 { - // Proof Size summary in bytes: - // Measured: `736` - // Estimated: `52645` - // Minimum execution time: 65_934_000 picoseconds. - Weight::from_parts(67_915_916, 0) - .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 65 - .saturating_add(Weight::from_parts(7_190, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(4)) + fn receive_single_n_bytes_message_proof_with_dispatch(_n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights + Weight::from_parts(1, 1) } } 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 b309232825db..1d3d9e55f7ee 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: {:?}", - ::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: {:?}", - ::Version::get() - ), - ) - } } 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 425b53da30fc..09d55f4323ab 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(::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; -/// 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; - -/// 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 for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_bridge_messages::WeightInfo; - 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; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubRococoMessagesInstance, DeliveryRewardInBalance, >; - type SourceHeaderChain = SourceHeaderChainAdapter; 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, + RefundableParachain, 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 5d4e41bd706d..627e41ef0ba6 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::( parachains, parachain_head_size, - proof_size, + proof_params, ) } } 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 305a8726fa1b..b0befec30d67 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 @@ -68,26 +68,19 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(5)) .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`: None, mode: `Measured`) - /// 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`) - /// 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 { + fn receive_n_messages_proof(n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights // Proof Size summary in bytes: - // Measured: `502` - // Estimated: `52645` - // Minimum execution time: 50_898_000 picoseconds. - Weight::from_parts(52_743_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(1)) + // 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)) } + /// 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) @@ -108,41 +101,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(5)) .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`: None, mode: `Measured`) - /// 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_1_kb() -> Weight { - // Proof Size summary in bytes: - // Measured: `433` - // Estimated: `52645` - // Minimum execution time: 39_085_000 picoseconds. - Weight::from_parts(41_623_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`: None, mode: `Measured`) - /// 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 { + fn receive_single_n_bytes_message_proof(n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights // Proof Size summary in bytes: - // Measured: `433` - // Estimated: `52645` - // Minimum execution time: 72_754_000 picoseconds. - Weight::from_parts(74_985_000, 0) - .saturating_add(Weight::from_parts(0, 52645)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)) + // 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)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -204,39 +173,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// 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:1) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// 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`) - /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) - /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `PolkadotXcm::SupportedVersion` (r:1 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) - /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0) - /// 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`: None, mode: `Measured`) - /// The range of component `i` is `[128, 2048]`. - fn receive_single_message_proof_with_dispatch(i: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `633` - // Estimated: `52645` - // Minimum execution time: 67_047_000 picoseconds. - Weight::from_parts(68_717_105, 0) - .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 138 - .saturating_add(Weight::from_parts(8_056, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(4)) + fn receive_single_n_bytes_message_proof_with_dispatch(_n: u32) -> Weight { + // TODO: FAIL-CI - regenerate weights + Weight::from_parts(1, 1) } } 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 836594140b23..763271fd7af0 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 90af4dd8f3ed..fb96d29a497a 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 bfa2f0f50f94..8f3c7de61f84 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>, - > + BridgeMessagesConfig< + + BridgeGrandpaConfig> + + BridgeMessagesConfig< Self::MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf>, 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( - sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, MPI, MB)>, +pub struct WithRemoteGrandpaChainHelperAdapter( + sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, MPI)>, ); -impl WithRemoteGrandpaChainHelper - for WithRemoteGrandpaChainHelperAdapter +impl WithRemoteGrandpaChainHelper + for WithRemoteGrandpaChainHelperAdapter where Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config - + BridgeGrandpaConfig>> + + BridgeGrandpaConfig> + BridgeMessagesConfig< MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf>, OutboundPayload = XcmAsPlainPayload, > + pallet_bridge_relayers::Config, AllPalletsWithoutSystem: OnInitialize> + OnFinalize>, 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( AccountIdOf: From, RuntimeCallOf: From> + From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -161,7 +138,8 @@ pub fn relayed_incoming_message_works( // 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, + ThisChainOf, (), >( lane_id, @@ -186,7 +164,7 @@ pub fn relayed_incoming_message_works( ( BridgeMessagesCall::::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( AccountIdOf: From, RuntimeCallOf: From> + From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { // ensure that the runtime allows free header submissions let free_headers_interval = ( // 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, + ThisChainOf, (), >( lane_id, @@ -322,7 +295,7 @@ pub fn free_relay_extrinsic_works( ( BridgeMessagesCall::::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( RuntimeCallOf: From> + From> + From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -407,7 +374,8 @@ pub fn complex_relay_extrinsic_works( // 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, + ThisChainOf, (), >( lane_id, @@ -428,7 +396,7 @@ pub fn complex_relay_extrinsic_works( }.into(), BridgeMessagesCall::::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>, RuntimeCallOf: From> + From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { run_test::(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, + ThisChainOf, (), >( LaneId::default(), @@ -526,19 +489,11 @@ where AccountIdOf: From, RuntimeHelper::Runtime: pallet_utility::Config>, - MessageThisChain: + ThisChainOf: bp_runtime::Chain>, RuntimeCallOf: From> + From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf>>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { run_test::(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, + ThisChainOf, (), >( LaneId::default(), @@ -587,13 +543,7 @@ where RuntimeHelper: WithRemoteGrandpaChainHelper, RuntimeCallOf: From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { run_test::(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, + ThisChainOf, (), >( LaneId::default(), @@ -639,19 +590,11 @@ pub fn can_calculate_fee_for_standalone_message_confirmation_transaction: From, - MessageThisChain: + ThisChainOf: bp_runtime::Chain>, RuntimeCallOf: From>, - UnderlyingChainOf>: ChainWithGrandpa, - >::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf>>, - >, - >, + BridgedChainOf: ChainWithGrandpa, { run_test::(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, + ThisChainOf, (), >( 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 12ab382d9e0f..6580648e6606 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>, 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( - sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, MB)>, +pub struct WithRemoteParachainHelperAdapter( + sp_std::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI)>, ); -impl WithRemoteParachainHelper - for WithRemoteParachainHelperAdapter +impl WithRemoteParachainHelper + for WithRemoteParachainHelperAdapter where Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config @@ -90,7 +79,6 @@ where + BridgeMessagesConfig< MPI, InboundPayload = XcmAsPlainPayload, - InboundRelayer = bp_runtime::AccountIdOf>, 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( RuntimeCallOf: From> + From> + From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -179,7 +159,8 @@ pub fn relayed_incoming_message_works( message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( lane_id, @@ -219,7 +200,7 @@ pub fn relayed_incoming_message_works( ( BridgeMessagesCall::::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( RuntimeCallOf: From> + From> + From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, { // ensure that the runtime allows free header submissions let free_headers_interval = ( message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( lane_id, @@ -390,7 +365,7 @@ pub fn free_relay_extrinsic_works( ( BridgeMessagesCall::::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( + From> + From> + From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, { helpers::relayed_incoming_message_works::< RuntimeHelper::Runtime, @@ -488,7 +456,8 @@ pub fn complex_relay_extrinsic_works( message_proof, ) = test_data::from_parachain::make_complex_relayer_delivery_proofs::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( lane_id, @@ -518,7 +487,7 @@ pub fn complex_relay_extrinsic_works( }.into(), BridgeMessagesCall::::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: From> + From> + From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, { run_test::(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::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( LaneId::default(), @@ -612,7 +575,6 @@ where RuntimeHelper::GPI, RuntimeHelper::PPI, RuntimeHelper::MPI, - _, >( relay_chain_header, grandpa_justification, @@ -637,23 +599,14 @@ where AccountIdOf: From, RuntimeHelper::Runtime: pallet_utility::Config>, - MessageThisChain: - bp_runtime::Chain>, + ThisChainOf: + Chain>, RuntimeCallOf: From> + From> + From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf>>, - >, - >, { run_test::(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::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( LaneId::default(), @@ -714,16 +668,9 @@ where RuntimeHelper: WithRemoteParachainHelper, RuntimeCallOf: From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::SourceHeaderChain: - SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof< - HashOf>, - >, - >, { run_test::(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::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( 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::(), @@ -778,22 +725,13 @@ pub fn can_calculate_fee_for_standalone_message_confirmation_transaction: From, - MessageThisChain: - bp_runtime::Chain>, + ThisChainOf: + Chain>, RuntimeCallOf: From>, - UnderlyingChainOf>: - bp_runtime::Chain + Parachain, + BridgedChainOf: Chain + Parachain, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::TargetHeaderChain: - TargetHeaderChain< - XcmAsPlainPayload, - AccountIdOf, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf>>, - >, - >, { run_test::(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::< >::BridgedChain, - RuntimeHelper::MB, + BridgedChainOf, + ThisChainOf, (), >( 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 0ce049cd1c46..c990c6e5307c 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( pub type CallsAndVerifiers = Vec<(RuntimeCallOf, Box)>; +pub type InboundRelayerId = bp_runtime::AccountIdOf>; + /// Returns relayer id at the bridged chain. pub fn relayer_id_at_bridged_chain, MPI>( -) -> Runtime::InboundRelayer { - Runtime::InboundRelayer::decode(&mut TrailingZeroInput::zeroes()).unwrap() +) -> InboundRelayerId { + 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( ) -> sp_runtime::DispatchOutcome, prepare_message_proof_import: impl FnOnce( Runtime::AccountId, - Runtime::InboundRelayer, + InboundRelayerId, 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 e5d5e7cac96b..36206a6738d3 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( bridged_header: BridgedHeader, bridged_justification: GrandpaJustification>, message_proof: FromBridgedChainMessagesProof>>, - relayer_id_at_bridged_chain: AccountIdOf>, + relayer_id_at_bridged_chain: InboundRelayerId, ) -> pallet_utility::Call where Runtime: pallet_bridge_grandpa::Config - + pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = AccountIdOf>, - > + pallet_utility::Config, + + pallet_bridge_messages::Config + + pallet_utility::Config, GPI: 'static, MPI: 'static, - >::SourceHeaderChain: SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof>>, - >, ::RuntimeCall: From> + From>, + BridgedChainOf: Chain>>, { let submit_grandpa = pallet_bridge_grandpa::Call::::submit_finality_proof { finality_target: Box::new(bridged_header), @@ -73,7 +67,7 @@ where }; let submit_message = pallet_bridge_messages::Call::::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, - >::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf>, - >, - >, ::RuntimeCall: From> + From>, + BridgedChainOf: Chain>>, { let submit_grandpa = pallet_bridge_grandpa::Call::::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( message_proof: FromBridgedChainMessagesProof>>, - relayer_id_at_bridged_chain: AccountIdOf>, + relayer_id_at_bridged_chain: InboundRelayerId, ) -> Runtime::RuntimeCall where Runtime: pallet_bridge_grandpa::Config - + pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = AccountIdOf>, - >, + + pallet_bridge_messages::Config, MPI: 'static, - >::SourceHeaderChain: SourceHeaderChain< - MessagesProof = FromBridgedChainMessagesProof>>, - >, Runtime::RuntimeCall: From>, + BridgedChainOf: Chain>>, { pallet_bridge_messages::Call::::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 + pallet_bridge_messages::Config, MPI: 'static, - >::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof< - HashOf>, - >, - >, Runtime::RuntimeCall: From>, + BridgedChainOf: Chain>>, { pallet_bridge_messages::Call::::receive_messages_delivery_proof { proof: message_delivery_proof, @@ -176,43 +152,51 @@ where } /// Prepare storage proofs of messages, stored at the (bridged) source GRANDPA chain. -pub fn make_complex_relayer_delivery_proofs( +pub fn make_complex_relayer_delivery_proofs< + BridgedChain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, xcm_message: Xcm, message_nonce: MessageNonce, message_destination: Junctions, - header_number: BlockNumberOf>, + header_number: BlockNumberOf, is_minimal_call: bool, ) -> ( - HeaderOf>, - GrandpaJustification>>, - FromBridgedChainMessagesProof>>, + HeaderOf, + GrandpaJustification>, + FromBridgedChainMessagesProof>, ) where - MB: MessageBridge, - MessageBridgedChain: Send + Sync + 'static, - UnderlyingChainOf>: 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::( - 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::( + 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, - >(state_root, header_number, is_minimal_call); + let (header, justification) = make_complex_bridged_grandpa_header_proof::( + state_root, + header_number, + is_minimal_call, + ); let message_proof = FromBridgedChainMessagesProof { bridged_header_hash: header.hash(), - storage_proof, + storage: storage_proof, lane: lane_id, nonces_start: message_nonce, nonces_end: message_nonce, @@ -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( +pub fn make_complex_relayer_confirmation_proofs< + BridgedChain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, - header_number: BlockNumberOf>, - relayer_id_at_this_chain: AccountIdOf>, + header_number: BlockNumberOf, + relayer_id_at_this_chain: AccountIdOf, relayers_state: UnrewardedRelayersState, ) -> ( - HeaderOf>, - GrandpaJustification>>, - FromBridgedChainMessagesDeliveryProof>>, + HeaderOf, + GrandpaJustification>, + FromBridgedChainMessagesDeliveryProof>, ) where - MB: MessageBridge, - MessageBridgedChain: Send + Sync + 'static, - MessageThisChain: Send + Sync + 'static, - UnderlyingChainOf>: ChainWithGrandpa, + BridgedChain: ChainWithGrandpa, + ThisChainWithMessages: ChainWithMessages, { // prepare storage proof containing message delivery proof - let (state_root, storage_proof) = prepare_message_delivery_storage_proof::( - 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::( + 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::( - state_root, - header_number, - false, - ); + let (header, justification) = + make_complex_bridged_grandpa_header_proof::(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 5d3cba4e53b5..435f5adb038b 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( +pub fn make_complex_relayer_delivery_batch( relay_chain_header: BridgedHeader, grandpa_justification: GrandpaJustification>, parachain_heads: Vec<(ParaId, ParaHash)>, para_heads_proof: ParaHeadsProof, message_proof: FromBridgedChainMessagesProof, - relayer_id_at_bridged_chain: InboundRelayer, -) -> pallet_utility::Call where - Runtime:pallet_bridge_grandpa::Config + relayer_id_at_bridged_chain: InboundRelayerId, +) -> pallet_utility::Call +where + Runtime: pallet_bridge_grandpa::Config + pallet_bridge_parachains::Config - + pallet_bridge_messages::Config< - MPI, - InboundPayload = XcmAsPlainPayload, - InboundRelayer = InboundRelayer, - > + + pallet_bridge_messages::Config + pallet_utility::Config, GPI: 'static, PPI: 'static, MPI: 'static, - ParaHash: From<<>::BridgedChain as bp_runtime::Chain>::Hash>, - <>::BridgedChain as bp_runtime::Chain>::Hash: From, - <>::SourceHeaderChain as SourceHeaderChain>::MessagesProof: - From>, - ::RuntimeCall: - From> + ParaHash: From< + <>::BridgedChain as bp_runtime::Chain>::Hash, + >, + <>::BridgedChain as bp_runtime::Chain>::Hash: + From, + BridgedChainOf: Chain + Parachain, + ::RuntimeCall: From> + From> + From>, { @@ -93,7 +90,7 @@ pub fn make_complex_relayer_delivery_batch::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, >::BridgedChain: bp_runtime::Chain + ChainWithGrandpa, - >::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof, - >, + BridgedChainOf: Chain + Parachain, ::RuntimeCall: From> + From> + From>, @@ -160,23 +153,19 @@ where } /// Prepare a call with message proof. -pub fn make_standalone_relayer_delivery_call( +pub fn make_standalone_relayer_delivery_call( message_proof: FromBridgedChainMessagesProof, - 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::RuntimeCall +where + Runtime: pallet_bridge_messages::Config, MPI: 'static, - Runtime::RuntimeCall: From>, - <>::SourceHeaderChain as SourceHeaderChain>::MessagesProof: - From>, + Runtime::RuntimeCall: From>, + BridgedChainOf: Chain + Parachain, { pallet_bridge_messages::Call::::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: 'static, Runtime::RuntimeCall: From>, - >::TargetHeaderChain: TargetHeaderChain< - XcmAsPlainPayload, - Runtime::AccountId, - MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof, - >, + BridgedChainOf: Chain + Parachain, { pallet_bridge_messages::Call::::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( +pub fn make_complex_relayer_delivery_proofs< + BridgedRelayChain, + BridgedParachain, + ThisChainWithMessages, + InnerXcmRuntimeCall, +>( lane_id: LaneId, xcm_message: Xcm, message_nonce: MessageNonce, @@ -226,24 +216,27 @@ pub fn make_complex_relayer_delivery_proofs + ChainWithGrandpa, - MB: MessageBridge, - UnderlyingChainOf>: bp_runtime::Chain + Parachain, + BridgedParachain: bp_runtime::Chain + 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::( - 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::( + 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::( + make_complex_bridged_parachain_heads_proof::( para_state_root, para_header_number, relay_header_number, @@ -253,7 +246,7 @@ where let message_proof = FromBridgedChainMessagesProof { bridged_header_hash: bridged_para_head.hash(), - storage_proof: para_storage_proof, + storage: para_storage_proof, lane: lane_id, nonces_start: message_nonce, nonces_end: message_nonce, @@ -270,12 +263,17 @@ where } /// Prepare storage proofs of message confirmations, stored at the target parachain. -pub fn make_complex_relayer_confirmation_proofs( +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>, + relayer_id_at_this_chain: AccountIdOf, relayers_state: UnrewardedRelayersState, ) -> ( HeaderOf, @@ -288,28 +286,29 @@ pub fn make_complex_relayer_confirmation_proofs + ChainWithGrandpa, - MB: MessageBridge, - UnderlyingChainOf>: bp_runtime::Chain + Parachain, + BridgedParachain: bp_runtime::Chain + Parachain, + ThisChainWithMessages: ChainWithMessages, { // prepare para storage proof containing message delivery proof - let (para_state_root, para_storage_proof) = prepare_message_delivery_storage_proof::( - 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::( + 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::( + make_complex_bridged_parachain_heads_proof::( 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( +pub fn make_complex_bridged_parachain_heads_proof( para_state_root: ParaHash, para_header_number: u32, relay_header_number: BlockNumberOf, @@ -350,20 +349,17 @@ pub fn make_complex_bridged_parachain_heads_proof( where BridgedRelayChain: bp_runtime::Chain + ChainWithGrandpa, - MB: MessageBridge, - ::BridgedChain: Send + Sync + 'static, - ::ThisChain: Send + Sync + 'static, - UnderlyingChainOf>: bp_runtime::Chain + Parachain, + BridgedParachain: bp_runtime::Chain + Parachain, { let bridged_para_head = ParaHead( - bp_test_utils::test_header_with_root::>( + bp_test_utils::test_header_with_root::>( para_header_number.into(), para_state_root, ) .encode(), ); let (relay_state_root, para_heads_proof, parachain_heads) = - prepare_parachain_heads_proof::>(vec![( + prepare_parachain_heads_proof::>(vec![( bridged_para_id, bridged_para_head.clone(), )]); From 0325bdcfb511d1e0fb8113ad6c52f208acbf739b Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 20 Jun 2024 11:32:16 +0000 Subject: [PATCH 21/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_grandpa ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_relayers ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_relayers ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_parachains ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_parachains ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_grandpa ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- .../src/weights/pallet_bridge_grandpa.rs | 20 ++- ...idge_messages_rococo_to_rococo_bulletin.rs | 146 +++++++++++----- ...allet_bridge_messages_rococo_to_westend.rs | 156 ++++++++++++----- .../src/weights/pallet_bridge_parachains.rs | 46 ++--- .../src/weights/pallet_bridge_relayers.rs | 36 ++-- .../src/weights/pallet_bridge_grandpa.rs | 20 +-- .../src/weights/pallet_bridge_messages.rs | 160 ++++++++++++------ .../src/weights/pallet_bridge_parachains.rs | 46 ++--- .../src/weights/pallet_bridge_relayers.rs | 26 +-- 9 files changed, 428 insertions(+), 228 deletions(-) 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 11e1439a1f6d..a8722256fe6d 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-05-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-06-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vicqj8em-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-1pho9goo-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: @@ -64,15 +64,17 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo Weight { + fn submit_finality_proof(p: u32, v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `438 + p * (60 ±0)` // Estimated: `51735` - // Minimum execution time: 300_829_000 picoseconds. - Weight::from_parts(321_573_000, 0) + // Minimum execution time: 295_891_000 picoseconds. + Weight::from_parts(14_601_194, 0) .saturating_add(Weight::from_parts(0, 51735)) - // Standard Error: 25_917 - .saturating_add(Weight::from_parts(48_613_160, 0).saturating_mul(p.into())) + // Standard Error: 17_801 + .saturating_add(Weight::from_parts(40_844_924, 0).saturating_mul(p.into())) + // Standard Error: 59_401 + .saturating_add(Weight::from_parts(2_533_202, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -90,8 +92,8 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `621` + // Measured: `654` // Estimated: `52645` - // Minimum execution time: 36_661_000 picoseconds. - Weight::from_parts(38_106_000, 0) + // Minimum execution time: 35_316_000 picoseconds. + Weight::from_parts(36_290_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } - fn receive_n_messages_proof(n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights + /// 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`) + /// 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, 4076]`. + /// The range of component `n` is `[1, 4076]`. + fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // 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)) + // Measured: `654` + // Estimated: `52645` + // Minimum execution time: 34_874_000 picoseconds. + Weight::from_parts(35_741_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 1_562 + .saturating_add(Weight::from_parts(9_285_039, 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) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -88,25 +98,35 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `621` + // Measured: `654` // Estimated: `52645` - // Minimum execution time: 42_211_000 picoseconds. - Weight::from_parts(43_454_000, 0) + // Minimum execution time: 42_487_000 picoseconds. + Weight::from_parts(43_343_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } - fn receive_single_n_bytes_message_proof(n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights + /// 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`) + /// 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: `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)) + // Measured: `654` + // Estimated: `52645` + // Minimum execution time: 34_349_000 picoseconds. + Weight::from_parts(35_630_173, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_976, 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) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -114,15 +134,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:1) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `588` + // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_553_000 picoseconds. - Weight::from_parts(26_205_000, 0) + // Minimum execution time: 25_229_000 picoseconds. + Weight::from_parts(26_207_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -130,15 +152,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `588` + // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_610_000 picoseconds. - Weight::from_parts(26_273_000, 0) + // Minimum execution time: 26_529_000 picoseconds. + Weight::from_parts(27_121_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -146,18 +170,52 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `588` + // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_651_000 picoseconds. - Weight::from_parts(26_172_000, 0) + // Minimum execution time: 26_455_000 picoseconds. + Weight::from_parts(27_212_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes(3)) } - fn receive_single_n_bytes_message_proof_with_dispatch(_n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights - Weight::from_parts(1, 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`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 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) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// 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`: 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 `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: 53_750_000 picoseconds. + Weight::from_parts(57_441_963, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 8 + .saturating_add(Weight::from_parts(7_382, 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 fbe2bf21c5b3..14f63ffa4ccd 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 @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_bridge_messages` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -51,7 +51,7 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// 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`: None, mode: `Measured`) + /// 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) @@ -60,22 +60,42 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `605` + // Measured: `658` // Estimated: `52645` - // Minimum execution time: 40_349_000 picoseconds. - Weight::from_parts(41_856_000, 0) + // Minimum execution time: 39_554_000 picoseconds. + Weight::from_parts(40_983_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } - fn receive_n_messages_proof(_n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights - Weight::from_parts(1, 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`) + /// 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, 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: 39_524_000 picoseconds. + Weight::from_parts(40_155_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 1_579 + .saturating_add(Weight::from_parts(9_365_386, 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) /// 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`: None, mode: `Measured`) + /// 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) @@ -84,25 +104,37 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `605` + // Measured: `658` // Estimated: `52645` - // Minimum execution time: 45_761_000 picoseconds. - Weight::from_parts(47_075_000, 0) + // Minimum execution time: 46_662_000 picoseconds. + Weight::from_parts(48_755_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } - fn receive_single_n_bytes_message_proof(n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights + /// 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`) + /// 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: `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)) + // Measured: `658` + // Estimated: `52645` + // Minimum execution time: 38_412_000 picoseconds. + Weight::from_parts(40_736_865, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_957, 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) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -114,15 +146,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `447` - // Estimated: `3912` - // Minimum execution time: 32_325_000 picoseconds. - Weight::from_parts(33_070_000, 0) - .saturating_add(Weight::from_parts(0, 3912)) + // Measured: `501` + // Estimated: `3966` + // Minimum execution time: 32_617_000 picoseconds. + Weight::from_parts(33_386_000, 0) + .saturating_add(Weight::from_parts(0, 3966)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -134,15 +168,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `447` - // Estimated: `3912` - // Minimum execution time: 32_180_000 picoseconds. - Weight::from_parts(33_202_000, 0) - .saturating_add(Weight::from_parts(0, 3912)) + // Measured: `501` + // Estimated: `3966` + // Minimum execution time: 33_877_000 picoseconds. + Weight::from_parts(34_970_000, 0) + .saturating_add(Weight::from_parts(0, 3966)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -154,18 +190,52 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `501` // Estimated: `6086` - // Minimum execution time: 36_774_000 picoseconds. - Weight::from_parts(37_774_000, 0) + // Minimum execution time: 37_891_000 picoseconds. + Weight::from_parts(39_192_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(5)) } - fn receive_single_n_bytes_message_proof_with_dispatch(_n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights - Weight::from_parts(1, 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:1) + /// 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`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 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) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0) + /// 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 `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: 56_038_000 picoseconds. + Weight::from_parts(60_365_671, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 10 + .saturating_add(Weight::from_parts(7_383, 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 ea68852804e3..2a1ea2fed7de 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 @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! -//! 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-06-20, 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-1pho9goo-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: @@ -56,20 +56,20 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf /// Proof: `BridgeWestendParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendParachains::ImportedParaHashes` (r:1 w:1) /// Proof: `BridgeWestendParachains::ImportedParaHashes` (`max_values`: Some(64), `max_size`: Some(64), added: 1054, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendGrandpa::FreeHeadersRemaining` (r:1 w:1) + /// Proof: `BridgeWestendGrandpa::FreeHeadersRemaining` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// 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: `434` + // Measured: `558` // Estimated: `2543` - // Minimum execution time: 31_135_000 picoseconds. - Weight::from_parts(32_061_351, 0) + // Minimum execution time: 34_672_000 picoseconds. + Weight::from_parts(35_987_371, 0) .saturating_add(Weight::from_parts(0, 2543)) - // Standard Error: 80_309 - .saturating_add(Weight::from_parts(99_724, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeWestendParachains::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) @@ -79,17 +79,19 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf /// Proof: `BridgeWestendParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendParachains::ImportedParaHashes` (r:1 w:1) /// Proof: `BridgeWestendParachains::ImportedParaHashes` (`max_values`: Some(64), `max_size`: Some(64), added: 1054, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendGrandpa::FreeHeadersRemaining` (r:1 w:1) + /// Proof: `BridgeWestendGrandpa::FreeHeadersRemaining` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:0 w:1) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) fn submit_parachain_heads_with_1kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `558` // Estimated: `2543` - // Minimum execution time: 32_263_000 picoseconds. - Weight::from_parts(33_139_000, 0) + // Minimum execution time: 35_961_000 picoseconds. + Weight::from_parts(36_377_000, 0) .saturating_add(Weight::from_parts(0, 2543)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeWestendParachains::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) @@ -99,16 +101,18 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf /// Proof: `BridgeWestendParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendParachains::ImportedParaHashes` (r:1 w:1) /// Proof: `BridgeWestendParachains::ImportedParaHashes` (`max_values`: Some(64), `max_size`: Some(64), added: 1054, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendGrandpa::FreeHeadersRemaining` (r:1 w:1) + /// Proof: `BridgeWestendGrandpa::FreeHeadersRemaining` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:0 w:1) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) fn submit_parachain_heads_with_16kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `558` // Estimated: `2543` - // Minimum execution time: 61_313_000 picoseconds. - Weight::from_parts(62_200_000, 0) + // Minimum execution time: 57_145_000 picoseconds. + Weight::from_parts(58_253_000, 0) .saturating_add(Weight::from_parts(0, 2543)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .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 5ab4cb900d84..a124b9276d05 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 @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! -//! 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-06-20, 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-1pho9goo-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: @@ -54,10 +54,10 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn claim_rewards() -> Weight { // Proof Size summary in bytes: - // Measured: `244` + // Measured: `278` // Estimated: `3593` - // Minimum execution time: 45_393_000 picoseconds. - Weight::from_parts(46_210_000, 0) + // Minimum execution time: 43_851_000 picoseconds. + Weight::from_parts(44_697_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -70,10 +70,10 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) fn register() -> Weight { // Proof Size summary in bytes: - // Measured: `97` + // Measured: `131` // Estimated: `4714` - // Minimum execution time: 23_767_000 picoseconds. - Weight::from_parts(24_217_000, 0) + // Minimum execution time: 24_013_000 picoseconds. + Weight::from_parts(24_625_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -84,10 +84,10 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `197` + // Measured: `231` // Estimated: `4714` - // Minimum execution time: 25_745_000 picoseconds. - Weight::from_parts(26_319_000, 0) + // Minimum execution time: 24_632_000 picoseconds. + Weight::from_parts(25_010_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -100,10 +100,10 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn slash_and_deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `300` + // Measured: `334` // Estimated: `4714` - // Minimum execution time: 27_497_000 picoseconds. - Weight::from_parts(27_939_000, 0) + // Minimum execution time: 27_022_000 picoseconds. + Weight::from_parts(27_581_000, 0) .saturating_add(Weight::from_parts(0, 4714)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -112,10 +112,10 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn register_relayer_reward() -> Weight { // Proof Size summary in bytes: - // Measured: `42` + // Measured: `76` // Estimated: `3538` - // Minimum execution time: 5_584_000 picoseconds. - Weight::from_parts(5_908_000, 0) + // Minimum execution time: 5_269_000 picoseconds. + Weight::from_parts(5_428_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/pallet_bridge_grandpa.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_grandpa.rs index e98be6ba39be..d434d274dafe 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-05-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-06-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vicqj8em-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-1pho9goo-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 pallet_bridge_grandpa::WeightInfo for WeightInfo pallet_bridge_grandpa::WeightInfo for WeightInfo pallet_bridge_messages::WeightInfo for WeightInfo< /// 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`: None, mode: `Measured`) + /// 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) @@ -60,31 +60,41 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `502` + // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_646_000 picoseconds. - Weight::from_parts(41_754_000, 0) + // Minimum execution time: 40_418_000 picoseconds. + Weight::from_parts(41_449_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } - fn receive_n_messages_proof(n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights + /// 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`) + /// 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, 4076]`. + fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // 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)) + // Measured: `522` + // Estimated: `52645` + // Minimum execution time: 39_405_000 picoseconds. + Weight::from_parts(40_283_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 11_499 + .saturating_add(Weight::from_parts(9_545_249, 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) /// 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`: None, mode: `Measured`) + /// 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) @@ -93,25 +103,36 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `502` + // Measured: `522` // Estimated: `52645` - // Minimum execution time: 45_848_000 picoseconds. - Weight::from_parts(47_036_000, 0) + // Minimum execution time: 47_084_000 picoseconds. + Weight::from_parts(48_546_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } - fn receive_single_n_bytes_message_proof(n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights + /// 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`) + /// 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: `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)) + // Measured: `522` + // Estimated: `52645` + // Minimum execution time: 39_239_000 picoseconds. + Weight::from_parts(41_253_759, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 10 + .saturating_add(Weight::from_parts(1_821, 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) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -123,15 +144,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `337` - // Estimated: `3802` - // Minimum execution time: 31_479_000 picoseconds. - Weight::from_parts(32_280_000, 0) - .saturating_add(Weight::from_parts(0, 3802)) + // Measured: `357` + // Estimated: `3822` + // Minimum execution time: 31_397_000 picoseconds. + Weight::from_parts(32_157_000, 0) + .saturating_add(Weight::from_parts(0, 3822)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -143,15 +166,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `337` - // Estimated: `3802` - // Minimum execution time: 31_807_000 picoseconds. - Weight::from_parts(32_219_000, 0) - .saturating_add(Weight::from_parts(0, 3802)) + // Measured: `357` + // Estimated: `3822` + // Minimum execution time: 32_831_000 picoseconds. + Weight::from_parts(33_908_000, 0) + .saturating_add(Weight::from_parts(0, 3822)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -163,18 +188,51 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `337` + // Measured: `357` // Estimated: `6086` - // Minimum execution time: 36_450_000 picoseconds. - Weight::from_parts(37_288_000, 0) + // Minimum execution time: 36_861_000 picoseconds. + Weight::from_parts(38_046_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(5)) } - fn receive_single_n_bytes_message_proof_with_dispatch(_n: u32) -> Weight { - // TODO: FAIL-CI - regenerate weights - Weight::from_parts(1, 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:1) + /// 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`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 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) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0) + /// 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 `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: 56_947_000 picoseconds. + Weight::from_parts(61_470_671, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 16 + .saturating_add(Weight::from_parts(6_899, 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 9819bd406541..f622d58fcad3 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 @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! -//! 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-06-20, 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-1pho9goo-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: @@ -56,18 +56,22 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf /// Proof: `BridgeRococoParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoParachains::ImportedParaHashes` (r:1 w:1) /// Proof: `BridgeRococoParachains::ImportedParaHashes` (`max_values`: Some(64), `max_size`: Some(64), added: 1054, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoGrandpa::FreeHeadersRemaining` (r:1 w:1) + /// Proof: `BridgeRococoGrandpa::FreeHeadersRemaining` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// 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: `291` + // Measured: `315` // Estimated: `2543` - // Minimum execution time: 29_994_000 picoseconds. - Weight::from_parts(31_005_636, 0) + // Minimum execution time: 33_552_000 picoseconds. + Weight::from_parts(34_528_551, 0) .saturating_add(Weight::from_parts(0, 2543)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + // Standard Error: 78_732 + .saturating_add(Weight::from_parts(86_524, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeRococoParachains::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) @@ -77,17 +81,19 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf /// Proof: `BridgeRococoParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoParachains::ImportedParaHashes` (r:1 w:1) /// Proof: `BridgeRococoParachains::ImportedParaHashes` (`max_values`: Some(64), `max_size`: Some(64), added: 1054, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoGrandpa::FreeHeadersRemaining` (r:1 w:1) + /// Proof: `BridgeRococoGrandpa::FreeHeadersRemaining` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:0 w:1) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) fn submit_parachain_heads_with_1kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `291` + // Measured: `315` // Estimated: `2543` - // Minimum execution time: 31_425_000 picoseconds. - Weight::from_parts(32_163_000, 0) + // Minimum execution time: 34_697_000 picoseconds. + Weight::from_parts(35_201_000, 0) .saturating_add(Weight::from_parts(0, 2543)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeRococoParachains::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) @@ -97,16 +103,18 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf /// Proof: `BridgeRococoParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoParachains::ImportedParaHashes` (r:1 w:1) /// Proof: `BridgeRococoParachains::ImportedParaHashes` (`max_values`: Some(64), `max_size`: Some(64), added: 1054, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoGrandpa::FreeHeadersRemaining` (r:1 w:1) + /// Proof: `BridgeRococoGrandpa::FreeHeadersRemaining` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:0 w:1) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) fn submit_parachain_heads_with_16kb_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `291` + // Measured: `315` // Estimated: `2543` - // Minimum execution time: 60_062_000 picoseconds. - Weight::from_parts(61_201_000, 0) + // Minimum execution time: 54_661_000 picoseconds. + Weight::from_parts(55_900_000, 0) .saturating_add(Weight::from_parts(0, 2543)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .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 ed96f0cd87c9..f8adb3894d5c 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 @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! -//! 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-06-20, 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-1pho9goo-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: @@ -56,8 +56,8 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `207` // Estimated: `3593` - // Minimum execution time: 45_732_000 picoseconds. - Weight::from_parts(46_282_000, 0) + // Minimum execution time: 43_407_000 picoseconds. + Weight::from_parts(44_596_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `61` // Estimated: `4714` - // Minimum execution time: 22_934_000 picoseconds. - Weight::from_parts(23_531_000, 0) + // Minimum execution time: 23_882_000 picoseconds. + Weight::from_parts(24_750_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `160` // Estimated: `4714` - // Minimum execution time: 25_187_000 picoseconds. - Weight::from_parts(25_679_000, 0) + // Minimum execution time: 23_983_000 picoseconds. + Weight::from_parts(24_806_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `263` // Estimated: `4714` - // Minimum execution time: 27_015_000 picoseconds. - Weight::from_parts(27_608_000, 0) + // Minimum execution time: 26_502_000 picoseconds. + Weight::from_parts(27_054_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `6` // Estimated: `3538` - // Minimum execution time: 5_207_000 picoseconds. - Weight::from_parts(5_394_000, 0) + // Minimum execution time: 4_700_000 picoseconds. + Weight::from_parts(4_970_000, 0) .saturating_add(Weight::from_parts(0, 3538)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) From 948e4abba921bcfae64a392a337683af15984b17 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 26 Jun 2024 22:46:13 +0200 Subject: [PATCH 22/58] Removed unused `OtherBridgedChain` and `TargetClientBase` --- bridges/modules/parachains/src/mock.rs | 35 -------------------------- bridges/relays/finality/src/base.rs | 4 --- 2 files changed, 39 deletions(-) diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index 746b65c435c3..c49b5939093c 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -283,41 +283,6 @@ impl ChainWithGrandpa for TestBridgedChain { 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; - - 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!() - } - - fn max_extrinsic_weight() -> Weight { - unreachable!() - } -} - -impl ChainWithGrandpa for OtherBridgedChain { - 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; -} - /// Return test externalities to use in tests. pub fn new_test_ext() -> sp_io::TestExternalities { sp_io::TestExternalities::new(Default::default()) diff --git a/bridges/relays/finality/src/base.rs b/bridges/relays/finality/src/base.rs index 4253468eaace..8704bff95494 100644 --- a/bridges/relays/finality/src/base.rs +++ b/bridges/relays/finality/src/base.rs @@ -45,7 +45,3 @@ pub trait SourceClientBase: RelayClient { /// Subscribe to new finality proofs. async fn finality_proofs(&self) -> Result; } - -/// Target client used in finality related loops. -#[async_trait] -pub trait TargetClientBase: RelayClient {} From b1b6ccf0a032d44cb1735588e93d310cea649af9 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 26 Jun 2024 23:00:28 +0200 Subject: [PATCH 23/58] zepter+taplo --- bridges/bin/runtime-common/Cargo.toml | 2 ++ bridges/modules/messages/Cargo.toml | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index 91a3c1665275..c55285c03587 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -62,6 +62,7 @@ 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", @@ -69,6 +70,7 @@ std = [ "frame-system/std", "hash-db/std", "log/std", + "pallet-balances/std", "pallet-bridge-grandpa/std", "pallet-bridge-messages/std", "pallet-bridge-parachains/std", diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index 1136dd6603a4..e007676fdd1e 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -43,13 +43,18 @@ 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", From 096aca1cdb5f18a4350de4b3471a3e2315203a44 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 27 Jun 2024 00:02:35 +0200 Subject: [PATCH 24/58] Revert wrong value + feature propagation --- Cargo.lock | 12 ------------ bridges/bin/runtime-common/Cargo.toml | 11 +++++------ bridges/chains/chain-bridge-hub-rococo/src/lib.rs | 2 +- bridges/modules/grandpa/Cargo.toml | 4 ---- bridges/modules/parachains/Cargo.toml | 2 -- bridges/relays/client-substrate/Cargo.toml | 3 --- bridges/relays/lib-substrate-relay/Cargo.toml | 2 -- bridges/relays/messages/Cargo.toml | 1 - .../src/bridge_to_westend_config.rs | 2 +- 9 files changed, 7 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f65f64a0fbe8..033d0c58774b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2367,7 +2367,6 @@ dependencies = [ "bp-xcm-bridge-hub-router", "frame-support", "frame-system", - "hash-db", "log", "pallet-balances", "pallet-bridge-grandpa", @@ -2378,8 +2377,6 @@ dependencies = [ "pallet-utility", "parity-scale-codec", "scale-info", - "sp-api", - "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0", @@ -8633,7 +8630,6 @@ dependencies = [ "async-std", "async-trait", "bp-messages", - "env_logger 0.11.3", "finality-relay", "futures", "hex", @@ -10097,7 +10093,6 @@ dependencies = [ "bp-header-chain", "bp-runtime", "bp-test-utils", - "finality-grandpa", "frame-benchmarking", "frame-support", "frame-system", @@ -10109,7 +10104,6 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 14.0.0", - "sp-trie", ] [[package]] @@ -10156,7 +10150,6 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 14.0.0", - "sp-trie", ] [[package]] @@ -16237,13 +16230,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", @@ -21417,9 +21407,7 @@ dependencies = [ "bp-polkadot-core", "bp-relayers", "bp-runtime", - "bridge-runtime-common", "equivocation-detector", - "finality-grandpa", "finality-relay", "frame-support", "frame-system", diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index c55285c03587..17f01ae7ae83 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -12,7 +12,6 @@ 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 } @@ -37,8 +36,6 @@ 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 } @@ -68,7 +65,6 @@ std = [ "codec/std", "frame-support/std", "frame-system/std", - "hash-db/std", "log/std", "pallet-balances/std", "pallet-bridge-grandpa/std", @@ -78,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", @@ -89,6 +83,7 @@ std = [ "xcm/std", ] runtime-benchmarks = [ + "bp-runtime/test-helpers", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -102,3 +97,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", ] integrity-test = ["static_assertions"] +test-helpers = [ + "bp-runtime/test-helpers", + "sp-trie", +] diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index c41f9cc1defc..d46801684499 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -108,7 +108,7 @@ frame_support::parameter_types! { /// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message. /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) - pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 82_023_783; + pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 315_412_180; /// 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_standalone_message_confirmation_transaction` + `33%`) diff --git a/bridges/modules/grandpa/Cargo.toml b/bridges/modules/grandpa/Cargo.toml index 307c7ddaaffd..515a97033f0d 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,7 +29,6 @@ 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 } @@ -47,7 +45,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 +53,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/parachains/Cargo.toml b/bridges/modules/parachains/Cargo.toml index 97bad724a789..cda0ee8106d5 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/relays/client-substrate/Cargo.toml b/bridges/relays/client-substrate/Cargo.toml index 66501d03691a..969cd73d6194 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/lib-substrate-relay/Cargo.toml b/bridges/relays/lib-substrate-relay/Cargo.toml index 28fee5b167ff..bcf903481680 100644 --- a/bridges/relays/lib-substrate-relay/Cargo.toml +++ b/bridges/relays/lib-substrate-relay/Cargo.toml @@ -30,10 +30,8 @@ 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 } diff --git a/bridges/relays/messages/Cargo.toml b/bridges/relays/messages/Cargo.toml index 96e441fc6730..c7a132bb3bae 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/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 383db80bfa15..07bb718bd13d 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 @@ -59,7 +59,7 @@ parameter_types! { // see the `FEE_BOOST_PER_PARACHAIN_HEADER` constant get the meaning of this value pub PriorityBoostPerParachainHeader: u64 = 1_396_340_903_540_903; // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value - pub PriorityBoostPerMessage: u64 = 2_222_542_612_942_613; + pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; pub AssetHubRococoParaId: cumulus_primitives_core::ParaId = bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID.into(); pub AssetHubWestendParaId: cumulus_primitives_core::ParaId = bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID.into(); From 7e6b6b20abac1cd24a7d7b8a837e8add10efa4c9 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 27 Jun 2024 09:49:20 +0200 Subject: [PATCH 25/58] Getter for raw proof and fix features --- bridges/bin/runtime-common/Cargo.toml | 1 + bridges/primitives/runtime/src/storage_proof.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index 17f01ae7ae83..36f27b6aa035 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -94,6 +94,7 @@ 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"] diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 48b766fda1df..d7360700f299 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -184,6 +184,11 @@ impl UnverifiedStorageProof { } Ok(VerifiedStorageProof { db: trusted_db }) } + + /// Getter for proof + pub fn proof(&self) -> &RawStorageProof { + &self.proof + } } impl Size for UnverifiedStorageProof { From c8a40eff4b5fdea7efe58aa544b136df0bf02df4 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 27 Jun 2024 15:36:14 +0200 Subject: [PATCH 26/58] Added tests for macro compatibility with `pallet_bridge_messages` + fix --- Cargo.lock | 1 + bridges/primitives/messages/src/lib.rs | 11 +- .../primitives/messages/src/target_chain.rs | 8 +- bridges/relays/lib-substrate-relay/Cargo.toml | 3 +- .../lib-substrate-relay/src/messages/mod.rs | 361 +++++++++++++++++- 5 files changed, 366 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 033d0c58774b..32a9a3e27cce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21427,6 +21427,7 @@ dependencies = [ "rbtag", "relay-substrate-client", "relay-utils", + "scale-info", "sp-consensus-grandpa", "sp-core", "sp-runtime", diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 208d252e816f..9984f8ac3222 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -21,8 +21,8 @@ use bp_header_chain::HeaderChainError; use bp_runtime::{ - messages::MessageDispatchResult, AccountIdOf, BasicOperatingMode, Chain, HashOf, OperatingMode, - RangeInclusiveExt, StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, + messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt, + StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::PalletError; @@ -514,13 +514,6 @@ where relayers_rewards } -/// The `BridgeMessagesCall` used by a chain. -pub type BridgeMessagesCallOf = BridgeMessagesCall< - AccountIdOf, - target_chain::FromBridgedChainMessagesProof>, - source_chain::FromBridgedChainMessagesDeliveryProof>, ->; - /// A minimized version of `pallet-bridge-messages::Call` that can be used without a runtime. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] #[allow(non_camel_case_types)] diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index 974cb38cbc0a..ca6ce4f55164 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -172,13 +172,9 @@ impl DeliveryPayments for () { /// Structure that may be used in place of `MessageDispatch` on chains, /// where inbound messages are forbidden. -pub struct ForbidInboundMessages( - PhantomData<(MessagesProof, DispatchPayload)>, -); +pub struct ForbidInboundMessages(PhantomData); -impl MessageDispatch - for ForbidInboundMessages -{ +impl MessageDispatch for ForbidInboundMessages { type DispatchPayload = DispatchPayload; type DispatchLevelResult = (); diff --git a/bridges/relays/lib-substrate-relay/Cargo.toml b/bridges/relays/lib-substrate-relay/Cargo.toml index bcf903481680..85b6fb0e50bf 100644 --- a/bridges/relays/lib-substrate-relay/Cargo.toml +++ b/bridges/relays/lib-substrate-relay/Cargo.toml @@ -25,7 +25,6 @@ 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 } @@ -46,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,5 +54,6 @@ sp-consensus-grandpa = { workspace = true, default-features = true } sp-runtime = { workspace = true, default-features = 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/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index b58838e5dcf9..31db66c15363 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -455,7 +455,7 @@ macro_rules! generate_receive_message_proof_call_builder { bp_runtime::paste::item! { $bridge_messages($receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_source, - proof: proof.1, + proof: Box::new(proof.1), messages_count: messages_count, dispatch_weight: dispatch_weight, }) @@ -669,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), + } + pub type CodegenBridgeMessagesCall = bp_messages::BridgeMessagesCall< + u64, + Box>, + FromBridgedChainMessagesDeliveryProof, + >; + + impl From> for RuntimeCall { + fn from(value: MockUtilityCall) -> RuntimeCall { + match value { + MockUtilityCall::batch_all(calls) => + RuntimeCall::Utility(UtilityCall::::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: 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::::receive_messages_proof { + relayer_id_at_bridged_chain: account.clone(), + proof: Box::new(receive_messages_proof.clone()), + messages_count, + dispatch_weight, + }; + + // construct mock enum Call + let mock_enum_receive_messages_proof = CodegenBridgeMessagesCall::receive_messages_proof { + relayer_id_at_bridged_chain: account.clone(), + proof: Box::new(receive_messages_proof.clone()), + 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::::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; + pub type SignedBlock = generic::SignedBlock; + + 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; + type InboundPayload = Vec; + type DeliveryPayments = (); + type DeliveryConfirmationPayments = (); + type OnMessagesDelivered = (); + type MessageDispatch = ForbidInboundMessages>; + } + + 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 for BridgedHeaderChain { + fn finalized_header_state_root( + _hash: HashOf, + ) -> Option> { + 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, + _: UnsignedTransaction, + ) -> Result + 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; + } + + #[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, + _: UnsignedTransaction, + ) -> Result + 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; + } + + #[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; + type TargetBatchCallBuilder = UtilityPalletBatchCallBuilder; + } + + 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 + ); + } +} From cdd1280d97eb27d49d917889a2a3d15254ffa498 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 28 Jun 2024 00:20:27 +0200 Subject: [PATCH 27/58] Updated new `substrate-relay` version `v2.0.0-rc1-compact-proof-ro-we` with compact proofs --- docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile index e17952ccee80..fdcec3e10411 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:v2.0.0-rc1-compact-proof-ro-we # metadata ARG VCS_REF From ded4e864098c1b8cb8efa1f73f9b19c5b0d3a470 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 10:08:27 +0200 Subject: [PATCH 28/58] Revert compact-proofs-related changes (runtimes) --- .../extensions/refund_relayer_extension.rs | 2 +- .../src/messages_benchmarking.rs | 8 +- .../runtime-common/src/messages_call_ext.rs | 2 +- .../src/parachains_benchmarking.rs | 129 +++++--- bridges/modules/messages/src/proofs.rs | 158 +++++++--- .../messages/src/tests/messages_generation.rs | 133 ++++++++- bridges/modules/messages/src/tests/mock.rs | 4 +- bridges/modules/parachains/src/lib.rs | 31 +- bridges/modules/parachains/src/proofs.rs | 115 ++++++++ bridges/primitives/header-chain/src/lib.rs | 16 +- .../primitives/messages/src/source_chain.rs | 7 +- .../primitives/messages/src/target_chain.rs | 9 +- .../polkadot-core/src/parachains.rs | 7 +- bridges/primitives/runtime/src/lib.rs | 10 +- .../primitives/runtime/src/storage_proof.rs | 275 +++++++++++++++++- bridges/primitives/test-utils/src/lib.rs | 12 +- ...ridges_zombienet_tests_injected.Dockerfile | 2 +- 17 files changed, 782 insertions(+), 138 deletions(-) create mode 100644 bridges/modules/parachains/src/proofs.rs 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 3ba20ef018df..6ba3506377d0 100644 --- a/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/extensions/refund_relayer_extension.rs @@ -1144,7 +1144,7 @@ pub(crate) mod tests { relayer_id_at_bridged_chain: relayer_account_at_bridged_chain(), proof: Box::new(FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage: Default::default(), + storage_proof: Default::default(), lane: TestLaneId::get(), nonces_start: pallet_bridge_messages::InboundLanes::::get( TEST_LANE_ID, diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index f39c9ee74894..1880e65547fe 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -84,7 +84,7 @@ where MI: 'static, { // prepare storage proof - let (state_root, storage) = + let (state_root, storage_proof) = prepare_messages_storage_proof::, ThisChainOf>( params.lane, params.message_nonces.clone(), @@ -103,7 +103,7 @@ where ( FromBridgedChainMessagesProof { bridged_header_hash, - storage, + storage_proof, lane: params.lane, nonces_start: *params.message_nonces.start(), nonces_end: *params.message_nonces.end(), @@ -131,7 +131,7 @@ where BridgedChainOf: Chain + Parachain, { // prepare storage proof - let (state_root, storage) = + let (state_root, storage_proof) = prepare_messages_storage_proof::, ThisChainOf>( params.lane, params.message_nonces.clone(), @@ -151,7 +151,7 @@ where ( FromBridgedChainMessagesProof { bridged_header_hash, - storage, + storage_proof, lane: params.lane, nonces_start: *params.message_nonces.start(), nonces_end: *params.message_nonces.end(), diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index 6d14842f8c99..a9ee1969ae0c 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -404,7 +404,7 @@ mod tests { dispatch_weight: frame_support::weights::Weight::zero(), proof: Box::new(FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage: Default::default(), + storage_proof: Default::default(), lane: LaneId([0, 0, 0, 0]), nonces_start, nonces_end, diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index e64b6fc22392..67b1d0891196 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -22,13 +22,12 @@ 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::{grow_storage_value, Chain, UnverifiedStorageProof, UnverifiedStorageProofParams}; +use bp_runtime::{grow_storage_value, record_all_trie_keys, Chain, UnverifiedStorageProofParams}; use codec::Encode; -use frame_support::{sp_runtime::StateVersion, traits::Get}; -use pallet_bridge_grandpa::BridgedChain; +use frame_support::traits::Get; use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; use sp_std::prelude::*; -use sp_trie::{LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, TrieDBMutBuilder, TrieMut}; +use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; /// Prepare proof of messages for the `receive_messages_proof` call. /// @@ -45,33 +44,6 @@ where PI: 'static, >::BridgedChain: Chain, -{ - match as Chain>::STATE_VERSION { - StateVersion::V0 => do_prepare_parachain_heads_proof::>( - parachains, - parachain_head_size, - proof_params, - ), - StateVersion::V1 => do_prepare_parachain_heads_proof::>( - parachains, - parachain_head_size, - proof_params, - ), - } -} - -fn do_prepare_parachain_heads_proof( - parachains: &[ParaId], - parachain_head_size: u32, - proof_params: UnverifiedStorageProofParams, -) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) -where - R: pallet_bridge_parachains::Config - + pallet_bridge_grandpa::Config, - PI: 'static, - >::BridgedChain: - Chain, - L: TrieConfiguration, { let parachain_head = ParaHead(vec![0u8; parachain_head_size as usize]); @@ -81,7 +53,8 @@ where let mut state_root = Default::default(); let mut mdb = MemoryDB::default(); { - let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut state_root).build(); + let mut trie = + TrieDBMutBuilderV1::::new(&mut mdb, &mut state_root).build(); // insert parachain heads for (i, parachain) in parachains.into_iter().enumerate() { @@ -95,18 +68,100 @@ where trie.insert(&storage_key.0, &leaf_data) .map_err(|_| "TrieMut::insert has failed") .expect("TrieMut::insert should not fail in benchmarks"); - storage_keys.push(storage_key.0); + storage_keys.push(storage_key); parachain_heads.push((*parachain, parachain_head.hash())) } } // generate heads storage proof - let storage_proof = - UnverifiedStorageProof::try_from_db::(&mdb, state_root, storage_keys) - .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); + let proof = record_all_trie_keys::, _>(&mdb, &state_root) + .map_err(|_| "record_all_trie_keys has failed") + .expect("record_all_trie_keys should not fail in benchmarks"); let (relay_block_number, relay_block_hash) = insert_header_to_grandpa_pallet::(state_root); - (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof }, parachain_heads) + (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof: proof }, parachain_heads) } + +// TODO: for compact proof +// /// Prepare proof of messages for the `receive_messages_proof` call. +// /// +// /// In addition to returning valid messages proof, environment is prepared to verify this message +// /// proof. +// pub fn prepare_parachain_heads_proof_compact( +// parachains: &[ParaId], +// parachain_head_size: u32, +// proof_params: UnverifiedStorageProofParams, +// ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) +// where +// R: pallet_bridge_parachains::Config +// + pallet_bridge_grandpa::Config, +// PI: 'static, +// >::BridgedChain: +// Chain, +// { +// match as Chain>::STATE_VERSION { +// StateVersion::V0 => do_prepare_parachain_heads_proof::>( +// parachains, +// parachain_head_size, +// proof_params, +// ), +// StateVersion::V1 => do_prepare_parachain_heads_proof::>( +// parachains, +// parachain_head_size, +// proof_params, +// ), +// } +// } +// +// fn do_prepare_parachain_heads_proof( +// parachains: &[ParaId], +// parachain_head_size: u32, +// proof_params: UnverifiedStorageProofParams, +// ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) +// where +// R: pallet_bridge_parachains::Config +// + pallet_bridge_grandpa::Config, +// PI: 'static, +// >::BridgedChain: +// Chain, +// L: TrieConfiguration, +// { +// let parachain_head = ParaHead(vec![0u8; parachain_head_size as usize]); +// +// // insert all heads to the trie +// let mut parachain_heads = Vec::with_capacity(parachains.len()); +// let mut storage_keys = Vec::with_capacity(parachains.len()); +// let mut state_root = Default::default(); +// let mut mdb = MemoryDB::default(); +// { +// let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut state_root).build(); +// +// // insert parachain heads +// for (i, parachain) in parachains.into_iter().enumerate() { +// let storage_key = +// parachain_head_storage_key_at_source(R::ParasPalletName::get(), *parachain); +// let leaf_data = if i == 0 { +// grow_storage_value(parachain_head.encode(), &proof_params) +// } else { +// parachain_head.encode() +// }; +// trie.insert(&storage_key.0, &leaf_data) +// .map_err(|_| "TrieMut::insert has failed") +// .expect("TrieMut::insert should not fail in benchmarks"); +// storage_keys.push(storage_key.0); +// parachain_heads.push((*parachain, parachain_head.hash())) +// } +// } +// +// // generate heads storage proof +// let storage_proof = +// UnverifiedStorageProof::try_from_db::(&mdb, state_root, storage_keys) +// .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); +// +// let (relay_block_number, relay_block_hash) = +// insert_header_to_grandpa_pallet::(state_root); +// +// (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof }, parachain_heads) +// } diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index adcbd4128616..a44ccf9dc0f7 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -18,14 +18,18 @@ use crate::{BridgedChainOf, BridgedHeaderChainOf, Config}; -use bp_header_chain::HeaderChain; +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, RangeInclusiveExt, VerifiedStorageProof}; +use bp_runtime::{ + HashOf, HasherOf, RangeInclusiveExt, RawStorageProof, StorageProofChecker, StorageProofError, + UnverifiedStorageProof, VerifiedStorageProof, +}; +use codec::Decode; use sp_std::vec::Vec; /// 'Parsed' message delivery proof - inbound lane id and its state. @@ -46,14 +50,17 @@ pub fn verify_messages_proof, I: 'static>( ) -> Result, VerificationError> { let FromBridgedChainMessagesProof { bridged_header_hash, - storage, + storage_proof, lane, nonces_start, nonces_end, } = proof; - let storage = BridgedHeaderChainOf::::verify_storage_proof(bridged_header_hash, storage) + let mut parser: StorageProofCheckerAdapter = + MessagesStorageProofAdapter::try_new_with_verified_storage_proof( + bridged_header_hash, + storage_proof, + ) .map_err(VerificationError::HeaderChain)?; - let mut parser = StorageAdapter:: { storage, _dummy: Default::default() }; let nonces_range = nonces_start..=nonces_end; // receiving proofs where end < begin is ok (if proof includes outbound lane state) @@ -69,14 +76,18 @@ pub fn verify_messages_proof, I: 'static>( 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)?; + 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)?, + lane_state: parser + .read_and_decode_outbound_lane_data(&lane) + .map_err(VerificationError::OutboundLaneStorage)?, messages, }; @@ -86,10 +97,7 @@ pub fn verify_messages_proof, I: 'static>( } // Check that the storage proof doesn't have any untouched keys. - parser - .storage - .ensure_no_unused_keys() - .map_err(VerificationError::StorageProof)?; + 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(); @@ -103,57 +111,135 @@ pub fn verify_messages_delivery_proof, I: 'static>( proof: FromBridgedChainMessagesDeliveryProof>>, ) -> Result, VerificationError> { let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = proof; - let mut storage = - T::BridgedHeaderChain::verify_storage_proof(bridged_header_hash, storage_proof) - .map_err(VerificationError::HeaderChain)?; + let mut parser: StorageProofCheckerAdapter = + 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 = storage - .get_and_decode_mandatory(&storage_inbound_lane_data_key) + 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 - storage.ensure_no_unused_keys().map_err(VerificationError::StorageProof)?; + parser.ensure_no_unused_keys().map_err(VerificationError::StorageProof)?; Ok((lane, inbound_lane_data)) } -struct StorageAdapter { - storage: VerifiedStorageProof, - _dummy: sp_std::marker::PhantomData<(T, I)>, -} +trait StorageProofAdapter, I: 'static> { + fn read_and_decode_mandatory_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result; + fn read_and_decode_optional_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, StorageProofError>; + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError>; -impl, I: 'static> StorageAdapter { fn read_and_decode_outbound_lane_data( &mut self, lane_id: &LaneId, - ) -> Result, VerificationError> { + ) -> Result, 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.storage - .get_and_decode_optional(&storage_outbound_lane_data_key) - .map_err(VerificationError::OutboundLaneStorage) + self.read_and_decode_optional_value(&storage_outbound_lane_data_key) } fn read_and_decode_message_payload( &mut self, message_key: &MessageKey, - ) -> Result { + ) -> Result { 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.storage - .get_and_decode_mandatory(&storage_message_key) - .map_err(VerificationError::MessageStorage) + self.read_and_decode_mandatory_value(&storage_message_key) + } +} + +type MessagesStorageProofAdapter = StorageProofCheckerAdapter; + +struct StorageAdapter { + storage: VerifiedStorageProof, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl, I: 'static> StorageAdapter { + fn try_new_with_verified_storage_proof( + bridged_header_hash: HashOf>, + storage_proof: UnverifiedStorageProof, + ) -> Result { + BridgedHeaderChainOf::::verify_storage_proof(bridged_header_hash, storage_proof) + .map(|storage| StorageAdapter:: { storage, _dummy: Default::default() }) + } +} + +impl, I: 'static> StorageProofAdapter for StorageAdapter { + fn read_and_decode_optional_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, StorageProofError> { + self.storage.get_and_decode_optional(&key) + } + + fn read_and_decode_mandatory_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result { + self.storage.get_and_decode_mandatory(&key) + } + + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { + self.storage.ensure_no_unused_keys() + } +} + +struct StorageProofCheckerAdapter, I: 'static> { + storage: StorageProofChecker>>, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl, I: 'static> StorageProofCheckerAdapter { + fn try_new_with_verified_storage_proof( + bridged_header_hash: HashOf>, + storage_proof: RawStorageProof, + ) -> Result { + BridgedHeaderChainOf::::verify_raw_storage_proof(bridged_header_hash, storage_proof) + .map(|storage| StorageProofCheckerAdapter:: { + storage, + _dummy: Default::default(), + }) + } +} + +impl, I: 'static> StorageProofAdapter for StorageProofCheckerAdapter { + fn read_and_decode_optional_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, StorageProofError> { + self.storage.read_and_decode_opt_value(key.as_ref()) + } + + fn read_and_decode_mandatory_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result { + self.storage.read_and_decode_mandatory_value(key.as_ref()) + } + + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { + self.storage.ensure_no_unused_nodes() } } @@ -168,7 +254,7 @@ mod tests { mock::*, }; - use bp_header_chain::{HeaderChainError, StoredHeaderDataBuilder}; + use bp_header_chain::StoredHeaderDataBuilder; use bp_runtime::{HeaderId, StorageProofError}; use codec::Encode; use sp_runtime::traits::Header; @@ -182,7 +268,7 @@ mod tests { add_unused_key: bool, test: impl Fn(FromBridgedChainMessagesProof) -> R, ) -> R { - let (state_root, storage) = prepare_messages_storage_proof::( + let (state_root, storage_proof) = prepare_messages_storage_proof::( TEST_LANE_ID, 1..=nonces_end, outbound_lane_data, @@ -214,7 +300,7 @@ mod tests { ); test(FromBridgedChainMessagesProof { bridged_header_hash, - storage, + storage_proof, lane: TEST_LANE_ID, nonces_start: 1, nonces_end, @@ -305,7 +391,7 @@ mod tests { } ), Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( - StorageProofError::InvalidProof + StorageProofError::StorageRootMismatch ))), ); } @@ -323,7 +409,7 @@ mod tests { |proof| { verify_messages_proof::(proof, 10) }, ), Err(VerificationError::HeaderChain(HeaderChainError::StorageProof( - StorageProofError::InvalidProof + StorageProofError::DuplicateNodes ))), ); } diff --git a/bridges/modules/messages/src/tests/messages_generation.rs b/bridges/modules/messages/src/tests/messages_generation.rs index 5e078e262e0e..a17754cba821 100644 --- a/bridges/modules/messages/src/tests/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -21,13 +21,16 @@ use bp_messages::{ MessagePayload, OutboundLaneData, }; use bp_runtime::{ - grow_storage_value, AccountIdOf, Chain, HashOf, HasherOf, RangeInclusiveExt, - UnverifiedStorageProof, UnverifiedStorageProofParams, + grow_storage_value, record_all_trie_keys, AccountIdOf, Chain, HashOf, HasherOf, + RangeInclusiveExt, RawStorageProof, UnverifiedStorageProof, UnverifiedStorageProofParams, }; use codec::Encode; use frame_support::sp_runtime::StateVersion; use sp_std::{ops::RangeInclusive, prelude::*}; -use sp_trie::{LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, TrieDBMutBuilder, TrieMut}; +use sp_trie::{ + trie_types::TrieDBMutBuilderV1, LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, + TrieDBMutBuilder, TrieMut, +}; /// Dummy message generation function. pub fn generate_dummy_message(_: MessageNonce) -> MessagePayload { @@ -58,6 +61,125 @@ pub fn prepare_messages_storage_proof Vec, add_duplicate_key: bool, add_unused_key: bool, +) -> (HashOf, RawStorageProof) +where + HashOf: 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; + let mut storage_keys = Vec::with_capacity(message_count as usize + 1); + let mut root = Default::default(); + let mut mdb = MemoryDB::default(); + { + let mut trie = + TrieDBMutBuilderV1::>::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, &generate_message(nonce)) { + Some(message_payload) => + if i == 0 { + grow_storage_value(message_payload, &proof_params) + } else { + message_payload + }, + None => continue, + }; + let storage_key = storage_keys::message_key( + ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, + &message_key.lane_id, + message_key.nonce, + ) + .0; + trie.insert(&storage_key, &message_payload) + .map_err(|_| "TrieMut::insert has failed") + .expect("TrieMut::insert should not fail in benchmarks"); + storage_keys.push(storage_key); + } + + // 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( + 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"); + storage_keys.push(storage_key); + } + } + + // generate storage proof to be delivered to This chain + let mut storage_proof = + record_all_trie_keys::>, _>(&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( + lane: LaneId, + inbound_lane_data: InboundLaneData>, + proof_params: UnverifiedStorageProofParams, +) -> (HashOf, RawStorageProof) +where + HashOf: Copy + Default, +{ + // prepare Bridged chain storage with inbound lane state + 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::>::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::>, _>(&mdb, &root) + .map_err(|_| "record_all_trie_keys has failed") + .expect("record_all_trie_keys should not fail in benchmarks"); + + (root, storage_proof) +} + +/// Prepare storage proof of given messages. +/// +/// Returns state trie root and nodes with prepared messages. +#[allow(clippy::too_many_arguments)] +pub fn prepare_messages_storage_proof_compact( + lane: LaneId, + message_nonces: RangeInclusive, + outbound_lane_data: Option, + proof_params: UnverifiedStorageProofParams, + generate_message: impl Fn(MessageNonce) -> MessagePayload, + encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, + encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, + add_duplicate_key: bool, + add_unused_key: bool, ) -> (HashOf, UnverifiedStorageProof) where HashOf: Copy + Default, @@ -97,7 +219,10 @@ where } /// Prepare storage proof that proves given messages delivery. -pub fn prepare_message_delivery_storage_proof( +pub fn prepare_message_delivery_storage_proof_compact< + BridgedChain: Chain, + ThisChain: ChainWithMessages, +>( lane: LaneId, inbound_lane_data: InboundLaneData>, proof_params: UnverifiedStorageProofParams, diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index de730d1d25f9..ffdd536830b5 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -470,7 +470,7 @@ pub fn prepare_messages_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) = prepare_messages_storage_proof::( + let (storage_root, storage_proof) = prepare_messages_storage_proof::( TEST_LANE_ID, nonces_start..=nonces_end, outbound_lane_data, @@ -491,7 +491,7 @@ pub fn prepare_messages_proof( Box::new(FromBridgedChainMessagesProof:: { bridged_header_hash, - storage, + storage_proof, lane, nonces_start, nonces_end, diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index c228cc40571a..269d587d9c8b 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_parachains::{ParaInfo, ParaStoredHeaderData}; use bp_polkadot_core::parachains::{ParaHash, ParaHead, 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"; @@ -83,7 +85,7 @@ pub mod pallet { }; use bp_runtime::{ BasicOperatingMode, BoundedStorageValue, OwnedBridgeModule, StorageDoubleMapKeyProvider, - StorageMapKeyProvider, StorageProofError, VerifiedStorageProof, + StorageMapKeyProvider, }; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -448,14 +450,15 @@ pub mod pallet { parachains.len() as _, ); - let mut storage = GrandpaPalletOf::::verify_storage_proof( - relay_block_hash, - parachain_heads_proof.storage_proof, - ) - .map_err(Error::::HeaderChainStorageProof)?; + let mut storage: ParachainsStorageProofAdapter = + ParachainsStorageProofAdapter::try_new_with_verified_storage_proof( + relay_block_hash, + parachain_heads_proof.storage_proof, + ) + .map_err(Error::::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!( @@ -631,16 +634,6 @@ pub mod pallet { ImportedParaHeads::::get(parachain, hash).map(|h| h.into_inner()) } - /// Read parachain head from storage proof. - fn read_parachain_head( - storage: &mut VerifiedStorageProof, - parachain: ParaId, - ) -> Result, StorageProofError> { - let parachain_head_key = - parachain_head_storage_key_at_source(T::ParasPalletName::get(), parachain); - storage.get_and_decode_optional(¶chain_head_key) - } - /// Try to update parachain head. pub(super) fn update_parachain_head( parachain: ParaId, @@ -1577,7 +1570,7 @@ pub(crate) mod tests { assert_noop!( import_parachain_1_head(0, Default::default(), parachains, proof), Error::::HeaderChainStorageProof(HeaderChainError::StorageProof( - StorageProofError::InvalidProof + StorageProofError::StorageRootMismatch )) ); }); diff --git a/bridges/modules/parachains/src/proofs.rs b/bridges/modules/parachains/src/proofs.rs new file mode 100644 index 000000000000..dbcce532caee --- /dev/null +++ b/bridges/modules/parachains/src/proofs.rs @@ -0,0 +1,115 @@ +// 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 . + +//! 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, UnverifiedStorageProof, + VerifiedStorageProof, +}; +use codec::Decode; +use frame_support::traits::Get; + +/// Abstraction over storage proof manipulation, hiding implementation details of actual storage +/// proofs. +pub trait StorageProofAdapter, I: 'static> { + /// Read and decode optional value from the proof. + fn read_and_decode_optional_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, 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, 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. +pub type ParachainsStorageProofAdapter = RawStorageProofAdapter; + +/// A `StorageProofAdapter` implementation for compact storage proofs. +pub struct CompactStorageProofAdapter { + storage: VerifiedStorageProof, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl, I: 'static> CompactStorageProofAdapter { + /// Try to create a new instance of `CompactStorageProofAdapter`. + pub fn try_new_with_verified_storage_proof( + relay_block_hash: RelayBlockHash, + storage_proof: UnverifiedStorageProof, + ) -> Result { + GrandpaPalletOf::::verify_storage_proof(relay_block_hash, storage_proof).map( + |storage| CompactStorageProofAdapter:: { storage, _dummy: Default::default() }, + ) + } +} + +impl, I: 'static> StorageProofAdapter for CompactStorageProofAdapter { + fn read_and_decode_optional_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, StorageProofError> { + self.storage.get_and_decode_optional(&key) + } + + fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { + self.storage.ensure_no_unused_keys() + } +} + +/// A `StorageProofAdapter` implementation for raw storage proofs. +pub struct RawStorageProofAdapter, I: 'static> { + storage: StorageProofChecker, + _dummy: sp_std::marker::PhantomData<(T, I)>, +} + +impl, I: 'static> RawStorageProofAdapter { + /// Try to create a new instance of `RawStorageProofAdapter`. + pub fn try_new_with_verified_storage_proof( + relay_block_hash: RelayBlockHash, + storage_proof: RawStorageProof, + ) -> Result { + GrandpaPalletOf::::verify_raw_storage_proof(relay_block_hash, storage_proof) + .map(|storage| RawStorageProofAdapter:: { storage, _dummy: Default::default() }) + } +} + +impl, I: 'static> StorageProofAdapter for RawStorageProofAdapter { + fn read_and_decode_optional_value( + &mut self, + key: &impl AsRef<[u8]>, + ) -> Result, 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/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index 08d7bcd64f3e..e488f873fa0d 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -24,8 +24,9 @@ use crate::justification::{ GrandpaJustification, JustificationVerificationContext, JustificationVerificationError, }; use bp_runtime::{ - BasicOperatingMode, BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, StorageProofError, - UnderlyingChainProvider, UnverifiedStorageProof, VerifiedStorageProof, + BasicOperatingMode, BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, RawStorageProof, + StorageProofChecker, StorageProofError, UnderlyingChainProvider, UnverifiedStorageProof, + VerifiedStorageProof, }; use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug}; @@ -78,6 +79,7 @@ impl StoredHeaderDataBuilder for H { pub trait HeaderChain { /// Returns state (storage) root of given finalized header. fn finalized_header_state_root(header_hash: HashOf) -> Option>; + /// Get a `VerifiedStorageProof` starting from an `UnverifiedStorageProof`. fn verify_storage_proof( header_hash: HashOf, @@ -88,6 +90,16 @@ pub trait HeaderChain { db.verify::>(C::STATE_VERSION, &state_root) .map_err(HeaderChainError::StorageProof) } + + /// Get storage proof checker using finalized header. + fn verify_raw_storage_proof( + header_hash: HashOf, + storage_proof: RawStorageProof, + ) -> Result>, HeaderChainError> { + let state_root = Self::finalized_header_state_root(header_hash) + .ok_or(HeaderChainError::UnknownHeader)?; + StorageProofChecker::new(state_root, storage_proof).map_err(HeaderChainError::StorageProof) + } } /// A type that can be used as a parameter in a dispatchable function. diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index 881052b8277a..64f015bdb822 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -18,7 +18,7 @@ use crate::{LaneId, MessageNonce, UnrewardedRelayer}; -use bp_runtime::{Size, UnverifiedStorageProof}; +use bp_runtime::{raw_storage_proof_size, RawStorageProof, Size}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_core::RuntimeDebug; @@ -43,14 +43,15 @@ pub struct FromBridgedChainMessagesDeliveryProof { /// 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: UnverifiedStorageProof, + pub storage_proof: RawStorageProof, /// Lane id of which messages were delivered and the proof is for. pub lane: LaneId, } impl Size for FromBridgedChainMessagesDeliveryProof { fn size(&self) -> u32 { - self.storage_proof.size() + use frame_support::sp_runtime::SaturatedConversion; + raw_storage_proof_size(&self.storage_proof).saturated_into() } } diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index ca6ce4f55164..74fecb9d9f0d 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -18,7 +18,7 @@ use crate::{LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData}; -use bp_runtime::{messages::MessageDispatchResult, Size, UnverifiedStorageProof}; +use bp_runtime::{messages::MessageDispatchResult, raw_storage_proof_size, RawStorageProof, Size}; use codec::{Decode, Encode, Error as CodecError}; use frame_support::weights::Weight; use scale_info::TypeInfo; @@ -41,8 +41,8 @@ use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, marker::PhantomData, pub struct FromBridgedChainMessagesProof { /// Hash of the finalized bridged header the proof is for. pub bridged_header_hash: BridgedHeaderHash, - /// The proved storage containing the messages being delivered. - pub storage: UnverifiedStorageProof, + /// 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. @@ -53,7 +53,8 @@ pub struct FromBridgedChainMessagesProof { impl Size for FromBridgedChainMessagesProof { fn size(&self) -> u32 { - self.storage.size() + use frame_support::sp_runtime::SaturatedConversion; + raw_storage_proof_size(&self.storage_proof).saturated_into() } } diff --git a/bridges/primitives/polkadot-core/src/parachains.rs b/bridges/primitives/polkadot-core/src/parachains.rs index 87d706a1f4fa..d54ee108386e 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::{Size, UnverifiedStorageProof}; +use bp_runtime::{raw_storage_proof_size, RawStorageProof, Size}; use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_core::Hasher; @@ -91,11 +91,12 @@ pub type ParaHasher = crate::Hasher; #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct ParaHeadsProof { /// Unverified storage proof of finalized parachain heads. - pub storage_proof: UnverifiedStorageProof, + pub storage_proof: RawStorageProof, } impl Size for ParaHeadsProof { fn size(&self) -> u32 { - self.storage_proof.size() + use frame_support::sp_runtime::SaturatedConversion; + raw_storage_proof_size(&self.storage_proof).saturated_into() } } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index ca709caad7fb..3e510a0a6453 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -41,8 +41,14 @@ 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 = "test-helpers")] -pub use storage_proof::{grow_storage_proof, grow_storage_value, UnverifiedStorageProofParams}; -pub use storage_proof::{StorageProofError, UnverifiedStorageProof, VerifiedStorageProof}; +pub use storage_proof::{ + 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, + StorageProofRequest, StorageProofType, UnverifiedStorageProof, VerifiedStorageProof, +}; pub use storage_types::BoundedStorageValue; pub mod extensions; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index d7360700f299..4134b9a47b62 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -21,24 +21,21 @@ use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; use sp_runtime::{SaturatedConversion, StateVersion}; use sp_std::{default::Default, vec, vec::Vec}; use sp_trie::{ - generate_trie_proof, verify_trie_proof, LayoutV0, LayoutV1, StorageProof, TrieDBBuilder, - TrieHash, + accessed_nodes_tracker::AccessedNodesTracker, generate_trie_proof, read_trie_value, + verify_trie_proof, LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieDBBuilder, TrieHash, }; use codec::{Decode, Encode}; -use hash_db::Hasher; +use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use scale_info::TypeInfo; +#[cfg(feature = "test-helpers")] +use sp_trie::{recorder_ext::RecorderExt, Recorder, TrieError}; use trie_db::{DBValue, Trie}; #[cfg(feature = "test-helpers")] use trie_db::{TrieConfiguration, TrieDBMut}; use crate::Size; -/// Raw storage proof type (just raw trie nodes). -pub type RawStorageProof = Vec>; - -pub type RawStorageKey = Vec; - /// Errors that can occur when interacting with `UnverifiedStorageProof` and `VerifiedStorageProof`. #[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] pub enum StorageProofError { @@ -54,10 +51,63 @@ pub enum StorageProofError { EmptyVal, /// Error decoding value associated to a provided key. DecodeError, - /// At least one key in the `VerifiedStorageProof` wasn't read. + /// 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 for StorageProofError { + fn from(e: sp_trie::StorageProofError) -> Self { + match e { + sp_trie::StorageProofError::DuplicateNodes => StorageProofError::DuplicateNodes, + } + } } +impl From for StorageProofError { + fn from(e: sp_trie::accessed_nodes_tracker::Error) -> Self { + match e { + sp_trie::accessed_nodes_tracker::Error::UnusedNodes => StorageProofError::UnusedKey, + } + } +} + +/// For backwards compatibility (relaying), we need to support several proof types. +/// This enum contains all supported storage proof types. +pub enum StorageProofType { + /// Raw proofs + Raw(RawStorageProof), + /// Compact proofs + Compact(UnverifiedStorageProof), +} + +/// For backwards compatibility (relaying), we need to support several proof types. +/// This enum contains all supported storage proof types which we can request. +pub enum StorageProofRequest { + /// Raw proofs + Raw, + /// Compact proofs + Compact, +} + +/// 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())) +} + +pub type RawStorageKey = Vec; + /// Structure representing a key-value database stored as a sorted `Vec` of tuples. /// /// The structure also contains a proof of the fact that the key-value tuples are actually present @@ -168,7 +218,10 @@ impl UnverifiedStorageProof { StateVersion::V1 => verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), } - .map_err(|_| StorageProofError::InvalidProof)?; + .map_err(|e| { + log::warn!(target: "bridge-storage-proofs", "UnverifiedStorageProof::verify error: {e:?}"); + StorageProofError::InvalidProof + })?; // Fill the `VerifiedStorageProof` let mut trusted_db = Vec::with_capacity(self.db.len()); @@ -193,7 +246,7 @@ impl UnverifiedStorageProof { impl Size for UnverifiedStorageProof { fn size(&self) -> u32 { - let proof_size = self.proof.iter().fold(0usize, |sum, node| sum.saturating_add(node.len())); + let proof_size = raw_storage_proof_size(&self.proof); let entries_size = self.db.iter().fold(0usize, |sum, (key, value)| { sum.saturating_add(key.len()) .saturating_add(value.as_ref().unwrap_or(&vec![]).len()) @@ -230,7 +283,10 @@ impl VerifiedStorageProof { key: &impl AsRef<[u8]>, ) -> Result { let val = self.get(key)?.as_ref().ok_or(StorageProofError::EmptyVal)?; - D::decode(&mut &val[..]).map_err(|_| StorageProofError::DecodeError) + D::decode(&mut &val[..]).map_err(|e| { + log::warn!(target: "bridge-storage-proofs", "get_and_decode_mandatory error: {e:?}"); + StorageProofError::DecodeError + }) } /// Returns a reference to the value corresponding to the key. @@ -339,8 +395,201 @@ pub fn grow_storage_proof( assert_eq!(added_nodes, num_extra_nodes) } +/// Record all keys for a given root. +#[cfg(feature = "test-helpers")] +pub fn record_all_keys( + db: &DB, + root: &TrieHash, +) -> Result>> +where + DB: hash_db::HashDBRef, +{ + let mut recorder = Recorder::::new(); + let trie = TrieDBBuilder::::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()) +} + +/// This struct is used to read storage values from a subset of a Merklized database. The "proof" +/// is a subset of the nodes in the Merkle structure of the database, so that it provides +/// authentication against a known Merkle root as well as the values in the +/// database themselves. +pub struct StorageProofChecker +where + H: Hasher, +{ + root: H::Out, + db: MemoryDB, + accessed_nodes_tracker: AccessedNodesTracker, +} + +impl StorageProofChecker +where + H: Hasher, +{ + /// 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 { + 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(StorageProofError::StorageRootMismatch) + } + + Ok(StorageProofChecker { root, db, accessed_nodes_tracker: recorder }) + } + + /// 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<(), 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>, StorageProofError> { + // LayoutV1 or LayoutV0 is identical for proof that only read values. + read_trie_value::, _>( + &self.db, + &self.root, + key, + Some(&mut self.accessed_nodes_tracker), + None, + ) + .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( + &mut self, + key: &[u8], + ) -> Result, StorageProofError> { + self.read_value(key).and_then(|v| { + 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( + &mut self, + key: &[u8], + ) -> Result { + 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( + &mut self, + key: &[u8], + ) -> Result, StorageProofError> { + match self.read_and_decode_value(key) { + Ok(outbound_lane_data) => Ok(outbound_lane_data), + Err(StorageProofError::StorageValueUnavailable) => Ok(None), + Err(e) => Err(e), + } + } +} + +#[cfg(test)] +pub mod tests_for_storage_proof_checker { + use super::*; + use codec::Encode; + + /// Return valid storage proof and state root. + /// + /// NOTE: This should only be used for **testing**. + #[cfg(feature = "std")] + pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { + use sp_state_machine::{backend::Backend, prove_read, InMemoryBackend}; + + let state_version = sp_runtime::StateVersion::default(); + + // construct storage proof + let backend = >::from(( + 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()))]), + (None, vec![(b"key4".to_vec(), Some((42u64, 42u32, 42u16, 42u8).encode()))]), + // Value is too big to fit in a branch node + (None, vec![(b"key11".to_vec(), Some(vec![0u8; 32]))]), + ], + state_version, + )); + let root = backend.storage_root(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()) + } + + #[test] + fn storage_proof_check() { + let (root, proof) = craft_valid_storage_proof(); + + // check proof in runtime + let mut checker = + >::new(root, proof.clone()).unwrap(); + 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(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(StorageProofError::DecodeError), + )); + + // checking proof against invalid commitment fails + assert_eq!( + >::new(sp_core::H256::random(), proof).err(), + Some(StorageProofError::StorageRootMismatch) + ); + } + + #[test] + fn proof_with_unused_items_is_rejected() { + let (root, proof) = craft_valid_storage_proof(); + + let mut checker = + StorageProofChecker::::new(root, proof.clone()).unwrap(); + checker.read_value(b"key1").unwrap().unwrap(); + checker.read_value(b"key2").unwrap(); + checker.read_value(b"key4").unwrap(); + checker.read_value(b"key22").unwrap(); + assert_eq!(checker.ensure_no_unused_nodes(), Ok(())); + + let checker = StorageProofChecker::::new(root, proof).unwrap(); + assert_eq!(checker.ensure_no_unused_nodes(), Err(StorageProofError::UnusedKey)); + } +} + #[cfg(test)] -mod tests { +mod tests_for_unverified_storage_proof { use super::*; type Hasher = sp_core::Blake2Hasher; diff --git a/bridges/primitives/test-utils/src/lib.rs b/bridges/primitives/test-utils/src/lib.rs index e2f1fe68c585..9855c32a4689 100644 --- a/bridges/primitives/test-utils/src/lib.rs +++ b/bridges/primitives/test-utils/src/lib.rs @@ -22,12 +22,12 @@ use bp_header_chain::justification::{required_justification_precommits, GrandpaJustification}; use bp_parachains::parachain_head_storage_key_at_source; use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId}; -use bp_runtime::UnverifiedStorageProof; +use bp_runtime::record_all_trie_keys; use codec::Encode; use sp_consensus_grandpa::{AuthorityId, AuthoritySignature, AuthorityWeight, SetId}; use sp_runtime::traits::{Header as HeaderT, One, Zero}; use sp_std::prelude::*; -use sp_trie::{trie_types::TrieDBMutBuilderV1, MemoryDB, TrieMut}; +use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; // Re-export all our test account utilities pub use keyring::*; @@ -191,10 +191,10 @@ pub fn prepare_parachain_heads_proof( } } - // generate storage proof to be delivered to This chain - let storage_proof = - UnverifiedStorageProof::try_from_db::(&mdb, root, storage_keys) - .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); + // generate storage proof to be delivered to this chain + let storage_proof = record_all_trie_keys::, _>(&mdb, &root) + .map_err(|_| "record_all_trie_keys has failed") + .expect("record_all_trie_keys should not fail in benchmarks"); (root, ParaHeadsProof { storage_proof }, parachains) } diff --git a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile index fdcec3e10411..634b9f188291 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:v2.0.0-rc1-compact-proof-ro-we +ARG SUBSTRATE_RELAY_IMAGE=docker.io/paritytech/substrate-relay:v1.6.5 # metadata ARG VCS_REF From 4c94e43986f19f8281ace575b33115e6305f8c64 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 11:09:04 +0200 Subject: [PATCH 29/58] Remove compact proofs so they could be restored in different branch --- .../src/parachains_benchmarking.rs | 82 --- bridges/modules/grandpa/Cargo.toml | 1 + bridges/modules/grandpa/src/lib.rs | 7 +- bridges/modules/messages/src/proofs.rs | 46 +- .../messages/src/tests/messages_generation.rs | 208 +------ bridges/modules/parachains/src/proofs.rs | 40 +- bridges/primitives/header-chain/src/lib.rs | 16 +- bridges/primitives/runtime/src/lib.rs | 6 +- .../primitives/runtime/src/storage_proof.rs | 586 ++++-------------- 9 files changed, 133 insertions(+), 859 deletions(-) diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index 67b1d0891196..bcbd779b44de 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -83,85 +83,3 @@ where (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof: proof }, parachain_heads) } - -// TODO: for compact proof -// /// Prepare proof of messages for the `receive_messages_proof` call. -// /// -// /// In addition to returning valid messages proof, environment is prepared to verify this message -// /// proof. -// pub fn prepare_parachain_heads_proof_compact( -// parachains: &[ParaId], -// parachain_head_size: u32, -// proof_params: UnverifiedStorageProofParams, -// ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) -// where -// R: pallet_bridge_parachains::Config -// + pallet_bridge_grandpa::Config, -// PI: 'static, -// >::BridgedChain: -// Chain, -// { -// match as Chain>::STATE_VERSION { -// StateVersion::V0 => do_prepare_parachain_heads_proof::>( -// parachains, -// parachain_head_size, -// proof_params, -// ), -// StateVersion::V1 => do_prepare_parachain_heads_proof::>( -// parachains, -// parachain_head_size, -// proof_params, -// ), -// } -// } -// -// fn do_prepare_parachain_heads_proof( -// parachains: &[ParaId], -// parachain_head_size: u32, -// proof_params: UnverifiedStorageProofParams, -// ) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) -// where -// R: pallet_bridge_parachains::Config -// + pallet_bridge_grandpa::Config, -// PI: 'static, -// >::BridgedChain: -// Chain, -// L: TrieConfiguration, -// { -// let parachain_head = ParaHead(vec![0u8; parachain_head_size as usize]); -// -// // insert all heads to the trie -// let mut parachain_heads = Vec::with_capacity(parachains.len()); -// let mut storage_keys = Vec::with_capacity(parachains.len()); -// let mut state_root = Default::default(); -// let mut mdb = MemoryDB::default(); -// { -// let mut trie = TrieDBMutBuilder::::new(&mut mdb, &mut state_root).build(); -// -// // insert parachain heads -// for (i, parachain) in parachains.into_iter().enumerate() { -// let storage_key = -// parachain_head_storage_key_at_source(R::ParasPalletName::get(), *parachain); -// let leaf_data = if i == 0 { -// grow_storage_value(parachain_head.encode(), &proof_params) -// } else { -// parachain_head.encode() -// }; -// trie.insert(&storage_key.0, &leaf_data) -// .map_err(|_| "TrieMut::insert has failed") -// .expect("TrieMut::insert should not fail in benchmarks"); -// storage_keys.push(storage_key.0); -// parachain_heads.push((*parachain, parachain_head.hash())) -// } -// } -// -// // generate heads storage proof -// let storage_proof = -// UnverifiedStorageProof::try_from_db::(&mdb, state_root, storage_keys) -// .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); -// -// let (relay_block_number, relay_block_hash) = -// insert_header_to_grandpa_pallet::(state_root); -// -// (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof }, parachain_heads) -// } diff --git a/bridges/modules/grandpa/Cargo.toml b/bridges/modules/grandpa/Cargo.toml index 515a97033f0d..6d1419ae5b03 100644 --- a/bridges/modules/grandpa/Cargo.toml +++ b/bridges/modules/grandpa/Cargo.toml @@ -35,6 +35,7 @@ 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 } diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 5a74442ae1bf..08ceb0b0af78 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -834,7 +834,7 @@ mod tests { System, TestBridgedChain, TestHeader, TestNumber, TestRuntime, MAX_BRIDGED_AUTHORITIES, }; use bp_header_chain::BridgeGrandpaCall; - use bp_runtime::{BasicOperatingMode, UnverifiedStorageProof}; + use bp_runtime::BasicOperatingMode; use bp_test_utils::{ authority_list, generate_owned_bridge_module_tests, make_default_justification, make_justification_for_header, JustificationGeneratorParams, ALICE, BOB, @@ -1459,10 +1459,7 @@ mod tests { #[test] fn parse_finalized_storage_accepts_valid_proof() { run_test(|| { - let (state_root, storage_proof) = UnverifiedStorageProof::try_from_entries::< - sp_core::Blake2Hasher, - >(Default::default(), &[(b"key1".to_vec(), None)]) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); + let (state_root, storage_proof) = bp_runtime::craft_valid_storage_proof(); let mut header = test_header(2); header.set_state_root(state_root); diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index a44ccf9dc0f7..f5d421925d97 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -27,7 +27,6 @@ use bp_messages::{ }; use bp_runtime::{ HashOf, HasherOf, RangeInclusiveExt, RawStorageProof, StorageProofChecker, StorageProofError, - UnverifiedStorageProof, VerifiedStorageProof, }; use codec::Decode; use sp_std::vec::Vec; @@ -168,43 +167,10 @@ trait StorageProofAdapter, I: 'static> { } } +/// Actual storage proof adapter for messages proofs. type MessagesStorageProofAdapter = StorageProofCheckerAdapter; -struct StorageAdapter { - storage: VerifiedStorageProof, - _dummy: sp_std::marker::PhantomData<(T, I)>, -} - -impl, I: 'static> StorageAdapter { - fn try_new_with_verified_storage_proof( - bridged_header_hash: HashOf>, - storage_proof: UnverifiedStorageProof, - ) -> Result { - BridgedHeaderChainOf::::verify_storage_proof(bridged_header_hash, storage_proof) - .map(|storage| StorageAdapter:: { storage, _dummy: Default::default() }) - } -} - -impl, I: 'static> StorageProofAdapter for StorageAdapter { - fn read_and_decode_optional_value( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result, StorageProofError> { - self.storage.get_and_decode_optional(&key) - } - - fn read_and_decode_mandatory_value( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result { - self.storage.get_and_decode_mandatory(&key) - } - - fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { - self.storage.ensure_no_unused_keys() - } -} - +/// A `StorageProofAdapter` implementation for raw storage proofs. struct StorageProofCheckerAdapter, I: 'static> { storage: StorageProofChecker>>, _dummy: sp_std::marker::PhantomData<(T, I)>, @@ -215,11 +181,9 @@ impl, I: 'static> StorageProofCheckerAdapter { bridged_header_hash: HashOf>, storage_proof: RawStorageProof, ) -> Result { - BridgedHeaderChainOf::::verify_raw_storage_proof(bridged_header_hash, storage_proof) - .map(|storage| StorageProofCheckerAdapter:: { - storage, - _dummy: Default::default(), - }) + BridgedHeaderChainOf::::verify_storage_proof(bridged_header_hash, storage_proof).map( + |storage| StorageProofCheckerAdapter:: { storage, _dummy: Default::default() }, + ) } } diff --git a/bridges/modules/messages/src/tests/messages_generation.rs b/bridges/modules/messages/src/tests/messages_generation.rs index a17754cba821..6c4867fa6de3 100644 --- a/bridges/modules/messages/src/tests/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -22,15 +22,11 @@ use bp_messages::{ }; use bp_runtime::{ grow_storage_value, record_all_trie_keys, AccountIdOf, Chain, HashOf, HasherOf, - RangeInclusiveExt, RawStorageProof, UnverifiedStorageProof, UnverifiedStorageProofParams, + RawStorageProof, UnverifiedStorageProofParams, }; use codec::Encode; -use frame_support::sp_runtime::StateVersion; use sp_std::{ops::RangeInclusive, prelude::*}; -use sp_trie::{ - trie_types::TrieDBMutBuilderV1, LayoutV0, LayoutV1, MemoryDB, TrieConfiguration, - TrieDBMutBuilder, TrieMut, -}; +use sp_trie::{trie_types::TrieDBMutBuilderV1, LayoutV1, MemoryDB, TrieMut}; /// Dummy message generation function. pub fn generate_dummy_message(_: MessageNonce) -> MessagePayload { @@ -165,203 +161,3 @@ where (root, storage_proof) } - -/// Prepare storage proof of given messages. -/// -/// Returns state trie root and nodes with prepared messages. -#[allow(clippy::too_many_arguments)] -pub fn prepare_messages_storage_proof_compact( - lane: LaneId, - message_nonces: RangeInclusive, - outbound_lane_data: Option, - proof_params: UnverifiedStorageProofParams, - generate_message: impl Fn(MessageNonce) -> MessagePayload, - encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, - encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, - add_duplicate_key: bool, - add_unused_key: bool, -) -> (HashOf, UnverifiedStorageProof) -where - HashOf: Copy + Default, -{ - match BridgedChain::STATE_VERSION { - StateVersion::V0 => do_prepare_messages_storage_proof::< - BridgedChain, - ThisChain, - LayoutV0>, - >( - lane, - message_nonces, - outbound_lane_data, - proof_params, - generate_message, - encode_message, - encode_outbound_lane_data, - add_duplicate_key, - add_unused_key, - ), - StateVersion::V1 => do_prepare_messages_storage_proof::< - BridgedChain, - ThisChain, - LayoutV1>, - >( - lane, - message_nonces, - outbound_lane_data, - proof_params, - generate_message, - encode_message, - encode_outbound_lane_data, - add_duplicate_key, - add_unused_key, - ), - } -} - -/// Prepare storage proof that proves given messages delivery. -pub fn prepare_message_delivery_storage_proof_compact< - BridgedChain: Chain, - ThisChain: ChainWithMessages, ->( - lane: LaneId, - inbound_lane_data: InboundLaneData>, - proof_params: UnverifiedStorageProofParams, -) -> (HashOf, UnverifiedStorageProof) -where - HashOf: Copy + Default, -{ - match BridgedChain::STATE_VERSION { - StateVersion::V0 => do_prepare_message_delivery_storage_proof::< - BridgedChain, - ThisChain, - LayoutV0>, - >(lane, inbound_lane_data, proof_params), - StateVersion::V1 => do_prepare_message_delivery_storage_proof::< - BridgedChain, - ThisChain, - LayoutV1>, - >(lane, inbound_lane_data, proof_params), - } -} - -/// Prepare storage proof of given messages. -/// -/// Returns state trie root and nodes with prepared messages. -#[allow(clippy::too_many_arguments)] -fn do_prepare_messages_storage_proof( - lane: LaneId, - message_nonces: RangeInclusive, - outbound_lane_data: Option, - proof_params: UnverifiedStorageProofParams, - generate_message: impl Fn(MessageNonce) -> MessagePayload, - encode_message: impl Fn(MessageNonce, &MessagePayload) -> Option>, - encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, - add_duplicate_key: bool, - add_unused_key: bool, -) -> (HashOf, UnverifiedStorageProof) -where - L: TrieConfiguration>, - HashOf: Copy + Default, -{ - // prepare Bridged chain storage with messages and (optionally) outbound lane state - let message_count = message_nonces.saturating_len(); - let mut storage_keys = Vec::with_capacity(message_count as usize + 1); - let mut root = Default::default(); - let mut mdb = MemoryDB::default(); - { - let mut trie = TrieDBMutBuilder::::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, &generate_message(nonce)) { - Some(message_payload) => - if i == 0 { - grow_storage_value(message_payload, &proof_params) - } else { - message_payload - }, - None => continue, - }; - let storage_key = storage_keys::message_key( - ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, - &message_key.lane_id, - message_key.nonce, - ) - .0; - trie.insert(&storage_key, &message_payload) - .map_err(|_| "TrieMut::insert has failed") - .expect("TrieMut::insert should not fail in benchmarks"); - storage_keys.push(storage_key); - } - - // 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( - 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"); - storage_keys.push(storage_key); - } - - if add_duplicate_key { - let duplicate_key = storage_keys.last().unwrap().clone(); - storage_keys.push(duplicate_key); - } - - if add_unused_key { - let storage_key = b"unused_key".to_vec(); - trie.insert(&storage_key, b"unused_value") - .map_err(|_| "TrieMut::insert has failed") - .expect("TrieMut::insert should not fail in benchmarks"); - storage_keys.push(storage_key); - } - } - - // generate storage proof to be delivered to This chain - let storage = - UnverifiedStorageProof::try_from_db::, _>(&mdb, root, storage_keys) - .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); - - (root, storage) -} - -/// Prepare storage proof of given messages delivery. -/// -/// Returns state trie root and partial storage trie. -fn do_prepare_message_delivery_storage_proof( - lane: LaneId, - inbound_lane_data: InboundLaneData>, - proof_params: UnverifiedStorageProofParams, -) -> (HashOf, UnverifiedStorageProof) -where - L: TrieConfiguration>, - HashOf: Copy + Default, -{ - // prepare Bridged chain storage with inbound lane state - 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 = TrieDBMutBuilder::::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 = UnverifiedStorageProof::try_from_db::, _>( - &mdb, - root, - vec![storage_key], - ) - .expect("UnverifiedStorageProof::try_from_db() should not fail in benchmarks"); - (root, storage) -} diff --git a/bridges/modules/parachains/src/proofs.rs b/bridges/modules/parachains/src/proofs.rs index dbcce532caee..dcf22229f342 100644 --- a/bridges/modules/parachains/src/proofs.rs +++ b/bridges/modules/parachains/src/proofs.rs @@ -20,10 +20,7 @@ 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, UnverifiedStorageProof, - VerifiedStorageProof, -}; +use bp_runtime::{RawStorageProof, StorageProofChecker, StorageProofError}; use codec::Decode; use frame_support::traits::Get; @@ -50,40 +47,9 @@ pub trait StorageProofAdapter, I: 'static> { } } -/// Actual storage proof adapter. +/// Actual storage proof adapter for parachain proofs. pub type ParachainsStorageProofAdapter = RawStorageProofAdapter; -/// A `StorageProofAdapter` implementation for compact storage proofs. -pub struct CompactStorageProofAdapter { - storage: VerifiedStorageProof, - _dummy: sp_std::marker::PhantomData<(T, I)>, -} - -impl, I: 'static> CompactStorageProofAdapter { - /// Try to create a new instance of `CompactStorageProofAdapter`. - pub fn try_new_with_verified_storage_proof( - relay_block_hash: RelayBlockHash, - storage_proof: UnverifiedStorageProof, - ) -> Result { - GrandpaPalletOf::::verify_storage_proof(relay_block_hash, storage_proof).map( - |storage| CompactStorageProofAdapter:: { storage, _dummy: Default::default() }, - ) - } -} - -impl, I: 'static> StorageProofAdapter for CompactStorageProofAdapter { - fn read_and_decode_optional_value( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result, StorageProofError> { - self.storage.get_and_decode_optional(&key) - } - - fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { - self.storage.ensure_no_unused_keys() - } -} - /// A `StorageProofAdapter` implementation for raw storage proofs. pub struct RawStorageProofAdapter, I: 'static> { storage: StorageProofChecker, @@ -96,7 +62,7 @@ impl, I: 'static> RawStorageProofAdapter { relay_block_hash: RelayBlockHash, storage_proof: RawStorageProof, ) -> Result { - GrandpaPalletOf::::verify_raw_storage_proof(relay_block_hash, storage_proof) + GrandpaPalletOf::::verify_storage_proof(relay_block_hash, storage_proof) .map(|storage| RawStorageProofAdapter:: { storage, _dummy: Default::default() }) } } diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index e488f873fa0d..26295dee1801 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -25,8 +25,7 @@ use crate::justification::{ }; use bp_runtime::{ BasicOperatingMode, BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, RawStorageProof, - StorageProofChecker, StorageProofError, UnderlyingChainProvider, UnverifiedStorageProof, - VerifiedStorageProof, + StorageProofChecker, StorageProofError, UnderlyingChainProvider, }; use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug}; @@ -80,19 +79,8 @@ pub trait HeaderChain { /// Returns state (storage) root of given finalized header. fn finalized_header_state_root(header_hash: HashOf) -> Option>; - /// Get a `VerifiedStorageProof` starting from an `UnverifiedStorageProof`. - fn verify_storage_proof( - header_hash: HashOf, - db: UnverifiedStorageProof, - ) -> Result { - let state_root = Self::finalized_header_state_root(header_hash) - .ok_or(HeaderChainError::UnknownHeader)?; - db.verify::>(C::STATE_VERSION, &state_root) - .map_err(HeaderChainError::StorageProof) - } - /// Get storage proof checker using finalized header. - fn verify_raw_storage_proof( + fn verify_storage_proof( header_hash: HashOf, storage_proof: RawStorageProof, ) -> Result>, HeaderChainError> { diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 3e510a0a6453..425dd32f8ff3 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -42,12 +42,12 @@ pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; #[cfg(feature = "test-helpers")] pub use storage_proof::{ - grow_storage_proof, grow_storage_value, record_all_keys as record_all_trie_keys, - UnverifiedStorageProofParams, + craft_valid_storage_proof, 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, - StorageProofRequest, StorageProofType, UnverifiedStorageProof, VerifiedStorageProof, + StorageProofRequest, StorageProofResult, }; pub use storage_types::BoundedStorageValue; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 4134b9a47b62..27cee2ddca5c 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -17,12 +17,11 @@ //! Logic for working with storage proofs. use frame_support::PalletError; -use sp_core::{storage::TrackedStorageKey, RuntimeDebug}; -use sp_runtime::{SaturatedConversion, StateVersion}; -use sp_std::{default::Default, vec, vec::Vec}; +use sp_core::RuntimeDebug; +use sp_std::{default::Default, vec::Vec}; use sp_trie::{ - accessed_nodes_tracker::AccessedNodesTracker, generate_trie_proof, read_trie_value, - verify_trie_proof, LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieDBBuilder, TrieHash, + accessed_nodes_tracker::AccessedNodesTracker, read_trie_value, LayoutV1, MemoryDB, + StorageProof, TrieDBBuilder, TrieHash, }; use codec::{Decode, Encode}; @@ -30,12 +29,10 @@ use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use scale_info::TypeInfo; #[cfg(feature = "test-helpers")] use sp_trie::{recorder_ext::RecorderExt, Recorder, TrieError}; -use trie_db::{DBValue, Trie}; +use trie_db::Trie; #[cfg(feature = "test-helpers")] use trie_db::{TrieConfiguration, TrieDBMut}; -use crate::Size; - /// Errors that can occur when interacting with `UnverifiedStorageProof` and `VerifiedStorageProof`. #[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)] pub enum StorageProofError { @@ -80,11 +77,9 @@ impl From for StorageProofError { /// For backwards compatibility (relaying), we need to support several proof types. /// This enum contains all supported storage proof types. -pub enum StorageProofType { +pub enum StorageProofResult { /// Raw proofs Raw(RawStorageProof), - /// Compact proofs - Compact(UnverifiedStorageProof), } /// For backwards compatibility (relaying), we need to support several proof types. @@ -92,8 +87,6 @@ pub enum StorageProofType { pub enum StorageProofRequest { /// Raw proofs Raw, - /// Compact proofs - Compact, } /// Raw storage proof type (just raw trie nodes). @@ -106,215 +99,6 @@ pub fn raw_storage_proof_size(raw_storage_proof: &RawStorageProof) -> usize { .fold(0usize, |sum, node| sum.saturating_add(node.len())) } -pub type RawStorageKey = Vec; - -/// Structure representing a key-value database stored as a sorted `Vec` of tuples. -/// -/// The structure also contains a proof of the fact that the key-value tuples are actually present -/// in the chain storage. -#[derive(Clone, Default, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct UnverifiedStorageProof { - proof: RawStorageProof, - db: Vec<(RawStorageKey, Option)>, -} - -impl UnverifiedStorageProof { - /// Creates a new instance of `UnverifiedStorageProof`. - pub fn try_new( - read_proof: StorageProof, - root: TrieHash>, - mut keys: Vec + Ord>, - ) -> Result { - // It's ok to use `LayoutV1` in this function, no matter the actual underlying layout, - // because we only perform read operations. When reading `LayoutV0` and `LayoutV1` lead to - // the same result. - let mem_db = read_proof.into_memory_db(); - let trie_db = TrieDBBuilder::>::new(&mem_db, &root).build(); - - let trie_proof = generate_trie_proof::, _, _, _>(&mem_db, root, &keys) - .map_err(|_| StorageProofError::UnableToGenerateTrieProof)?; - - let mut entries = Vec::with_capacity(keys.len()); - keys.sort(); - for key in keys { - let val = trie_db.get(key.as_ref()).map_err(|_| StorageProofError::UnavailableKey)?; - entries.push((key.as_ref().to_vec(), val)); - } - - Ok(Self { proof: trie_proof, db: entries }) - } - - /// Creates a new instance of `UnverifiedStorageProof` from the provided entries. - /// - /// **This function is used only in tests and benchmarks.** - #[cfg(any(all(feature = "std", feature = "test-helpers"), test))] - pub fn try_from_entries( - state_version: StateVersion, - entries: &[(RawStorageKey, Option)], - ) -> Result<(H::Out, UnverifiedStorageProof), StorageProofError> - where - H::Out: codec::Codec, - { - let keys: Vec<_> = entries.iter().map(|(key, _)| key.clone()).collect(); - let entries: Vec<_> = - entries.iter().cloned().map(|(key, val)| (None, vec![(key, val)])).collect(); - let backend = sp_state_machine::TrieBackend::, H>::from(( - entries, - state_version, - )); - let root = *backend.root(); - - Ok((root, UnverifiedStorageProof::try_from_db(backend.backend_storage(), root, keys)?)) - } - - /// Creates a new instance of `UnverifiedStorageProof` from the provided db. - /// - /// **This function is used only in tests and benchmarks.** - #[cfg(any(feature = "test-helpers", test))] - pub fn try_from_db( - db: &DB, - root: H::Out, - keys: Vec + Ord>, - ) -> Result - where - DB: hash_db::HashDBRef, - { - use sp_std::collections::btree_set::BTreeSet; - use trie_db::Recorder; - - let mut recorder = Recorder::>::new(); - let trie = TrieDBBuilder::>::new(db, &root) - .with_recorder(&mut recorder) - .build(); - for key in &keys { - trie.get(key.as_ref()).map_err(|_| StorageProofError::UnavailableKey)?; - } - - let raw_read_proof: Vec<_> = recorder - .drain() - .into_iter() - .map(|n| n.data) - // recorder may record the same trie node multiple times and we don't want duplicate - // nodes in our proofs => let's deduplicate it by collecting to the BTreeSet first - .collect::>() - .into_iter() - .collect(); - - UnverifiedStorageProof::try_new::(StorageProof::new(raw_read_proof), root, keys) - } - - /// Validates the contained `db` against the contained proof. If the `db` is valid, converts it - /// into a `VerifiedStorageProof`. - pub fn verify( - mut self, - state_version: StateVersion, - state_root: &TrieHash>, - ) -> Result { - // First we verify the proof for the `UnverifiedStorageProof`. - // Note that `verify_trie_proof()` also checks for duplicate keys and unused nodes. - match state_version { - StateVersion::V0 => - verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), - StateVersion::V1 => - verify_trie_proof::, _, _, _>(state_root, &self.proof, &self.db), - } - .map_err(|e| { - log::warn!(target: "bridge-storage-proofs", "UnverifiedStorageProof::verify error: {e:?}"); - StorageProofError::InvalidProof - })?; - - // Fill the `VerifiedStorageProof` - let mut trusted_db = Vec::with_capacity(self.db.len()); - let mut iter = self.db.drain(..).peekable(); - while let Some((key, val)) = iter.next() { - // Let's also make sure that the db is actually sorted. - if let Some((next_key, _)) = iter.peek() { - if next_key <= &key { - return Err(StorageProofError::UnsortedEntries) - } - } - trusted_db.push((TrackedStorageKey::new(key), val)) - } - Ok(VerifiedStorageProof { db: trusted_db }) - } - - /// Getter for proof - pub fn proof(&self) -> &RawStorageProof { - &self.proof - } -} - -impl Size for UnverifiedStorageProof { - fn size(&self) -> u32 { - let proof_size = raw_storage_proof_size(&self.proof); - let entries_size = self.db.iter().fold(0usize, |sum, (key, value)| { - sum.saturating_add(key.len()) - .saturating_add(value.as_ref().unwrap_or(&vec![]).len()) - }); - - proof_size.saturating_add(entries_size).saturated_into() - } -} - -/// Structure representing a key-value database stored as a sorted `Vec` of tuples. -pub struct VerifiedStorageProof { - db: Vec<(TrackedStorageKey, Option)>, -} - -impl VerifiedStorageProof { - /// Returns a reference to the value corresponding to the key. - /// - /// Returns an error if the key doesn't exist. - pub fn get(&mut self, key: &impl AsRef<[u8]>) -> Result<&Option, StorageProofError> { - let idx = self - .db - .binary_search_by(|(db_key, _)| db_key.key.as_slice().cmp(key.as_ref())) - .map_err(|_| StorageProofError::UnavailableKey)?; - let (db_key, db_val) = self.db.get_mut(idx).ok_or(StorageProofError::UnavailableKey)?; - db_key.add_read(); - Ok(db_val) - } - - /// Returns a reference to the value corresponding to the key. - /// - /// Returns an error if the key doesn't exist or if the value associated to it is `None`. - pub fn get_and_decode_mandatory( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result { - let val = self.get(key)?.as_ref().ok_or(StorageProofError::EmptyVal)?; - D::decode(&mut &val[..]).map_err(|e| { - log::warn!(target: "bridge-storage-proofs", "get_and_decode_mandatory error: {e:?}"); - StorageProofError::DecodeError - }) - } - - /// Returns a reference to the value corresponding to the key. - /// - /// Returns `None` if the key doesn't exist or if the value associated to it is `None`. - pub fn get_and_decode_optional( - &mut self, - key: &impl AsRef<[u8]>, - ) -> Result, StorageProofError> { - match self.get_and_decode_mandatory(key) { - Ok(val) => Ok(Some(val)), - Err(StorageProofError::UnavailableKey | StorageProofError::EmptyVal) => Ok(None), - Err(e) => Err(e), - } - } - - /// Checks if each key was read. - pub fn ensure_no_unused_keys(&self) -> Result<(), StorageProofError> { - for (key, _) in &self.db { - if !key.has_been_read() { - return Err(StorageProofError::UnusedKey) - } - } - - Ok(()) - } -} - /// Storage values size requirements. /// /// This is currently used by benchmarks when generating storage proofs. @@ -333,87 +117,6 @@ impl UnverifiedStorageProofParams { } } -/// 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, params: &UnverifiedStorageProofParams) -> Vec { - 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( - trie: &mut TrieDBMut, - prefix: Vec, - 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( - db: &DB, - root: &TrieHash, -) -> Result>> -where - DB: hash_db::HashDBRef, -{ - let mut recorder = Recorder::::new(); - let trie = TrieDBBuilder::::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()) -} - /// This struct is used to read storage values from a subset of a Merklized database. The "proof" /// is a subset of the nodes in the Merkle structure of the database, so that it provides /// authentication against a known Merkle root as well as the values in the @@ -510,39 +213,120 @@ where } } +/// 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, params: &UnverifiedStorageProofParams) -> Vec { + 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( + trie: &mut TrieDBMut, + prefix: Vec, + 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( + db: &DB, + root: &TrieHash, +) -> Result>> +where + DB: hash_db::HashDBRef, +{ + let mut recorder = Recorder::::new(); + let trie = TrieDBBuilder::::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. +/// +/// NOTE: This should only be used for **testing**. +#[cfg(feature = "test-helpers")] +pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { + use sp_state_machine::{backend::Backend, prove_read, InMemoryBackend}; + + let state_version = sp_runtime::StateVersion::default(); + + // construct storage proof + let backend = >::from(( + 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()))]), + (None, vec![(b"key4".to_vec(), Some((42u64, 42u32, 42u16, 42u8).encode()))]), + // Value is too big to fit in a branch node + (None, vec![(b"key11".to_vec(), Some(vec![0u8; 32]))]), + ], + state_version, + )); + let root = backend.storage_root(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()) +} + #[cfg(test)] pub mod tests_for_storage_proof_checker { use super::*; use codec::Encode; - /// Return valid storage proof and state root. - /// - /// NOTE: This should only be used for **testing**. - #[cfg(feature = "std")] - pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { - use sp_state_machine::{backend::Backend, prove_read, InMemoryBackend}; - - let state_version = sp_runtime::StateVersion::default(); - - // construct storage proof - let backend = >::from(( - 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()))]), - (None, vec![(b"key4".to_vec(), Some((42u64, 42u32, 42u16, 42u8).encode()))]), - // Value is too big to fit in a branch node - (None, vec![(b"key11".to_vec(), Some(vec![0u8; 32]))]), - ], - state_version, - )); - let root = backend.storage_root(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()) - } - #[test] fn storage_proof_check() { let (root, proof) = craft_valid_storage_proof(); @@ -587,143 +371,3 @@ pub mod tests_for_storage_proof_checker { assert_eq!(checker.ensure_no_unused_nodes(), Err(StorageProofError::UnusedKey)); } } - -#[cfg(test)] -mod tests_for_unverified_storage_proof { - use super::*; - - type Hasher = sp_core::Blake2Hasher; - - #[test] - fn verify_succeeds_when_used_correctly() { - let (root, db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[(b"key1".to_vec(), None), (b"key2".to_vec(), Some(b"val2".to_vec()))], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - - assert!(db.verify::(StateVersion::V1, &root).is_ok()); - } - - #[test] - fn verify_fails_when_proof_contains_unneeded_nodes() { - let (root, mut db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[ - (b"key1".to_vec(), Some(b"val1".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - ], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - assert!(db.db.pop().is_some()); - - assert!(matches!( - db.verify::(StateVersion::V1, &root), - Err(StorageProofError::InvalidProof) - )); - } - - #[test] - fn verify_fails_when_db_contains_duplicate_nodes() { - let (root, mut db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[(b"key".to_vec(), None)], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - db.db.push((b"key".to_vec(), None)); - - assert!(matches!( - db.verify::(StateVersion::V1, &root), - Err(StorageProofError::InvalidProof) - )); - } - - #[test] - fn verify_fails_when_entries_are_not_sorted() { - let (root, mut db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[ - (b"key1".to_vec(), Some(b"val1".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - ], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - db.db.reverse(); - - assert!(matches!( - db.verify::(StateVersion::V1, &root), - Err(StorageProofError::UnsortedEntries) - )); - } - - #[test] - fn get_and_decode_mandatory_works() { - let (root, db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[ - (b"key11".to_vec(), Some(b"val11".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - (b"key1".to_vec(), None), - (b"key15".to_vec(), Some(b"val15".to_vec())), - ], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); - - assert!( - matches!(trusted_db.get_and_decode_mandatory::>(b"key11"), Ok(val) if val == b"val11".to_vec()) - ); - assert!( - matches!(trusted_db.get_and_decode_mandatory::>(b"key2"), Ok(val) if val == b"val2".to_vec()) - ); - assert!(matches!( - trusted_db.get_and_decode_mandatory::>(b"key1"), - Err(StorageProofError::EmptyVal) - )); - assert!(matches!( - trusted_db.get_and_decode_mandatory::>(b"key15"), - Err(StorageProofError::DecodeError) - )); - } - - #[test] - fn get_and_decode_optional_works() { - let (root, db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[ - (b"key11".to_vec(), Some(b"val11".to_vec().encode())), - (b"key2".to_vec(), Some(b"val2".to_vec().encode())), - (b"key1".to_vec(), None), - (b"key15".to_vec(), Some(b"val15".to_vec())), - ], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); - - assert!( - matches!(trusted_db.get_and_decode_optional::>(b"key11"), Ok(Some(val)) if val == - b"val11".to_vec()) - ); - assert!( - matches!(trusted_db.get_and_decode_optional::>(b"key2"), Ok(Some(val)) if val == b"val2".to_vec()) - ); - assert!(matches!(trusted_db.get_and_decode_optional::>(b"key1"), Ok(None))); - assert!(matches!( - trusted_db.get_and_decode_optional::>(b"key15"), - Err(StorageProofError::DecodeError) - )); - } - - #[test] - fn ensure_no_unused_keys_works_correctly() { - let (root, db) = UnverifiedStorageProof::try_from_entries::( - StateVersion::default(), - &[(b"key1".to_vec(), None), (b"key2".to_vec(), Some(b"val2".to_vec()))], - ) - .expect("UnverifiedStorageProof::try_from_entries() shouldn't fail in tests"); - let mut trusted_db = db.verify::(StateVersion::V1, &root).unwrap(); - assert!(trusted_db.get(b"key1").is_ok()); - - assert!(matches!(trusted_db.ensure_no_unused_keys(), Err(StorageProofError::UnusedKey))); - } -} From 94e977de9c440154b761422de491684db75dbcb1 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 11:34:11 +0200 Subject: [PATCH 30/58] Make bridges relayer storage-proof-type agnostic --- .../client-substrate/src/client/caching.rs | 9 ++++----- .../relays/client-substrate/src/client/rpc.rs | 17 ++++++++++------- .../client-substrate/src/client/traits.rs | 19 ++++--------------- .../lib-substrate-relay/src/messages/mod.rs | 4 ++-- .../src/messages/source.rs | 5 +++-- 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/bridges/relays/client-substrate/src/client/caching.rs b/bridges/relays/client-substrate/src/client/caching.rs index b57720befe6c..a574e5985bc8 100644 --- a/bridges/relays/client-substrate/src/client/caching.rs +++ b/bridges/relays/client-substrate/src/client/caching.rs @@ -31,7 +31,6 @@ use async_std::{ task::JoinHandle, }; use async_trait::async_trait; -use bp_runtime::UnverifiedStorageProof; use codec::Encode; use frame_support::weights::Weight; use futures::{FutureExt, StreamExt}; @@ -42,6 +41,7 @@ use sp_core::{ Bytes, Pair, }; use sp_runtime::{traits::Header as _, transaction_validity::TransactionValidity}; +use sp_trie::StorageProof; use sp_version::RuntimeVersion; /// `quick_cache::unsync::Cache` wrapped in async-aware synchronization primitives. @@ -462,12 +462,11 @@ impl> Client for CachingClient { .await } - async fn prove_storage_with_root( + async fn prove_storage( &self, at: HashOf, - state_root: HashOf, keys: Vec, - ) -> Result { - self.backend.prove_storage_with_root(at, state_root, keys).await + ) -> Result<(StorageProof, HashOf)> { + 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 1a0f2a4b3cc9..9c7f769462e5 100644 --- a/bridges/relays/client-substrate/src/client/rpc.rs +++ b/bridges/relays/client-substrate/src/client/rpc.rs @@ -37,7 +37,7 @@ use crate::{ use async_std::sync::{Arc, Mutex, RwLock}; use async_trait::async_trait; -use bp_runtime::{HasherOf, HeaderIdProvider, UnverifiedStorageProof}; +use bp_runtime::HeaderIdProvider; use codec::Encode; use frame_support::weights::Weight; use futures::TryFutureExt; @@ -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,12 +638,13 @@ impl Client for RpcClient { .map_err(|e| Error::failed_state_call::(at, method_clone, arguments_clone, e)) } - async fn prove_storage_with_root( + async fn prove_storage( &self, at: HashOf, - state_root: HashOf, keys: Vec, - ) -> Result { + ) -> Result<(StorageProof, HashOf)> { + let state_root = *self.header_by_hash(at).await?.state_root(); + let keys_clone = keys.clone(); let read_proof = self .jsonrpsee_execute(move |client| async move { @@ -652,8 +656,7 @@ impl Client for RpcClient { .await .map_err(|e| Error::failed_to_prove_storage::(at, keys.clone(), e))?; - UnverifiedStorageProof::try_new::>(read_proof, state_root, keys) - .map_err(|e| Error::Custom(format!("Error generating storage proof: {:?}", 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 7796c69b7805..6f4ef5aa9510 100644 --- a/bridges/relays/client-substrate/src/client/traits.rs +++ b/bridges/relays/client-substrate/src/client/traits.rs @@ -22,7 +22,7 @@ use crate::{ }; use async_trait::async_trait; -use bp_runtime::{StorageDoubleMapKeyProvider, StorageMapKeyProvider, UnverifiedStorageProof}; +use bp_runtime::{StorageDoubleMapKeyProvider, StorageMapKeyProvider}; use codec::{Decode, Encode}; use frame_support::weights::Weight; use sp_core::{ @@ -30,6 +30,7 @@ use sp_core::{ Bytes, Pair, }; use sp_runtime::{traits::Header as _, transaction_validity::TransactionValidity}; +use sp_trie::StorageProof; use sp_version::RuntimeVersion; use std::fmt::Debug; @@ -224,22 +225,10 @@ pub trait Client: 'static + Send + Sync + Clone + Debug { }) } - /// Returns storage proof of given storage keys. - async fn prove_storage_with_root( - &self, - at: HashOf, - state_root: HashOf, - keys: Vec, - ) -> Result; - - /// Returns storage proof of given storage keys. + /// Returns storage proof of given storage keys and state root. async fn prove_storage( &self, at: HashOf, keys: Vec, - ) -> Result { - let root = *self.header_by_hash(at).await?.state_root(); - - self.prove_storage_with_root(at, root, keys).await - } + ) -> Result<(StorageProof, HashOf)>; } diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index 05ba7247d6df..47bbf16bee76 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -643,7 +643,7 @@ where Weight::zero(), FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage: Default::default(), + storage_proof: Default::default(), lane: Default::default(), nonces_start: 1, nonces_end: messages as u64, @@ -705,7 +705,7 @@ mod tests { // data let receive_messages_proof = FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), - storage: Default::default(), + storage_proof: Default::default(), lane: LaneId([0, 0, 0, 0]), nonces_start: 0, nonces_end: 0, diff --git a/bridges/relays/lib-substrate-relay/src/messages/source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs index 8f0e1b54460c..3868fe62fc57 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -336,10 +336,11 @@ where )); } - let storage = self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; + let storage_proof = + self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesProof { bridged_header_hash: id.1, - storage, + storage_proof, lane: self.lane_id, nonces_start: *nonces.start(), nonces_end: *nonces.end(), From 19f4011ff473c547c758833f25668017d0b9abcb Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 12:30:00 +0200 Subject: [PATCH 31/58] Make bridges relayer storage-proof-type agnostic part 2 --- Cargo.lock | 1 + bridges/modules/parachains/src/lib.rs | 4 +++- bridges/relays/lib-substrate-relay/Cargo.toml | 1 + bridges/relays/lib-substrate-relay/src/lib.rs | 14 ++++++++++++++ .../lib-substrate-relay/src/messages/source.rs | 3 ++- .../lib-substrate-relay/src/messages/target.rs | 3 ++- .../lib-substrate-relay/src/parachains/source.rs | 13 ++++++++++--- 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfe12074ff1e..7e294ec12e33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21441,6 +21441,7 @@ dependencies = [ "sp-consensus-grandpa", "sp-core", "sp-runtime", + "sp-trie", "structopt", "strum 0.26.2", "thiserror", diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index 269d587d9c8b..e2c30ce9aecc 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -29,7 +29,7 @@ pub use weights_ext::WeightInfoExt; use bp_header_chain::{HeaderChain, HeaderChainError}; use bp_parachains::{ParaInfo, ParaStoredHeaderData}; -use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId}; +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; @@ -792,6 +792,7 @@ impl, I: 'static, C: Parachain> HeaderChain pub fn initialize_for_benchmarks, I: 'static, PC: Parachain>( header: HeaderOf, ) { + use bp_polkadot_core::parachains::ParaHead; use bp_runtime::HeaderIdProvider; use sp_runtime::traits::Header; @@ -835,6 +836,7 @@ pub(crate) mod tests { use bp_parachains::{ BestParaHeadHash, BridgeParachainCall, ImportedParaHeadsKeyProvider, ParasInfoKeyProvider, }; + use bp_polkadot_core::parachains::ParaHead; use bp_runtime::{ BasicOperatingMode, OwnedBridgeModuleError, StorageDoubleMapKeyProvider, StorageMapKeyProvider, StorageProofError, diff --git a/bridges/relays/lib-substrate-relay/Cargo.toml b/bridges/relays/lib-substrate-relay/Cargo.toml index 85b6fb0e50bf..b0f93e5b5485 100644 --- a/bridges/relays/lib-substrate-relay/Cargo.toml +++ b/bridges/relays/lib-substrate-relay/Cargo.toml @@ -52,6 +52,7 @@ 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 } diff --git a/bridges/relays/lib-substrate-relay/src/lib.rs b/bridges/relays/lib-substrate-relay/src/lib.rs index 002a58a66fe7..c004540a9f49 100644 --- a/bridges/relays/lib-substrate-relay/src/lib.rs +++ b/bridges/relays/lib-substrate-relay/src/lib.rs @@ -127,3 +127,17 @@ impl BatchCallBuilder 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( + proof: (StorageProof, HashOf), + ) -> RawStorageProof { + proof.0.into_iter_nodes().collect() + } +} diff --git a/bridges/relays/lib-substrate-relay/src/messages/source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs index 3868fe62fc57..b75fc86d5eee 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -25,6 +25,7 @@ use crate::{ SubstrateMessageLane, }, on_demand::OnDemandRelay, + proofs::to_raw_storage_proof, TransactionParams, }; @@ -340,7 +341,7 @@ where self.source_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesProof { bridged_header_hash: id.1, - storage_proof, + storage_proof: to_raw_storage_proof::(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 index 6a137bda46ee..a6bf169cffb6 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/target.rs @@ -28,6 +28,7 @@ use crate::{ SubstrateMessageLane, }, on_demand::OnDemandRelay, + proofs::to_raw_storage_proof, TransactionParams, }; @@ -240,7 +241,7 @@ where self.target_client.prove_storage(id.hash(), storage_keys.clone()).await?; let proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: id.1, - storage_proof, + storage_proof: to_raw_storage_proof::(storage_proof), lane: self.lane_id, }; Ok((id, (relayers_state, proof))) diff --git a/bridges/relays/lib-substrate-relay/src/parachains/source.rs b/bridges/relays/lib-substrate-relay/src/parachains/source.rs index 4ee41c45fafa..1aa12d1c913d 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; @@ -175,6 +177,11 @@ where })?; let parachain_head_hash = parachain_head.hash(); - Ok((ParaHeadsProof { storage_proof }, parachain_head_hash)) + Ok(( + ParaHeadsProof { + storage_proof: to_raw_storage_proof::(storage_proof), + }, + parachain_head_hash, + )) } } From a367b4962883b84f0b3ab9e41b3a6027b00b353d Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 13:27:03 +0200 Subject: [PATCH 32/58] Revert: `prune messages from confirmation tx, not from the on_idle (#2211)` --- Cargo.lock | 1 - bridges/modules/messages/Cargo.toml | 2 - bridges/modules/messages/src/lib.rs | 35 +++++ bridges/modules/messages/src/outbound_lane.rs | 106 +++++++++++++-- .../messages/src/tests/pallet_tests.rs | 124 ++++++++++++++++++ 5 files changed, 252 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e294ec12e33..8811c729a48e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10121,7 +10121,6 @@ dependencies = [ "frame-support", "frame-system", "log", - "num-traits", "pallet-balances", "pallet-bridge-grandpa", "parity-scale-codec", diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index e007676fdd1e..33f524030d26 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] codec = { workspace = true } log = { workspace = true } -num-traits = { workspace = true } scale-info = { features = ["derive"], workspace = true } # Bridge dependencies @@ -49,7 +48,6 @@ std = [ "frame-support/std", "frame-system/std", "log/std", - "num-traits/std", "pallet-balances/std", "pallet-bridge-grandpa/std", "scale-info/std", diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index b3c56cfd858b..e5edf2bfecfe 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -70,6 +70,7 @@ use bp_runtime::{ }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound}; +use sp_runtime::traits::UniqueSaturatedFrom; use sp_std::{marker::PhantomData, prelude::*}; mod inbound_lane; @@ -152,6 +153,40 @@ pub mod pallet { type OperatingModeStorage = PalletOperatingMode; } + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet + where + u32: TryFrom>, + { + fn on_idle(_block: BlockNumberFor, remaining_weight: Weight) -> Weight { + // we'll need at least to read outbound lane state, kill a message and update lane state + let db_weight = T::DbWeight::get(); + if !remaining_weight.all_gte(db_weight.reads_writes(1, 2)) { + return Weight::zero() + } + + // messages from lane with index `i` in `ActiveOutboundLanes` are pruned when + // `System::block_number() % lanes.len() == i`. Otherwise we need to read lane states on + // every block, wasting the whole `remaining_weight` for nothing and causing starvation + // of the last lane pruning + let active_lanes = T::ActiveOutboundLanes::get(); + let active_lanes_len = (active_lanes.len() as u32).into(); + let active_lane_index = u32::unique_saturated_from( + frame_system::Pallet::::block_number() % active_lanes_len, + ); + let active_lane_id = active_lanes[active_lane_index as usize]; + + // first db read - outbound lane state + let mut active_lane = outbound_lane::(active_lane_id); + let mut used_weight = db_weight.reads(1); + // and here we'll have writes + used_weight += active_lane.prune_messages(db_weight, remaining_weight - used_weight); + + // we already checked we have enough `remaining_weight` to cover this `used_weight` + used_weight + } + } + #[pallet::call] impl, I: 'static> Pallet { /// Change `PalletOwner`. diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index 788a13e82b1b..fcdddf199dc6 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -22,9 +22,13 @@ use bp_messages::{ ChainWithMessages, DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, }; use codec::{Decode, Encode}; -use frame_support::{traits::Get, BoundedVec, PalletError}; +use frame_support::{ + traits::Get, + weights::{RuntimeDbWeight, Weight}, + BoundedVec, PalletError, +}; use scale_info::TypeInfo; -use sp_runtime::RuntimeDebug; +use sp_runtime::{traits::Zero, RuntimeDebug}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData}; /// Outbound lane storage. @@ -139,17 +143,41 @@ impl OutboundLane { ensure_unrewarded_relayers_are_correct(confirmed_messages.end, relayers)?; - // prune all confirmed messages - for nonce in confirmed_messages.begin..=confirmed_messages.end { - self.storage.remove_message(&nonce); - } - data.latest_received_nonce = confirmed_messages.end; - data.oldest_unpruned_nonce = data.latest_received_nonce.saturating_add(1); self.storage.set_data(data); Ok(Some(confirmed_messages)) } + + /// Prune at most `max_messages_to_prune` already received messages. + /// + /// Returns weight, consumed by messages pruning and lane state update. + pub fn prune_messages( + &mut self, + db_weight: RuntimeDbWeight, + mut remaining_weight: Weight, + ) -> Weight { + let write_weight = db_weight.writes(1); + let two_writes_weight = write_weight + write_weight; + let mut spent_weight = Weight::zero(); + let mut data = self.storage.data(); + while remaining_weight.all_gte(two_writes_weight) && + data.oldest_unpruned_nonce <= data.latest_received_nonce + { + self.storage.remove_message(&data.oldest_unpruned_nonce); + + spent_weight += write_weight; + remaining_weight -= write_weight; + data.oldest_unpruned_nonce += 1; + } + + if !spent_weight.is_zero() { + spent_weight += write_weight; + self.storage.set_data(data); + } + + spent_weight + } } /// Verifies unrewarded relayers vec. @@ -193,6 +221,7 @@ mod tests { REGULAR_PAYLOAD, TEST_LANE_ID, }, }; + use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; fn unrewarded_relayers( @@ -252,7 +281,7 @@ mod tests { ); 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, 4); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -273,7 +302,7 @@ mod tests { ); 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, 3); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); assert_eq!( lane.confirm_delivery(3, 3, &unrewarded_relayers(3..=3)), @@ -281,7 +310,7 @@ mod tests { ); 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, 4); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -302,12 +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, 4); + 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, 4); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -365,6 +394,57 @@ mod tests { ); } + #[test] + fn prune_messages_works() { + run_test(|| { + let mut lane = outbound_lane::(TEST_LANE_ID); + // when lane is empty, nothing is pruned + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + Weight::zero() + ); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + // when nothing is confirmed, nothing is pruned + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + assert!(lane.storage.message(&1).is_some()); + assert!(lane.storage.message(&2).is_some()); + assert!(lane.storage.message(&3).is_some()); + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + Weight::zero() + ); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + // after confirmation, some messages are received + assert_eq!( + lane.confirm_delivery(2, 2, &unrewarded_relayers(1..=2)), + Ok(Some(delivered_messages(1..=2))), + ); + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + RocksDbWeight::get().writes(3), + ); + assert!(lane.storage.message(&1).is_none()); + assert!(lane.storage.message(&2).is_none()); + assert!(lane.storage.message(&3).is_some()); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 3); + // after last message is confirmed, everything is pruned + assert_eq!( + lane.confirm_delivery(1, 3, &unrewarded_relayers(3..=3)), + Ok(Some(delivered_messages(3..=3))), + ); + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + RocksDbWeight::get().writes(2), + ); + assert!(lane.storage.message(&1).is_none()); + assert!(lane.storage.message(&2).is_none()); + assert!(lane.storage.message(&3).is_none()); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4); + }); + } + #[test] fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index b2f7bb1c4a65..f8a52f32b694 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -41,6 +41,7 @@ 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}; @@ -833,6 +834,129 @@ fn inbound_message_details_works() { }); } +#[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::::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::(TEST_LANE_ID).data().latest_received_nonce, 4); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + System::::set_block_number(2); + + // if passed wight is too low to do anything + let dbw = DbWeight::get(); + assert_eq!(Pallet::::on_idle(0, dbw.reads_writes(1, 1)), Weight::zero(),); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + + // if passed wight is enough to prune single message + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(1, 2)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + + // if passed wight is enough to prune two more messages + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(1, 3)), + dbw.reads_writes(1, 3), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 4); + + // if passed wight is enough to prune many messages + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, 1); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, + 1 + ); + assert_eq!( + outbound_lane::(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::::set_block_number(2); + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 1 + ); + + // in block#3.on_idle lane messages of lane 2 are pruned + System::::set_block_number(3); + + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 2 + ); + }); +} + #[test] fn outbound_message_from_unconfigured_lane_is_rejected() { run_test(|| { From 6dbbb48e82202a95acef67e90168c8d3fd7ad2fb Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 13:38:21 +0200 Subject: [PATCH 33/58] Fixes --- .../bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs | 2 +- .../bridge-hubs/test-utils/src/test_data/from_parachain.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 36206a6738d3..c61a31e5454b 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 @@ -196,7 +196,7 @@ where let message_proof = FromBridgedChainMessagesProof { bridged_header_hash: header.hash(), - storage: storage_proof, + storage_proof, lane: lane_id, nonces_start: message_nonce, nonces_end: message_nonce, 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 435f5adb038b..897fe0d0b0f1 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 @@ -246,7 +246,7 @@ where let message_proof = FromBridgedChainMessagesProof { bridged_header_hash: bridged_para_head.hash(), - storage: para_storage_proof, + storage_proof: para_storage_proof, lane: lane_id, nonces_start: message_nonce, nonces_end: message_nonce, From 3a149d9c47380680f17328d780ffc8cff4277127 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 14:39:56 +0200 Subject: [PATCH 34/58] nits --- bridges/modules/messages/src/lib.rs | 276 ------------------ bridges/modules/messages/src/proofs.rs | 2 + .../messages/src/tests/pallet_tests.rs | 20 +- bridges/primitives/runtime/src/lib.rs | 1 - .../primitives/runtime/src/storage_proof.rs | 14 - prdoc/pr_4935.prdoc | 27 ++ 6 files changed, 48 insertions(+), 292 deletions(-) create mode 100644 prdoc/pr_4935.prdoc diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index e5edf2bfecfe..bf105b140401 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -507,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. @@ -864,277 +862,3 @@ fn verify_and_decode_messages_proof, I: 'static>( .collect() }) } - -// #[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::::validate_message( -// TEST_LANE_ID, -// &PAYLOAD_REJECTED_BY_TARGET_CHAIN, -// ), -// Error::::MessageRejectedByChainVerifier(VerificationError::Other( -// mock::TEST_ERROR -// )), -// ); -// }); -// } -// -// #[test] -// fn receive_messages_fails_if_dispatcher_is_inactive() { -// run_test(|| { -// TestMessageDispatch::deactivate(); -// assert_noop!( -// Pallet::::receive_messages_proof( -// RuntimeOrigin::signed(1), -// TEST_RELAYER_A, -// Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), -// 1, -// REGULAR_PAYLOAD.declared_weight, -// ), -// Error::::MessageDispatchInactive, -// ); -// }); -// } -// -// #[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::::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::::InsufficientDispatchWeight -// ); -// assert_eq!(InboundLanes::::get(TEST_LANE_ID).last_delivered_nonce(), 0); -// }); -// } -// -// #[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::::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::::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 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::::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::(TEST_LANE_ID).data().latest_received_nonce, -// 4 -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 1 -// ); -// System::::set_block_number(2); -// -// // if passed wight is too low to do anything -// let dbw = DbWeight::get(); -// assert_eq!( -// Pallet::::on_idle(0, dbw.reads_writes(1, 1)), -// Weight::zero(), -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 1 -// ); -// -// // if passed wight is enough to prune single message -// assert_eq!( -// Pallet::::on_idle(0, dbw.reads_writes(1, 2)), -// dbw.reads_writes(1, 2), -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 2 -// ); -// -// // if passed wight is enough to prune two more messages -// assert_eq!( -// Pallet::::on_idle(0, dbw.reads_writes(1, 3)), -// dbw.reads_writes(1, 3), -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 4 -// ); -// -// // if passed wight is enough to prune many messages -// assert_eq!( -// Pallet::::on_idle(0, dbw.reads_writes(100, 100)), -// dbw.reads_writes(1, 2), -// ); -// assert_eq!( -// outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, -// 1 -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 1 -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, -// 1 -// ); -// assert_eq!( -// outbound_lane::(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::::set_block_number(2); -// assert_eq!( -// Pallet::::on_idle(0, dbw.reads_writes(100, 100)), -// dbw.reads_writes(1, 2), -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 2 -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, -// 1 -// ); -// -// // in block#3.on_idle lane messages of lane 2 are pruned -// System::::set_block_number(3); -// -// assert_eq!( -// Pallet::::on_idle(0, dbw.reads_writes(100, 100)), -// dbw.reads_writes(1, 2), -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, -// 2 -// ); -// assert_eq!( -// outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, -// 2 -// ); -// }); -// } diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index f5d421925d97..9b5c15fb1929 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -132,6 +132,8 @@ pub fn verify_messages_delivery_proof, I: 'static>( Ok((lane, inbound_lane_data)) } +/// Abstraction over storage proof manipulation, hiding implementation details of actual storage +/// proofs. trait StorageProofAdapter, I: 'static> { fn read_and_decode_mandatory_value( &mut self, diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index f8a52f32b694..42e1042717de 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -163,6 +163,24 @@ fn pallet_rejects_transactions_if_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::::receive_messages_proof( + RuntimeOrigin::signed(1), + TEST_RELAYER_A, + proof, + 1, + REGULAR_PAYLOAD.declared_weight, + ), + Error::::MessageDispatchInactive, + ); + }); +} + #[test] fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { run_test(|| { @@ -609,7 +627,7 @@ fn receive_messages_accepts_batch_with_message_with_invalid_payload() { } #[test] -fn actual_dispatch_weight_does_not_overlow() { +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)); diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 425dd32f8ff3..efa8e659b368 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -47,7 +47,6 @@ pub use storage_proof::{ }; pub use storage_proof::{ raw_storage_proof_size, RawStorageProof, StorageProofChecker, StorageProofError, - StorageProofRequest, StorageProofResult, }; pub use storage_types::BoundedStorageValue; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 27cee2ddca5c..644ac64431e9 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -75,20 +75,6 @@ impl From for StorageProofError { } } -/// For backwards compatibility (relaying), we need to support several proof types. -/// This enum contains all supported storage proof types. -pub enum StorageProofResult { - /// Raw proofs - Raw(RawStorageProof), -} - -/// For backwards compatibility (relaying), we need to support several proof types. -/// This enum contains all supported storage proof types which we can request. -pub enum StorageProofRequest { - /// Raw proofs - Raw, -} - /// Raw storage proof type (just raw trie nodes). pub type RawStorageProof = sp_trie::RawStorageProof; diff --git a/prdoc/pr_4935.prdoc b/prdoc/pr_4935.prdoc new file mode 100644 index 000000000000..b6e46ebab6ca --- /dev/null +++ b/prdoc/pr_4935.prdoc @@ -0,0 +1,27 @@ +# 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 From e4a1c5b71868b0f06167a06c06ff1dd57a2c0eb8 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 15:16:00 +0200 Subject: [PATCH 35/58] CI fixes --- bridges/primitives/runtime/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bridges/primitives/runtime/Cargo.toml b/bridges/primitives/runtime/Cargo.toml index 117409b37b94..034e6c12610d 100644 --- a/bridges/primitives/runtime/Cargo.toml +++ b/bridges/primitives/runtime/Cargo.toml @@ -26,7 +26,7 @@ frame-system = { workspace = true } sp-core = { workspace = true } sp-io = { workspace = true } sp-runtime = { features = ["serde"], workspace = true } -sp-state-machine = { workspace = true } +sp-state-machine = { optional = true, workspace = true } sp-std = { workspace = true } sp-trie = { workspace = true } trie-db = { workspace = true } @@ -48,9 +48,9 @@ std = [ "sp-core/std", "sp-io/std", "sp-runtime/std", - "sp-state-machine/std", + "sp-state-machine?/std", "sp-std/std", "sp-trie/std", "trie-db/std", ] -test-helpers = [] +test-helpers = ["sp-state-machine"] From abd140f64c8198a6a154e68a0018d4eb29ec37b8 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 16:10:36 +0200 Subject: [PATCH 36/58] more nits --- bridges/primitives/runtime/Cargo.toml | 6 +++--- bridges/primitives/runtime/src/lib.rs | 4 +++- bridges/primitives/runtime/src/storage_proof.rs | 8 ++++---- prdoc/pr_4935.prdoc | 14 +++++++------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/bridges/primitives/runtime/Cargo.toml b/bridges/primitives/runtime/Cargo.toml index 034e6c12610d..117409b37b94 100644 --- a/bridges/primitives/runtime/Cargo.toml +++ b/bridges/primitives/runtime/Cargo.toml @@ -26,7 +26,7 @@ frame-system = { workspace = true } sp-core = { workspace = true } sp-io = { workspace = true } sp-runtime = { features = ["serde"], workspace = true } -sp-state-machine = { optional = true, workspace = true } +sp-state-machine = { workspace = true } sp-std = { workspace = true } sp-trie = { workspace = true } trie-db = { workspace = true } @@ -48,9 +48,9 @@ std = [ "sp-core/std", "sp-io/std", "sp-runtime/std", - "sp-state-machine?/std", + "sp-state-machine/std", "sp-std/std", "sp-trie/std", "trie-db/std", ] -test-helpers = ["sp-state-machine"] +test-helpers = [] diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index efa8e659b368..fcdd01238420 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -42,9 +42,11 @@ pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; #[cfg(feature = "test-helpers")] pub use storage_proof::{ - craft_valid_storage_proof, grow_storage_proof, grow_storage_value, + grow_storage_proof, grow_storage_value, record_all_keys as record_all_trie_keys, UnverifiedStorageProofParams, }; +#[cfg(feature = "std")] +pub use storage_proof::craft_valid_storage_proof; pub use storage_proof::{ raw_storage_proof_size, RawStorageProof, StorageProofChecker, StorageProofError, }; diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index 644ac64431e9..ec48d65f6b99 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -266,7 +266,7 @@ pub fn grow_storage_proof( pub fn record_all_keys( db: &DB, root: &TrieHash, -) -> Result>> +) -> Result>> where DB: hash_db::HashDBRef, { @@ -283,7 +283,7 @@ where /// Return valid storage proof and state root. /// /// NOTE: This should only be used for **testing**. -#[cfg(feature = "test-helpers")] +#[cfg(feature = "std")] pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { use sp_state_machine::{backend::Backend, prove_read, InMemoryBackend}; @@ -291,7 +291,7 @@ pub fn craft_valid_storage_proof() -> (sp_core::H256, RawStorageProof) { // construct storage proof let backend = >::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()))]), @@ -301,7 +301,7 @@ 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(); diff --git a/prdoc/pr_4935.prdoc b/prdoc/pr_4935.prdoc index b6e46ebab6ca..6e3e17ad9006 100644 --- a/prdoc/pr_4935.prdoc +++ b/prdoc/pr_4935.prdoc @@ -13,13 +13,13 @@ doc: 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, - >; + 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: From 685bcb4053bffdbeed9457fe811432977a9d2262 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 16:12:59 +0200 Subject: [PATCH 37/58] fmt --- bridges/primitives/runtime/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index fcdd01238420..8f5040ad9a1b 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -40,13 +40,13 @@ 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::{ - grow_storage_proof, grow_storage_value, - record_all_keys as record_all_trie_keys, UnverifiedStorageProofParams, + grow_storage_proof, grow_storage_value, record_all_keys as record_all_trie_keys, + UnverifiedStorageProofParams, }; -#[cfg(feature = "std")] -pub use storage_proof::craft_valid_storage_proof; pub use storage_proof::{ raw_storage_proof_size, RawStorageProof, StorageProofChecker, StorageProofError, }; From 2a3d5cc80eafe1af84fcb96e73aea242250be2cc Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:46:32 +0000 Subject: [PATCH 38/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_parachains --- .../src/weights/pallet_bridge_parachains.rs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) 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 f622d58fcad3..b4748f141705 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -61,15 +61,13 @@ impl 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: 33_552_000 picoseconds. - Weight::from_parts(34_528_551, 0) + // Minimum execution time: 34_177_000 picoseconds. + Weight::from_parts(35_662_308, 0) .saturating_add(Weight::from_parts(0, 2543)) - // Standard Error: 78_732 - .saturating_add(Weight::from_parts(86_524, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -89,8 +87,8 @@ impl pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `315` // Estimated: `2543` - // Minimum execution time: 34_697_000 picoseconds. - Weight::from_parts(35_201_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 pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `315` // Estimated: `2543` - // Minimum execution time: 54_661_000 picoseconds. - Weight::from_parts(55_900_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)) From 39a5340580eccef09b380bcff5b47f159a122c00 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:47:45 +0000 Subject: [PATCH 39/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_relayers --- .../src/weights/pallet_bridge_relayers.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 a124b9276d05..f8bb983e80aa 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -56,8 +56,8 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `278` // Estimated: `3593` - // Minimum execution time: 43_851_000 picoseconds. - Weight::from_parts(44_697_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `131` // Estimated: `4714` - // Minimum execution time: 24_013_000 picoseconds. - Weight::from_parts(24_625_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `231` // Estimated: `4714` - // Minimum execution time: 24_632_000 picoseconds. - Weight::from_parts(25_010_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `334` // Estimated: `4714` - // Minimum execution time: 27_022_000 picoseconds. - Weight::from_parts(27_581_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `76` // Estimated: `3538` - // Minimum execution time: 5_269_000 picoseconds. - Weight::from_parts(5_428_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)) From dcb550f8294e3e7738ef586bf688b36dee445ad9 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:47:50 +0000 Subject: [PATCH 40/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=xcm --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_benchmarks::generic --- .../xcm/pallet_xcm_benchmarks_generic.rs | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) 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 abd84f8e89b0..bafc973bdac4 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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) } } From 45155b3b9bb7f627e058b1882cc906c28515483a Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:48:06 +0000 Subject: [PATCH 41/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_grandpa --- .../src/weights/pallet_bridge_grandpa.rs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) 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 a8722256fe6d..3073705b2df8 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-20, 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-1pho9goo-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: @@ -64,17 +64,15 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo Weight { + fn submit_finality_proof(p: u32, _v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `438 + p * (60 ±0)` // Estimated: `51735` - // Minimum execution time: 295_891_000 picoseconds. - Weight::from_parts(14_601_194, 0) + // Minimum execution time: 301_982_000 picoseconds. + Weight::from_parts(356_093_000, 0) .saturating_add(Weight::from_parts(0, 51735)) - // Standard Error: 17_801 - .saturating_add(Weight::from_parts(40_844_924, 0).saturating_mul(p.into())) - // Standard Error: 59_401 - .saturating_add(Weight::from_parts(2_533_202, 0).saturating_mul(v.into())) + // Standard Error: 24_378 + .saturating_add(Weight::from_parts(50_293_143, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -92,8 +90,8 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo Date: Wed, 3 Jul 2024 15:48:32 +0000 Subject: [PATCH 42/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_relayers --- .../src/weights/pallet_bridge_relayers.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 f8adb3894d5c..60d81dc3082a 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_relayers` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -56,8 +56,8 @@ impl pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `207` // Estimated: `3593` - // Minimum execution time: 43_407_000 picoseconds. - Weight::from_parts(44_596_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `61` // Estimated: `4714` - // Minimum execution time: 23_882_000 picoseconds. - Weight::from_parts(24_750_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `160` // Estimated: `4714` - // Minimum execution time: 23_983_000 picoseconds. - Weight::from_parts(24_806_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `263` // Estimated: `4714` - // Minimum execution time: 26_502_000 picoseconds. - Weight::from_parts(27_054_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 pallet_bridge_relayers::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `6` // Estimated: `3538` - // Minimum execution time: 4_700_000 picoseconds. - Weight::from_parts(4_970_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)) From 27dfe41b8ec8d56f36376912e84484270ba0b6c0 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:48:48 +0000 Subject: [PATCH 43/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_parachains --- .../src/weights/pallet_bridge_parachains.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) 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 2a1ea2fed7de..8eb291ea1452 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_parachains` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -61,13 +61,15 @@ impl 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: 34_672_000 picoseconds. - Weight::from_parts(35_987_371, 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 pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `558` // Estimated: `2543` - // Minimum execution time: 35_961_000 picoseconds. - Weight::from_parts(36_377_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 pallet_bridge_parachains::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `558` // Estimated: `2543` - // Minimum execution time: 57_145_000 picoseconds. - Weight::from_parts(58_253_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)) From 25ed0da0b457d0a06b13f9c885184c12f2211b8a Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:49:40 +0000 Subject: [PATCH 44/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- .../src/weights/pallet_bridge_messages.rs | 60 +++++++++---------- 1 file changed, 27 insertions(+), 33 deletions(-) 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 f44c1e773f81..386342d7ea5d 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -62,8 +62,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_418_000 picoseconds. - Weight::from_parts(41_449_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)) @@ -83,11 +83,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 39_405_000 picoseconds. - Weight::from_parts(40_283_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: 11_499 - .saturating_add(Weight::from_parts(9_545_249, 0).saturating_mul(n.into())) + // 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)) } @@ -105,8 +105,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 47_084_000 picoseconds. - Weight::from_parts(48_546_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)) @@ -126,11 +126,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 39_239_000 picoseconds. - Weight::from_parts(41_253_759, 0) + // Minimum execution time: 39_668_000 picoseconds. + Weight::from_parts(41_908_980, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 10 - .saturating_add(Weight::from_parts(1_821, 0).saturating_mul(n.into())) + // 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)) } @@ -144,17 +144,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 31_397_000 picoseconds. - Weight::from_parts(32_157_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(3)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -166,17 +164,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 32_831_000 picoseconds. - Weight::from_parts(33_908_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(4)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -188,17 +184,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `6086` - // Minimum execution time: 36_861_000 picoseconds. - Weight::from_parts(38_046_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(5)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -227,11 +221,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `653` // Estimated: `52645` - // Minimum execution time: 56_947_000 picoseconds. - Weight::from_parts(61_470_671, 0) + // Minimum execution time: 56_465_000 picoseconds. + Weight::from_parts(61_575_775, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 16 - .saturating_add(Weight::from_parts(6_899, 0).saturating_mul(n.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)) } From 387e624e93bef84674bcc5ba93e6e0880e0c0698 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:50:03 +0000 Subject: [PATCH 45/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=xcm --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_benchmarks::generic --- .../xcm/pallet_xcm_benchmarks_generic.rs | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) 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 9281a880c7e1..73bea66bf710 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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 WeightInfo { // 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) } } From e2635b5d001bbb5ed7fa03b1acd593a59c9f8c55 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 15:52:50 +0000 Subject: [PATCH 46/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_grandpa --- .../src/weights/pallet_bridge_grandpa.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 d434d274dafe..55d1664e17fa 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-20, 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-1pho9goo-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,13 +68,13 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo pallet_bridge_grandpa::WeightInfo for WeightInfo Date: Wed, 3 Jul 2024 15:54:32 +0000 Subject: [PATCH 47/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- ...idge_messages_rococo_to_rococo_bulletin.rs | 60 +++++++++---------- ...allet_bridge_messages_rococo_to_westend.rs | 58 ++++++++---------- 2 files changed, 53 insertions(+), 65 deletions(-) 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 380a189755c9..5522a325f192 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -60,8 +60,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 35_316_000 picoseconds. - Weight::from_parts(36_290_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)) @@ -80,11 +80,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 34_874_000 picoseconds. - Weight::from_parts(35_741_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: 1_562 - .saturating_add(Weight::from_parts(9_285_039, 0).saturating_mul(n.into())) + // 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)) } @@ -100,8 +100,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 42_487_000 picoseconds. - Weight::from_parts(43_343_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)) @@ -120,11 +120,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 34_349_000 picoseconds. - Weight::from_parts(35_630_173, 0) + // Minimum execution time: 35_055_000 picoseconds. + Weight::from_parts(36_987_740, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 3 - .saturating_add(Weight::from_parts(1_976, 0).saturating_mul(n.into())) + // 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)) } @@ -134,17 +134,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_229_000 picoseconds. - Weight::from_parts(26_207_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(2)) + .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`) @@ -152,17 +150,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 26_529_000 picoseconds. - Weight::from_parts(27_121_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(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`) @@ -170,17 +166,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 26_455_000 picoseconds. - Weight::from_parts(27_212_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(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`) @@ -210,11 +204,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `813` // Estimated: `52645` - // Minimum execution time: 53_750_000 picoseconds. - Weight::from_parts(57_441_963, 0) + // Minimum execution time: 54_317_000 picoseconds. + Weight::from_parts(59_171_547, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 8 - .saturating_add(Weight::from_parts(7_382, 0).saturating_mul(n.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 14f63ffa4ccd..9c05dae979da 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,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, 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-1pho9goo-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: @@ -62,8 +62,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 39_554_000 picoseconds. - Weight::from_parts(40_983_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)) @@ -84,11 +84,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 39_524_000 picoseconds. - Weight::from_parts(40_155_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: 1_579 - .saturating_add(Weight::from_parts(9_365_386, 0).saturating_mul(n.into())) + // 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)) } @@ -106,8 +106,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 46_662_000 picoseconds. - Weight::from_parts(48_755_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)) @@ -128,11 +128,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 38_412_000 picoseconds. - Weight::from_parts(40_736_865, 0) + // Minimum execution time: 39_175_000 picoseconds. + Weight::from_parts(41_674_095, 0) .saturating_add(Weight::from_parts(0, 52645)) // Standard Error: 4 - .saturating_add(Weight::from_parts(1_957, 0).saturating_mul(n.into())) + .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)) } @@ -146,17 +146,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 32_617_000 picoseconds. - Weight::from_parts(33_386_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(3)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -168,17 +166,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 33_877_000 picoseconds. - Weight::from_parts(34_970_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(4)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -190,17 +186,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `6086` - // Minimum execution time: 37_891_000 picoseconds. - Weight::from_parts(39_192_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(5)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -230,11 +224,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `789` // Estimated: `52645` - // Minimum execution time: 56_038_000 picoseconds. - Weight::from_parts(60_365_671, 0) + // Minimum execution time: 56_562_000 picoseconds. + Weight::from_parts(61_452_871, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 10 - .saturating_add(Weight::from_parts(7_383, 0).saturating_mul(n.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)) } From 6047fa93ccd18c55b8e763b377d5dcc59e3daa03 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 17:07:00 +0000 Subject: [PATCH 48/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=asset-hub-rococo --runtime_dir=assets --target_dir=cumulus --pallet=pallet_xcm_bridge_hub_router --- .../weights/pallet_xcm_bridge_hub_router.rs | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) 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 775bc3bdb80f..0a86037391b4 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(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { /// 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 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 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 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)) From 32d745562c97b27fa089d569a0c58bc46d72517c Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 3 Jul 2024 17:07:12 +0000 Subject: [PATCH 49/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=asset-hub-westend --runtime_dir=assets --target_dir=cumulus --pallet=pallet_xcm_bridge_hub_router --- .../weights/pallet_xcm_bridge_hub_router.rs | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) 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 84d717b0283c..21d15c75af55 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(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { /// 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 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 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)) } From 233fb44ebb736f009e640fbd0abe63c891cf791c Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 22:51:35 +0200 Subject: [PATCH 50/58] make check-crates job happy + prdoc nits --- .../primitives/runtime/src/storage_proof.rs | 8 ++-- prdoc/pr_4935.prdoc | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/bridges/primitives/runtime/src/storage_proof.rs b/bridges/primitives/runtime/src/storage_proof.rs index ec48d65f6b99..7bfa0d6fde01 100644 --- a/bridges/primitives/runtime/src/storage_proof.rs +++ b/bridges/primitives/runtime/src/storage_proof.rs @@ -20,18 +20,16 @@ use frame_support::PalletError; use sp_core::RuntimeDebug; use sp_std::{default::Default, vec::Vec}; use sp_trie::{ - accessed_nodes_tracker::AccessedNodesTracker, read_trie_value, LayoutV1, MemoryDB, - StorageProof, TrieDBBuilder, TrieHash, + accessed_nodes_tracker::AccessedNodesTracker, read_trie_value, LayoutV1, MemoryDB, StorageProof, }; 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, TrieError}; -use trie_db::Trie; +use sp_trie::{recorder_ext::RecorderExt, Recorder, TrieDBBuilder, TrieError, TrieHash}; #[cfg(feature = "test-helpers")] -use trie_db::{TrieConfiguration, TrieDBMut}; +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)] diff --git a/prdoc/pr_4935.prdoc b/prdoc/pr_4935.prdoc index 6e3e17ad9006..5bc0c0b53aed 100644 --- a/prdoc/pr_4935.prdoc +++ b/prdoc/pr_4935.prdoc @@ -25,3 +25,51 @@ doc: crates: - name: pallet-bridge-messages bump: major + - 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: minor + - name: bp-bridge-hub-kusama + bump: patch + - name: bp-bridge-hub-polkadot + bump: patch + - name: bp-bridge-hub-rococo + bump: patch + - name: bp-bridge-hub-westend + bump: patch + - name: bp-kusama + bump: patch + - name: bp-polkadot + bump: patch + - name: bp-polkadot-bulletin + bump: patch + - name: bp-rococo + bump: patch + - name: bp-test-utils + bump: patch + - name: bp-westend + bump: patch + - name: bridge-hub-test-utils + bump: patch + - 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: patch + - name: bridge-hub-westend-runtime + bump: patch From 0f1c5ff660446470781b33601e6b60156f1df125 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 3 Jul 2024 23:06:43 +0200 Subject: [PATCH 51/58] Adjust fees and prdoc --- bridges/chains/chain-bridge-hub-rococo/src/lib.rs | 4 ++-- bridges/chains/chain-bridge-hub-westend/src/lib.rs | 4 ++-- prdoc/pr_4935.prdoc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index d46801684499..73af997b9950 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -108,9 +108,9 @@ frame_support::parameter_types! { /// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message. /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) - pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 315_412_180; + 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_standalone_message_confirmation_transaction` + `33%`) - pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 58_434_469; + 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 5b7fd2174053..17ff2c858a1d 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -97,9 +97,9 @@ frame_support::parameter_types! { /// Transaction fee that is paid at the Westend BridgeHub for delivering single inbound message. /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) - pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 94_661_076_452; + pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 94_211_536_452; /// Transaction fee that is paid at the Westend BridgeHub for delivering single outbound message confirmation. /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`) - pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_530_386_452; + pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_224_486_452; } diff --git a/prdoc/pr_4935.prdoc b/prdoc/pr_4935.prdoc index 5bc0c0b53aed..468723f88bab 100644 --- a/prdoc/pr_4935.prdoc +++ b/prdoc/pr_4935.prdoc @@ -25,7 +25,7 @@ doc: crates: - name: pallet-bridge-messages bump: major - - bridge-runtime-common + - name: bridge-runtime-common bump: major - name: bp-header-chain bump: major From cf4270157b75a6a87bc60613ae1f17bde2348fe6 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 4 Jul 2024 11:12:06 +0200 Subject: [PATCH 52/58] macro nit + prdoc --- .../lib-substrate-relay/src/messages/mod.rs | 10 +++---- prdoc/pr_4935.prdoc | 26 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index 47bbf16bee76..e52b70206669 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -403,7 +403,7 @@ where ) -> CallOf { let call: CallOf = BridgeMessagesCall::::receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_source, - proof: Box::new(proof.1), + proof: proof.1.into(), messages_count, dispatch_weight, } @@ -455,7 +455,7 @@ macro_rules! generate_receive_message_proof_call_builder { bp_runtime::paste::item! { $bridge_messages($receive_messages_proof { relayer_id_at_bridged_chain: relayer_id_at_source, - proof: Box::new(proof.1), + proof: proof.1.into(), messages_count: messages_count, dispatch_weight: dispatch_weight, }) @@ -496,7 +496,7 @@ where ) -> CallOf { let call: CallOf = BridgeMessagesCall::::receive_messages_delivery_proof { - proof: proof.1, + proof: proof.1.into(), relayers_state: proof.0, } .into(); @@ -718,7 +718,7 @@ mod tests { let pallet_receive_messages_proof = pallet_bridge_messages::Call::::receive_messages_proof { relayer_id_at_bridged_chain: account, - proof: Box::new(receive_messages_proof.clone()), + proof: receive_messages_proof.clone().into(), messages_count, dispatch_weight, }; @@ -726,7 +726,7 @@ mod tests { // construct mock enum Call let mock_enum_receive_messages_proof = CodegenBridgeMessagesCall::receive_messages_proof { relayer_id_at_bridged_chain: account, - proof: Box::new(receive_messages_proof.clone()), + proof: receive_messages_proof.clone().into(), messages_count, dispatch_weight, }; diff --git a/prdoc/pr_4935.prdoc b/prdoc/pr_4935.prdoc index 468723f88bab..2b06899b6339 100644 --- a/prdoc/pr_4935.prdoc +++ b/prdoc/pr_4935.prdoc @@ -34,29 +34,29 @@ crates: - name: bp-messages bump: major - name: bp-polkadot-core - bump: minor - - name: bp-bridge-hub-kusama bump: patch + - name: bp-bridge-hub-kusama + bump: minor - name: bp-bridge-hub-polkadot - bump: patch + bump: minor - name: bp-bridge-hub-rococo - bump: patch + bump: minor - name: bp-bridge-hub-westend - bump: patch + bump: minor - name: bp-kusama - bump: patch + bump: minor - name: bp-polkadot - bump: patch + bump: minor - name: bp-polkadot-bulletin - bump: patch + bump: minor - name: bp-rococo - bump: patch + bump: minor - name: bp-test-utils bump: patch - name: bp-westend - bump: patch + bump: minor - name: bridge-hub-test-utils - bump: patch + bump: major - name: pallet-bridge-grandpa bump: patch - name: pallet-bridge-parachains @@ -70,6 +70,6 @@ crates: - name: asset-hub-westend-runtime bump: patch - name: bridge-hub-rococo-runtime - bump: patch + bump: major - name: bridge-hub-westend-runtime - bump: patch + bump: major From 1ed7df78ee122cd4e5cf12ece85109a084f9f475 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 4 Jul 2024 16:05:32 +0200 Subject: [PATCH 53/58] Review comments --- bridges/modules/grandpa/src/lib.rs | 2 +- bridges/modules/messages/src/benchmarking.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 08ceb0b0af78..c62951b74656 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -1443,7 +1443,7 @@ mod tests { } #[test] - fn verify_vec_db_storage_rejects_unknown_header() { + fn verify_storage_proof_rejects_unknown_header() { run_test(|| { assert_noop!( Pallet::::verify_storage_proof( diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index a088829bd485..d38aaf32dc94 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -494,7 +494,6 @@ mod benchmarks { // * 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. - // #[benchmark(extra)] #[benchmark] fn receive_single_n_bytes_message_proof_with_dispatch( /// Proof size in KB From 308ec4a88a1d4887cef240478cd6a00d35e556d1 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 5 Jul 2024 13:01:29 +0200 Subject: [PATCH 54/58] Nits --- bridges/modules/messages/src/proofs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index 9b5c15fb1929..18367029d72c 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -54,7 +54,7 @@ pub fn verify_messages_proof, I: 'static>( nonces_start, nonces_end, } = proof; - let mut parser: StorageProofCheckerAdapter = + let mut parser: MessagesStorageProofAdapter = MessagesStorageProofAdapter::try_new_with_verified_storage_proof( bridged_header_hash, storage_proof, @@ -110,7 +110,7 @@ pub fn verify_messages_delivery_proof, I: 'static>( proof: FromBridgedChainMessagesDeliveryProof>>, ) -> Result, VerificationError> { let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = proof; - let mut parser: StorageProofCheckerAdapter = + let mut parser: MessagesStorageProofAdapter = MessagesStorageProofAdapter::try_new_with_verified_storage_proof( bridged_header_hash, storage_proof, From 7c875bead7125b6481ee6b8298186305d056c00d Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 10 Jul 2024 12:13:11 +0200 Subject: [PATCH 55/58] [bridges] Prune messages from confirmation tx body, not from the on_idle (#4944) Original PR with more context: https://github.com/paritytech/parity-bridges-common/pull/2211 Relates to: https://github.com/paritytech/parity-bridges-common/issues/2210 ## TODO - [x] fresh weighs for `pallet_bridge_messages` - [x] add `try_state` for `pallet_bridge_messages` which checks for unpruned messages - relates to the [comment](https://github.com/paritytech/parity-bridges-common/pull/2211#issuecomment-1643224831) - [x] ~prepare migration, that prunes leftovers, which would be pruned eventually from `on_idle` the [comment](https://github.com/paritytech/parity-bridges-common/pull/2211#issuecomment-1643224831)~ can be done also by `set_storage` / `kill_storage` or with `OnRuntimeUpgrade` implementatino when `do_try_state_for_outbound_lanes` detects problem. ## Open question - [ ] Do we really need `oldest_unpruned_nonce` afterwards? - after the runtime upgrade and when `do_try_state_for_outbound_lanes` pass, we won't need any migrations here - we won't even need `do_try_state_for_outbound_lanes` --------- Signed-off-by: Branislav Kontur Co-authored-by: Svyatoslav Nikolsky Co-authored-by: command-bot <> --- bridges/modules/messages/src/lib.rs | 95 ++++++---- bridges/modules/messages/src/outbound_lane.rs | 106 ++--------- .../messages/src/tests/pallet_tests.rs | 169 +++++------------- ...idge_messages_rococo_to_rococo_bulletin.rs | 56 +++--- ...allet_bridge_messages_rococo_to_westend.rs | 58 +++--- .../src/weights/pallet_bridge_messages.rs | 58 +++--- 6 files changed, 210 insertions(+), 332 deletions(-) diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index bf105b140401..c36313a14764 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -70,7 +70,6 @@ use bp_runtime::{ }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound}; -use sp_runtime::traits::UniqueSaturatedFrom; use sp_std::{marker::PhantomData, prelude::*}; mod inbound_lane; @@ -153,40 +152,6 @@ pub mod pallet { type OperatingModeStorage = PalletOperatingMode; } - #[pallet::hooks] - impl, I: 'static> Hooks> for Pallet - where - u32: TryFrom>, - { - fn on_idle(_block: BlockNumberFor, remaining_weight: Weight) -> Weight { - // we'll need at least to read outbound lane state, kill a message and update lane state - let db_weight = T::DbWeight::get(); - if !remaining_weight.all_gte(db_weight.reads_writes(1, 2)) { - return Weight::zero() - } - - // messages from lane with index `i` in `ActiveOutboundLanes` are pruned when - // `System::block_number() % lanes.len() == i`. Otherwise we need to read lane states on - // every block, wasting the whole `remaining_weight` for nothing and causing starvation - // of the last lane pruning - let active_lanes = T::ActiveOutboundLanes::get(); - let active_lanes_len = (active_lanes.len() as u32).into(); - let active_lane_index = u32::unique_saturated_from( - frame_system::Pallet::::block_number() % active_lanes_len, - ); - let active_lane_id = active_lanes[active_lane_index as usize]; - - // first db read - outbound lane state - let mut active_lane = outbound_lane::(active_lane_id); - let mut used_weight = db_weight.reads(1); - // and here we'll have writes - used_weight += active_lane.prune_messages(db_weight, remaining_weight - used_weight); - - // we already checked we have enough `remaining_weight` to cover this `used_weight` - used_weight - } - } - #[pallet::call] impl, I: 'static> Pallet { /// Change `PalletOwner`. @@ -610,6 +575,14 @@ pub mod pallet { } } + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + #[cfg(feature = "try-runtime")] + fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { + Self::do_try_state() + } + } + impl, I: 'static> Pallet { /// Get stored data of the outbound message with given nonce. pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option { @@ -644,6 +617,58 @@ pub mod pallet { } } + #[cfg(any(feature = "try-runtime", test))] + impl, I: 'static> Pallet { + /// Ensure the correctness of the state of this pallet. + pub fn do_try_state() -> Result<(), sp_runtime::TryRuntimeError> { + Self::do_try_state_for_outbound_lanes() + } + + /// Ensure the correctness of the state of outbound lanes. + pub fn do_try_state_for_outbound_lanes() -> Result<(), sp_runtime::TryRuntimeError> { + use sp_runtime::traits::One; + use sp_std::vec::Vec; + + // collect unpruned lanes + let mut unpruned_lanes = Vec::new(); + for (lane_id, lane_data) in OutboundLanes::::iter() { + let Some(expected_last_prunned_nonce) = + lane_data.oldest_unpruned_nonce.checked_sub(One::one()) + else { + continue; + }; + + // collect message_nonces that were supposed to be pruned + let mut unpruned_message_nonces = Vec::new(); + const MAX_MESSAGES_ITERATION: u64 = 16; + let start_nonce = + expected_last_prunned_nonce.checked_sub(MAX_MESSAGES_ITERATION).unwrap_or(0); + for current_nonce in start_nonce..=expected_last_prunned_nonce { + // check a message for current_nonce + if OutboundMessages::::contains_key(MessageKey { + lane_id, + nonce: current_nonce, + }) { + unpruned_message_nonces.push(current_nonce); + } + } + + if !unpruned_message_nonces.is_empty() { + log::warn!( + target: LOG_TARGET, + "do_try_state_for_outbound_lanes for lane_id: {lane_id:?} with lane_data: {lane_data:?} found unpruned_message_nonces: {unpruned_message_nonces:?}", + ); + unpruned_lanes.push((lane_id, lane_data, unpruned_message_nonces)); + } + } + + // ensure messages before `oldest_unpruned_nonce` are really pruned. + ensure!(unpruned_lanes.is_empty(), "Found unpruned lanes!"); + + Ok(()) + } + } + /// Get-parameter that returns number of active outbound lanes that the pallet maintains. pub struct MaybeOutboundLanesCount(PhantomData<(T, I)>); diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index fcdddf199dc6..788a13e82b1b 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -22,13 +22,9 @@ use bp_messages::{ ChainWithMessages, DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, }; use codec::{Decode, Encode}; -use frame_support::{ - traits::Get, - weights::{RuntimeDbWeight, Weight}, - BoundedVec, PalletError, -}; +use frame_support::{traits::Get, BoundedVec, PalletError}; use scale_info::TypeInfo; -use sp_runtime::{traits::Zero, RuntimeDebug}; +use sp_runtime::RuntimeDebug; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData}; /// Outbound lane storage. @@ -143,41 +139,17 @@ impl OutboundLane { ensure_unrewarded_relayers_are_correct(confirmed_messages.end, relayers)?; + // prune all confirmed messages + for nonce in confirmed_messages.begin..=confirmed_messages.end { + self.storage.remove_message(&nonce); + } + data.latest_received_nonce = confirmed_messages.end; + data.oldest_unpruned_nonce = data.latest_received_nonce.saturating_add(1); self.storage.set_data(data); Ok(Some(confirmed_messages)) } - - /// Prune at most `max_messages_to_prune` already received messages. - /// - /// Returns weight, consumed by messages pruning and lane state update. - pub fn prune_messages( - &mut self, - db_weight: RuntimeDbWeight, - mut remaining_weight: Weight, - ) -> Weight { - let write_weight = db_weight.writes(1); - let two_writes_weight = write_weight + write_weight; - let mut spent_weight = Weight::zero(); - let mut data = self.storage.data(); - while remaining_weight.all_gte(two_writes_weight) && - data.oldest_unpruned_nonce <= data.latest_received_nonce - { - self.storage.remove_message(&data.oldest_unpruned_nonce); - - spent_weight += write_weight; - remaining_weight -= write_weight; - data.oldest_unpruned_nonce += 1; - } - - if !spent_weight.is_zero() { - spent_weight += write_weight; - self.storage.set_data(data); - } - - spent_weight - } } /// Verifies unrewarded relayers vec. @@ -221,7 +193,6 @@ mod tests { REGULAR_PAYLOAD, TEST_LANE_ID, }, }; - use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; fn unrewarded_relayers( @@ -281,7 +252,7 @@ mod tests { ); 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.storage.data().oldest_unpruned_nonce, 4); }); } @@ -302,7 +273,7 @@ mod tests { ); 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.storage.data().oldest_unpruned_nonce, 3); assert_eq!( lane.confirm_delivery(3, 3, &unrewarded_relayers(3..=3)), @@ -310,7 +281,7 @@ mod tests { ); 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.storage.data().oldest_unpruned_nonce, 4); }); } @@ -331,12 +302,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.storage.data().oldest_unpruned_nonce, 4); 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); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4); }); } @@ -394,57 +365,6 @@ mod tests { ); } - #[test] - fn prune_messages_works() { - run_test(|| { - let mut lane = outbound_lane::(TEST_LANE_ID); - // when lane is empty, nothing is pruned - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - Weight::zero() - ); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); - // when nothing is confirmed, nothing is pruned - lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); - lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); - lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); - assert!(lane.storage.message(&1).is_some()); - assert!(lane.storage.message(&2).is_some()); - assert!(lane.storage.message(&3).is_some()); - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - Weight::zero() - ); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); - // after confirmation, some messages are received - assert_eq!( - lane.confirm_delivery(2, 2, &unrewarded_relayers(1..=2)), - Ok(Some(delivered_messages(1..=2))), - ); - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - RocksDbWeight::get().writes(3), - ); - assert!(lane.storage.message(&1).is_none()); - assert!(lane.storage.message(&2).is_none()); - assert!(lane.storage.message(&3).is_some()); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 3); - // after last message is confirmed, everything is pruned - assert_eq!( - lane.confirm_delivery(1, 3, &unrewarded_relayers(3..=3)), - Ok(Some(delivered_messages(3..=3))), - ); - assert_eq!( - lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), - RocksDbWeight::get().writes(2), - ); - assert!(lane.storage.message(&1).is_none()); - assert!(lane.storage.message(&2).is_none()); - assert!(lane.storage.message(&3).is_none()); - assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4); - }); - } - #[test] fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index 42e1042717de..f7a288d649a9 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -38,15 +38,14 @@ 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, + assert_err, 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; +use sp_runtime::{BoundedVec, DispatchError}; fn get_ready_for_events() { System::::set_block_number(1); @@ -99,6 +98,7 @@ fn receive_messages_delivery_proof() { last_delivered_nonce: 1, }, )); + assert_ok!(Pallet::::do_try_state()); assert_eq!( System::::events(), @@ -160,6 +160,7 @@ fn pallet_rejects_transactions_if_halted() { ), Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), ); + assert_ok!(Pallet::::do_try_state()); }); } @@ -220,6 +221,7 @@ fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { last_delivered_nonce: 1, }, )); + assert_ok!(Pallet::::do_try_state()); }); } @@ -395,10 +397,14 @@ fn receive_messages_proof_rejects_proof_with_too_many_messages() { #[test] fn receive_messages_delivery_proof_works() { run_test(|| { + assert_eq!(OutboundLanes::::get(TEST_LANE_ID).latest_received_nonce, 0); + assert_eq!(OutboundLanes::::get(TEST_LANE_ID).oldest_unpruned_nonce, 1); + send_regular_message(TEST_LANE_ID); receive_messages_delivery_proof(); - assert_eq!(OutboundLanes::::get(TEST_LANE_ID).latest_received_nonce, 1,); + assert_eq!(OutboundLanes::::get(TEST_LANE_ID).latest_received_nonce, 1); + assert_eq!(OutboundLanes::::get(TEST_LANE_ID).oldest_unpruned_nonce, 2); }); } @@ -428,6 +434,7 @@ fn receive_messages_delivery_proof_rewards_relayers() { }, ); assert_ok!(result); + assert_ok!(Pallet::::do_try_state()); assert_eq!( result.unwrap().actual_weight.unwrap(), TestWeightInfo::receive_messages_delivery_proof_weight( @@ -467,6 +474,7 @@ fn receive_messages_delivery_proof_rewards_relayers() { }, ); assert_ok!(result); + assert_ok!(Pallet::::do_try_state()); // even though the pre-dispatch weight was for two messages, the actual weight is // for single message only assert_eq!( @@ -852,129 +860,6 @@ fn inbound_message_details_works() { }); } -#[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::::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::(TEST_LANE_ID).data().latest_received_nonce, 4); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); - System::::set_block_number(2); - - // if passed wight is too low to do anything - let dbw = DbWeight::get(); - assert_eq!(Pallet::::on_idle(0, dbw.reads_writes(1, 1)), Weight::zero(),); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); - - // if passed wight is enough to prune single message - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 2)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); - - // if passed wight is enough to prune two more messages - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(1, 3)), - dbw.reads_writes(1, 3), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 4); - - // if passed wight is enough to prune many messages - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, 1); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, - 1 - ); - assert_eq!( - outbound_lane::(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::::set_block_number(2); - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 1 - ); - - // in block#3.on_idle lane messages of lane 2 are pruned - System::::set_block_number(3); - - assert_eq!( - Pallet::::on_idle(0, dbw.reads_writes(100, 100)), - dbw.reads_writes(1, 2), - ); - assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); - assert_eq!( - outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, - 2 - ); - }); -} - #[test] fn outbound_message_from_unconfigured_lane_is_rejected() { run_test(|| { @@ -1098,3 +983,33 @@ fn maybe_outbound_lanes_count_returns_correct_value() { Some(mock::ActiveOutboundLanes::get().len() as u32) ); } + +#[test] +fn do_try_state_for_outbound_lanes_works() { + run_test(|| { + let lane_id = TEST_LANE_ID; + + // setup delivered nonce 1 + OutboundLanes::::insert( + lane_id, + OutboundLaneData { + oldest_unpruned_nonce: 2, + latest_received_nonce: 1, + latest_generated_nonce: 0, + }, + ); + // store message for nonce 1 + OutboundMessages::::insert( + MessageKey { lane_id, nonce: 1 }, + BoundedVec::default(), + ); + assert_err!( + Pallet::::do_try_state(), + sp_runtime::TryRuntimeError::Other("Found unpruned lanes!") + ); + + // remove message for nonce 1 + OutboundMessages::::remove(MessageKey { lane_id, nonce: 1 }); + assert_ok!(Pallet::::do_try_state()); + }) +} 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 5522a325f192..d0a7ed25363d 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-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-04, 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 pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 37_206_000 picoseconds. - Weight::from_parts(38_545_000, 0) + // Minimum execution time: 36_836_000 picoseconds. + Weight::from_parts(37_858_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -80,11 +80,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 37_075_000 picoseconds. - Weight::from_parts(37_757_000, 0) + // Minimum execution time: 36_587_000 picoseconds. + Weight::from_parts(37_516_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())) + // Standard Error: 8_655 + .saturating_add(Weight::from_parts(11_649_169, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -100,8 +100,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 42_087_000 picoseconds. - Weight::from_parts(42_970_000, 0) + // Minimum execution time: 42_157_000 picoseconds. + Weight::from_parts(43_105_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -120,11 +120,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 35_055_000 picoseconds. - Weight::from_parts(36_987_740, 0) + // Minimum execution time: 35_536_000 picoseconds. + Weight::from_parts(37_452_828, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 4 - .saturating_add(Weight::from_parts(2_316, 0).saturating_mul(n.into())) + // Standard Error: 3 + .saturating_add(Weight::from_parts(2_269, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -134,15 +134,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:1) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 24_326_000 picoseconds. - Weight::from_parts(25_169_000, 0) + // Minimum execution time: 25_800_000 picoseconds. + Weight::from_parts(26_666_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -150,15 +152,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 24_484_000 picoseconds. - Weight::from_parts(25_130_000, 0) + // Minimum execution time: 27_262_000 picoseconds. + Weight::from_parts(27_997_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -166,15 +170,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 24_450_000 picoseconds. - Weight::from_parts(25_164_000, 0) + // Minimum execution time: 26_992_000 picoseconds. + Weight::from_parts(27_921_000, 0) .saturating_add(Weight::from_parts(0, 2543)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgePolkadotBulletinMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgePolkadotBulletinMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -204,11 +210,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `813` // Estimated: `52645` - // Minimum execution time: 54_317_000 picoseconds. - Weight::from_parts(59_171_547, 0) + // Minimum execution time: 55_509_000 picoseconds. + Weight::from_parts(59_826_763, 0) .saturating_add(Weight::from_parts(0, 52645)) // Standard Error: 7 - .saturating_add(Weight::from_parts(7_566, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(7_565, 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 9c05dae979da..dc6c917c6d00 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-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-04, 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 pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 41_396_000 picoseconds. - Weight::from_parts(43_141_000, 0) + // Minimum execution time: 40_198_000 picoseconds. + Weight::from_parts(42_079_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -84,11 +84,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 41_095_000 picoseconds. - Weight::from_parts(42_030_000, 0) + // Minimum execution time: 39_990_000 picoseconds. + Weight::from_parts(41_381_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())) + // Standard Error: 8_459 + .saturating_add(Weight::from_parts(11_710_167, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -106,8 +106,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 45_912_000 picoseconds. - Weight::from_parts(47_564_000, 0) + // Minimum execution time: 45_940_000 picoseconds. + Weight::from_parts(47_753_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -128,11 +128,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 39_175_000 picoseconds. - Weight::from_parts(41_674_095, 0) + // Minimum execution time: 39_067_000 picoseconds. + Weight::from_parts(41_787_019, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 4 - .saturating_add(Weight::from_parts(2_305, 0).saturating_mul(n.into())) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_295, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -146,15 +146,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 32_033_000 picoseconds. - Weight::from_parts(33_131_000, 0) + // Minimum execution time: 33_107_000 picoseconds. + Weight::from_parts(34_364_000, 0) .saturating_add(Weight::from_parts(0, 3966)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -166,15 +168,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 32_153_000 picoseconds. - Weight::from_parts(33_126_000, 0) + // Minimum execution time: 34_826_000 picoseconds. + Weight::from_parts(35_563_000, 0) .saturating_add(Weight::from_parts(0, 3966)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -186,15 +190,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `6086` - // Minimum execution time: 36_387_000 picoseconds. - Weight::from_parts(37_396_000, 0) + // Minimum execution time: 38_725_000 picoseconds. + Weight::from_parts(39_727_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -224,11 +230,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `789` // Estimated: `52645` - // Minimum execution time: 56_562_000 picoseconds. - Weight::from_parts(61_452_871, 0) + // Minimum execution time: 56_892_000 picoseconds. + Weight::from_parts(61_941_659, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 9 - .saturating_add(Weight::from_parts(7_587, 0).saturating_mul(n.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(7_580, 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_messages.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs index 386342d7ea5d..1033387b527e 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-07-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-04, 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 pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_748_000 picoseconds. - Weight::from_parts(41_836_000, 0) + // Minimum execution time: 40_289_000 picoseconds. + Weight::from_parts(42_150_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -83,11 +83,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_923_000 picoseconds. - Weight::from_parts(41_287_000, 0) + // Minimum execution time: 40_572_000 picoseconds. + Weight::from_parts(41_033_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())) + // Standard Error: 12_000 + .saturating_add(Weight::from_parts(11_710_588, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -105,8 +105,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 45_946_000 picoseconds. - Weight::from_parts(47_547_000, 0) + // Minimum execution time: 46_655_000 picoseconds. + Weight::from_parts(49_576_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -126,11 +126,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 39_668_000 picoseconds. - Weight::from_parts(41_908_980, 0) + // Minimum execution time: 40_245_000 picoseconds. + Weight::from_parts(43_461_320, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 11 - .saturating_add(Weight::from_parts(2_209, 0).saturating_mul(n.into())) + // Standard Error: 21 + .saturating_add(Weight::from_parts(2_246, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -144,15 +144,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 30_544_000 picoseconds. - Weight::from_parts(31_171_000, 0) + // Minimum execution time: 32_001_000 picoseconds. + Weight::from_parts(32_842_000, 0) .saturating_add(Weight::from_parts(0, 3822)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -164,15 +166,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 30_593_000 picoseconds. - Weight::from_parts(31_261_000, 0) + // Minimum execution time: 33_287_000 picoseconds. + Weight::from_parts(33_769_000, 0) .saturating_add(Weight::from_parts(0, 3822)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -184,15 +188,17 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `6086` - // Minimum execution time: 34_682_000 picoseconds. - Weight::from_parts(35_277_000, 0) + // Minimum execution time: 37_136_000 picoseconds. + Weight::from_parts(38_294_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -221,11 +227,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `653` // Estimated: `52645` - // Minimum execution time: 56_465_000 picoseconds. - Weight::from_parts(61_575_775, 0) + // Minimum execution time: 55_942_000 picoseconds. + Weight::from_parts(60_615_769, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 15 - .saturating_add(Weight::from_parts(7_197, 0).saturating_mul(n.into())) + // Standard Error: 14 + .saturating_add(Weight::from_parts(7_225, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } From 1dc37bcf4a93396beeee22a5cbe456f651dc05c4 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 11 Jul 2024 13:44:02 +0000 Subject: [PATCH 56/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_grandpa --- .../src/weights/pallet_bridge_grandpa.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) 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 3073705b2df8..4ce57b2e5016 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-07-03, 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: @@ -64,15 +64,17 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo Weight { + fn submit_finality_proof(p: u32, v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `438 + p * (60 ±0)` // Estimated: `51735` - // Minimum execution time: 301_982_000 picoseconds. - Weight::from_parts(356_093_000, 0) + // Minimum execution time: 325_365_000 picoseconds. + Weight::from_parts(14_958_535, 0) .saturating_add(Weight::from_parts(0, 51735)) - // Standard Error: 24_378 - .saturating_add(Weight::from_parts(50_293_143, 0).saturating_mul(p.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)) } @@ -90,8 +92,8 @@ impl pallet_bridge_grandpa::WeightInfo for WeightInfo Date: Thu, 11 Jul 2024 13:44:29 +0000 Subject: [PATCH 57/58] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_grandpa --- .../src/weights/pallet_bridge_grandpa.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 55d1664e17fa..fa7efc260489 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-07-03, 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 pallet_bridge_grandpa::WeightInfo for WeightInfo pallet_bridge_grandpa::WeightInfo for WeightInfo Date: Thu, 11 Jul 2024 16:08:08 +0200 Subject: [PATCH 58/58] Revert "[bridges] Prune messages from confirmation tx body, not from the on_idle" (#5005) Reverts paritytech/polkadot-sdk#4944 --- bridges/modules/messages/src/lib.rs | 95 ++++------ bridges/modules/messages/src/outbound_lane.rs | 106 +++++++++-- .../messages/src/tests/pallet_tests.rs | 169 +++++++++++++----- ...idge_messages_rococo_to_rococo_bulletin.rs | 56 +++--- ...allet_bridge_messages_rococo_to_westend.rs | 58 +++--- .../src/weights/pallet_bridge_messages.rs | 58 +++--- 6 files changed, 332 insertions(+), 210 deletions(-) diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index c36313a14764..bf105b140401 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -70,6 +70,7 @@ use bp_runtime::{ }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound}; +use sp_runtime::traits::UniqueSaturatedFrom; use sp_std::{marker::PhantomData, prelude::*}; mod inbound_lane; @@ -152,6 +153,40 @@ pub mod pallet { type OperatingModeStorage = PalletOperatingMode; } + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet + where + u32: TryFrom>, + { + fn on_idle(_block: BlockNumberFor, remaining_weight: Weight) -> Weight { + // we'll need at least to read outbound lane state, kill a message and update lane state + let db_weight = T::DbWeight::get(); + if !remaining_weight.all_gte(db_weight.reads_writes(1, 2)) { + return Weight::zero() + } + + // messages from lane with index `i` in `ActiveOutboundLanes` are pruned when + // `System::block_number() % lanes.len() == i`. Otherwise we need to read lane states on + // every block, wasting the whole `remaining_weight` for nothing and causing starvation + // of the last lane pruning + let active_lanes = T::ActiveOutboundLanes::get(); + let active_lanes_len = (active_lanes.len() as u32).into(); + let active_lane_index = u32::unique_saturated_from( + frame_system::Pallet::::block_number() % active_lanes_len, + ); + let active_lane_id = active_lanes[active_lane_index as usize]; + + // first db read - outbound lane state + let mut active_lane = outbound_lane::(active_lane_id); + let mut used_weight = db_weight.reads(1); + // and here we'll have writes + used_weight += active_lane.prune_messages(db_weight, remaining_weight - used_weight); + + // we already checked we have enough `remaining_weight` to cover this `used_weight` + used_weight + } + } + #[pallet::call] impl, I: 'static> Pallet { /// Change `PalletOwner`. @@ -575,14 +610,6 @@ pub mod pallet { } } - #[pallet::hooks] - impl, I: 'static> Hooks> for Pallet { - #[cfg(feature = "try-runtime")] - fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { - Self::do_try_state() - } - } - impl, I: 'static> Pallet { /// Get stored data of the outbound message with given nonce. pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option { @@ -617,58 +644,6 @@ pub mod pallet { } } - #[cfg(any(feature = "try-runtime", test))] - impl, I: 'static> Pallet { - /// Ensure the correctness of the state of this pallet. - pub fn do_try_state() -> Result<(), sp_runtime::TryRuntimeError> { - Self::do_try_state_for_outbound_lanes() - } - - /// Ensure the correctness of the state of outbound lanes. - pub fn do_try_state_for_outbound_lanes() -> Result<(), sp_runtime::TryRuntimeError> { - use sp_runtime::traits::One; - use sp_std::vec::Vec; - - // collect unpruned lanes - let mut unpruned_lanes = Vec::new(); - for (lane_id, lane_data) in OutboundLanes::::iter() { - let Some(expected_last_prunned_nonce) = - lane_data.oldest_unpruned_nonce.checked_sub(One::one()) - else { - continue; - }; - - // collect message_nonces that were supposed to be pruned - let mut unpruned_message_nonces = Vec::new(); - const MAX_MESSAGES_ITERATION: u64 = 16; - let start_nonce = - expected_last_prunned_nonce.checked_sub(MAX_MESSAGES_ITERATION).unwrap_or(0); - for current_nonce in start_nonce..=expected_last_prunned_nonce { - // check a message for current_nonce - if OutboundMessages::::contains_key(MessageKey { - lane_id, - nonce: current_nonce, - }) { - unpruned_message_nonces.push(current_nonce); - } - } - - if !unpruned_message_nonces.is_empty() { - log::warn!( - target: LOG_TARGET, - "do_try_state_for_outbound_lanes for lane_id: {lane_id:?} with lane_data: {lane_data:?} found unpruned_message_nonces: {unpruned_message_nonces:?}", - ); - unpruned_lanes.push((lane_id, lane_data, unpruned_message_nonces)); - } - } - - // ensure messages before `oldest_unpruned_nonce` are really pruned. - ensure!(unpruned_lanes.is_empty(), "Found unpruned lanes!"); - - Ok(()) - } - } - /// Get-parameter that returns number of active outbound lanes that the pallet maintains. pub struct MaybeOutboundLanesCount(PhantomData<(T, I)>); diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index 788a13e82b1b..fcdddf199dc6 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -22,9 +22,13 @@ use bp_messages::{ ChainWithMessages, DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer, }; use codec::{Decode, Encode}; -use frame_support::{traits::Get, BoundedVec, PalletError}; +use frame_support::{ + traits::Get, + weights::{RuntimeDbWeight, Weight}, + BoundedVec, PalletError, +}; use scale_info::TypeInfo; -use sp_runtime::RuntimeDebug; +use sp_runtime::{traits::Zero, RuntimeDebug}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData}; /// Outbound lane storage. @@ -139,17 +143,41 @@ impl OutboundLane { ensure_unrewarded_relayers_are_correct(confirmed_messages.end, relayers)?; - // prune all confirmed messages - for nonce in confirmed_messages.begin..=confirmed_messages.end { - self.storage.remove_message(&nonce); - } - data.latest_received_nonce = confirmed_messages.end; - data.oldest_unpruned_nonce = data.latest_received_nonce.saturating_add(1); self.storage.set_data(data); Ok(Some(confirmed_messages)) } + + /// Prune at most `max_messages_to_prune` already received messages. + /// + /// Returns weight, consumed by messages pruning and lane state update. + pub fn prune_messages( + &mut self, + db_weight: RuntimeDbWeight, + mut remaining_weight: Weight, + ) -> Weight { + let write_weight = db_weight.writes(1); + let two_writes_weight = write_weight + write_weight; + let mut spent_weight = Weight::zero(); + let mut data = self.storage.data(); + while remaining_weight.all_gte(two_writes_weight) && + data.oldest_unpruned_nonce <= data.latest_received_nonce + { + self.storage.remove_message(&data.oldest_unpruned_nonce); + + spent_weight += write_weight; + remaining_weight -= write_weight; + data.oldest_unpruned_nonce += 1; + } + + if !spent_weight.is_zero() { + spent_weight += write_weight; + self.storage.set_data(data); + } + + spent_weight + } } /// Verifies unrewarded relayers vec. @@ -193,6 +221,7 @@ mod tests { REGULAR_PAYLOAD, TEST_LANE_ID, }, }; + use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; fn unrewarded_relayers( @@ -252,7 +281,7 @@ mod tests { ); 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, 4); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -273,7 +302,7 @@ mod tests { ); 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, 3); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); assert_eq!( lane.confirm_delivery(3, 3, &unrewarded_relayers(3..=3)), @@ -281,7 +310,7 @@ mod tests { ); 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, 4); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -302,12 +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, 4); + 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, 4); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); }); } @@ -365,6 +394,57 @@ mod tests { ); } + #[test] + fn prune_messages_works() { + run_test(|| { + let mut lane = outbound_lane::(TEST_LANE_ID); + // when lane is empty, nothing is pruned + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + Weight::zero() + ); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + // when nothing is confirmed, nothing is pruned + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + assert!(lane.storage.message(&1).is_some()); + assert!(lane.storage.message(&2).is_some()); + assert!(lane.storage.message(&3).is_some()); + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + Weight::zero() + ); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); + // after confirmation, some messages are received + assert_eq!( + lane.confirm_delivery(2, 2, &unrewarded_relayers(1..=2)), + Ok(Some(delivered_messages(1..=2))), + ); + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + RocksDbWeight::get().writes(3), + ); + assert!(lane.storage.message(&1).is_none()); + assert!(lane.storage.message(&2).is_none()); + assert!(lane.storage.message(&3).is_some()); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 3); + // after last message is confirmed, everything is pruned + assert_eq!( + lane.confirm_delivery(1, 3, &unrewarded_relayers(3..=3)), + Ok(Some(delivered_messages(3..=3))), + ); + assert_eq!( + lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)), + RocksDbWeight::get().writes(2), + ); + assert!(lane.storage.message(&1).is_none()); + assert!(lane.storage.message(&2).is_none()); + assert!(lane.storage.message(&3).is_none()); + assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4); + }); + } + #[test] fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index f7a288d649a9..42e1042717de 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -38,14 +38,15 @@ use bp_runtime::{BasicOperatingMode, PreComputedSize, RangeInclusiveExt, Size}; use bp_test_utils::generate_owned_bridge_module_tests; use codec::Encode; use frame_support::{ - assert_err, assert_noop, assert_ok, + 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::{BoundedVec, DispatchError}; +use sp_runtime::DispatchError; fn get_ready_for_events() { System::::set_block_number(1); @@ -98,7 +99,6 @@ fn receive_messages_delivery_proof() { last_delivered_nonce: 1, }, )); - assert_ok!(Pallet::::do_try_state()); assert_eq!( System::::events(), @@ -160,7 +160,6 @@ fn pallet_rejects_transactions_if_halted() { ), Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted), ); - assert_ok!(Pallet::::do_try_state()); }); } @@ -221,7 +220,6 @@ fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { last_delivered_nonce: 1, }, )); - assert_ok!(Pallet::::do_try_state()); }); } @@ -397,14 +395,10 @@ fn receive_messages_proof_rejects_proof_with_too_many_messages() { #[test] fn receive_messages_delivery_proof_works() { run_test(|| { - assert_eq!(OutboundLanes::::get(TEST_LANE_ID).latest_received_nonce, 0); - assert_eq!(OutboundLanes::::get(TEST_LANE_ID).oldest_unpruned_nonce, 1); - send_regular_message(TEST_LANE_ID); receive_messages_delivery_proof(); - assert_eq!(OutboundLanes::::get(TEST_LANE_ID).latest_received_nonce, 1); - assert_eq!(OutboundLanes::::get(TEST_LANE_ID).oldest_unpruned_nonce, 2); + assert_eq!(OutboundLanes::::get(TEST_LANE_ID).latest_received_nonce, 1,); }); } @@ -434,7 +428,6 @@ fn receive_messages_delivery_proof_rewards_relayers() { }, ); assert_ok!(result); - assert_ok!(Pallet::::do_try_state()); assert_eq!( result.unwrap().actual_weight.unwrap(), TestWeightInfo::receive_messages_delivery_proof_weight( @@ -474,7 +467,6 @@ fn receive_messages_delivery_proof_rewards_relayers() { }, ); assert_ok!(result); - assert_ok!(Pallet::::do_try_state()); // even though the pre-dispatch weight was for two messages, the actual weight is // for single message only assert_eq!( @@ -860,6 +852,129 @@ fn inbound_message_details_works() { }); } +#[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::::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::(TEST_LANE_ID).data().latest_received_nonce, 4); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + System::::set_block_number(2); + + // if passed wight is too low to do anything + let dbw = DbWeight::get(); + assert_eq!(Pallet::::on_idle(0, dbw.reads_writes(1, 1)), Weight::zero(),); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + + // if passed wight is enough to prune single message + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(1, 2)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + + // if passed wight is enough to prune two more messages + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(1, 3)), + dbw.reads_writes(1, 3), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 4); + + // if passed wight is enough to prune many messages + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(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::::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::(TEST_LANE_ID).data().latest_received_nonce, 1); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 1); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().latest_received_nonce, + 1 + ); + assert_eq!( + outbound_lane::(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::::set_block_number(2); + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 1 + ); + + // in block#3.on_idle lane messages of lane 2 are pruned + System::::set_block_number(3); + + assert_eq!( + Pallet::::on_idle(0, dbw.reads_writes(100, 100)), + dbw.reads_writes(1, 2), + ); + assert_eq!(outbound_lane::(TEST_LANE_ID).data().oldest_unpruned_nonce, 2); + assert_eq!( + outbound_lane::(TEST_LANE_ID_2).data().oldest_unpruned_nonce, + 2 + ); + }); +} + #[test] fn outbound_message_from_unconfigured_lane_is_rejected() { run_test(|| { @@ -983,33 +1098,3 @@ fn maybe_outbound_lanes_count_returns_correct_value() { Some(mock::ActiveOutboundLanes::get().len() as u32) ); } - -#[test] -fn do_try_state_for_outbound_lanes_works() { - run_test(|| { - let lane_id = TEST_LANE_ID; - - // setup delivered nonce 1 - OutboundLanes::::insert( - lane_id, - OutboundLaneData { - oldest_unpruned_nonce: 2, - latest_received_nonce: 1, - latest_generated_nonce: 0, - }, - ); - // store message for nonce 1 - OutboundMessages::::insert( - MessageKey { lane_id, nonce: 1 }, - BoundedVec::default(), - ); - assert_err!( - Pallet::::do_try_state(), - sp_runtime::TryRuntimeError::Other("Found unpruned lanes!") - ); - - // remove message for nonce 1 - OutboundMessages::::remove(MessageKey { lane_id, nonce: 1 }); - assert_ok!(Pallet::::do_try_state()); - }) -} 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 d0a7ed25363d..5522a325f192 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-07-04, 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 pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 36_836_000 picoseconds. - Weight::from_parts(37_858_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)) @@ -80,11 +80,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 36_587_000 picoseconds. - Weight::from_parts(37_516_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: 8_655 - .saturating_add(Weight::from_parts(11_649_169, 0).saturating_mul(n.into())) + // 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)) } @@ -100,8 +100,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 42_157_000 picoseconds. - Weight::from_parts(43_105_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)) @@ -120,11 +120,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `654` // Estimated: `52645` - // Minimum execution time: 35_536_000 picoseconds. - Weight::from_parts(37_452_828, 0) + // Minimum execution time: 35_055_000 picoseconds. + Weight::from_parts(36_987_740, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 3 - .saturating_add(Weight::from_parts(2_269, 0).saturating_mul(n.into())) + // 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)) } @@ -134,17 +134,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 25_800_000 picoseconds. - Weight::from_parts(26_666_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(2)) + .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`) @@ -152,17 +150,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 27_262_000 picoseconds. - Weight::from_parts(27_997_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(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`) @@ -170,17 +166,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) - /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `621` // Estimated: `2543` - // Minimum execution time: 26_992_000 picoseconds. - Weight::from_parts(27_921_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(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`) @@ -210,11 +204,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `813` // Estimated: `52645` - // Minimum execution time: 55_509_000 picoseconds. - Weight::from_parts(59_826_763, 0) + // Minimum execution time: 54_317_000 picoseconds. + Weight::from_parts(59_171_547, 0) .saturating_add(Weight::from_parts(0, 52645)) // Standard Error: 7 - .saturating_add(Weight::from_parts(7_565, 0).saturating_mul(n.into())) + .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 dc6c917c6d00..9c05dae979da 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-07-04, 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 pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 40_198_000 picoseconds. - Weight::from_parts(42_079_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)) @@ -84,11 +84,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 39_990_000 picoseconds. - Weight::from_parts(41_381_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: 8_459 - .saturating_add(Weight::from_parts(11_710_167, 0).saturating_mul(n.into())) + // 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)) } @@ -106,8 +106,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 45_940_000 picoseconds. - Weight::from_parts(47_753_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)) @@ -128,11 +128,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `658` // Estimated: `52645` - // Minimum execution time: 39_067_000 picoseconds. - Weight::from_parts(41_787_019, 0) + // Minimum execution time: 39_175_000 picoseconds. + Weight::from_parts(41_674_095, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 5 - .saturating_add(Weight::from_parts(2_295, 0).saturating_mul(n.into())) + // 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)) } @@ -146,17 +146,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 33_107_000 picoseconds. - Weight::from_parts(34_364_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(3)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -168,17 +166,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `3966` - // Minimum execution time: 34_826_000 picoseconds. - Weight::from_parts(35_563_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(4)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -190,17 +186,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `501` // Estimated: `6086` - // Minimum execution time: 38_725_000 picoseconds. - Weight::from_parts(39_727_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(5)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -230,11 +224,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `789` // Estimated: `52645` - // Minimum execution time: 56_892_000 picoseconds. - Weight::from_parts(61_941_659, 0) + // Minimum execution time: 56_562_000 picoseconds. + Weight::from_parts(61_452_871, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 8 - .saturating_add(Weight::from_parts(7_580, 0).saturating_mul(n.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-westend/src/weights/pallet_bridge_messages.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs index 1033387b527e..386342d7ea5d 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-07-04, 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 pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_289_000 picoseconds. - Weight::from_parts(42_150_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)) @@ -83,11 +83,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_572_000 picoseconds. - Weight::from_parts(41_033_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: 12_000 - .saturating_add(Weight::from_parts(11_710_588, 0).saturating_mul(n.into())) + // 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)) } @@ -105,8 +105,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 46_655_000 picoseconds. - Weight::from_parts(49_576_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)) @@ -126,11 +126,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `522` // Estimated: `52645` - // Minimum execution time: 40_245_000 picoseconds. - Weight::from_parts(43_461_320, 0) + // Minimum execution time: 39_668_000 picoseconds. + Weight::from_parts(41_908_980, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 21 - .saturating_add(Weight::from_parts(2_246, 0).saturating_mul(n.into())) + // 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)) } @@ -144,17 +144,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 32_001_000 picoseconds. - Weight::from_parts(32_842_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(3)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -166,17 +164,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3822` - // Minimum execution time: 33_287_000 picoseconds. - Weight::from_parts(33_769_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(4)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -188,17 +184,15 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `6086` - // Minimum execution time: 37_136_000 picoseconds. - Weight::from_parts(38_294_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(5)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) /// Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -227,11 +221,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `653` // Estimated: `52645` - // Minimum execution time: 55_942_000 picoseconds. - Weight::from_parts(60_615_769, 0) + // Minimum execution time: 56_465_000 picoseconds. + Weight::from_parts(61_575_775, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 14 - .saturating_add(Weight::from_parts(7_225, 0).saturating_mul(n.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)) }