diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 2067dfccb562..66d78fc3c810 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -1036,6 +1036,7 @@ impl_runtime_apis! { ]; use bridge_runtime_common::messages_benchmarking::{ + generate_xcm_builder_bridge_message_sample, prepare_message_delivery_proof_from_grandpa_chain, prepare_message_delivery_proof_from_parachain, prepare_message_proof_from_grandpa_chain, @@ -1070,7 +1071,7 @@ impl_runtime_apis! { Runtime, WithRialtoParachainsInstance, WithRialtoParachainMessageBridge, - >(params, xcm::v3::Junctions::Here) + >(params, generate_xcm_builder_bridge_message_sample(xcm::v3::Junctions::Here)) } fn prepare_message_delivery_proof( @@ -1101,7 +1102,7 @@ impl_runtime_apis! { Runtime, RialtoGrandpaInstance, WithRialtoMessageBridge, - >(params, xcm::v3::Junctions::Here) + >(params, generate_xcm_builder_bridge_message_sample(xcm::v3::Junctions::Here)) } fn prepare_message_delivery_proof( diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index 60f4bb17858c..d80a88f1068c 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -29,7 +29,7 @@ use crate::{ }, }; -use bp_messages::storage_keys; +use bp_messages::{storage_keys, MessagePayload}; use bp_polkadot_core::parachains::ParaHash; use bp_runtime::{ record_all_trie_keys, Chain, Parachain, RawStorageProof, StorageProofSize, UnderlyingChainOf, @@ -45,8 +45,8 @@ use xcm::v3::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. fn prepare_inbound_message( params: &MessageProofParams, - destination: InteriorMultiLocation, -) -> Vec { + 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, @@ -58,20 +58,15 @@ fn prepare_inbound_message( return vec![0u8; expected_size] } - // else let's prepare successful message. For XCM bridge hubs, it is the message that - // will be pushed further to some XCM queue (XCMP/UMP) - let location = xcm::VersionedInteriorMultiLocation::V3(destination); - let location_encoded_size = location.encoded_size(); - - // we don't need to be super-precise with `expected_size` here - let xcm_size = expected_size.saturating_sub(location_encoded_size); - let xcm = xcm::VersionedXcm::<()>::V3(vec![Instruction::ClearOrigin; xcm_size].into()); - - // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor - // or public fields, so just tuple - // (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed - // to the storage) - (location, xcm).encode().encode() + // else let's prepare successful message. + let msg = successful_dispatch_message_generator(expected_size); + assert!( + msg.len() >= expected_size, + "msg.len(): {} does not match expected_size: {}", + expected_size, + msg.len() + ); + msg } /// Prepare proof of messages for the `receive_messages_proof` call. @@ -84,7 +79,7 @@ fn prepare_inbound_message( /// function. pub fn prepare_message_proof_from_grandpa_chain( params: MessageProofParams, - message_destination: InteriorMultiLocation, + message_generator: impl Fn(usize) -> MessagePayload, ) -> (FromBridgedChainMessagesProof>>, Weight) where R: pallet_bridge_grandpa::Config>>, @@ -97,7 +92,7 @@ where params.message_nonces.clone(), params.outbound_lane_data.clone(), params.size, - prepare_inbound_message(¶ms, message_destination), + prepare_inbound_message(¶ms, message_generator), encode_all_messages, encode_lane_data, ); @@ -127,7 +122,7 @@ where /// `prepare_message_proof_from_grandpa_chain` function. pub fn prepare_message_proof_from_parachain( params: MessageProofParams, - message_destination: InteriorMultiLocation, + message_generator: impl Fn(usize) -> MessagePayload, ) -> (FromBridgedChainMessagesProof>>, Weight) where R: pallet_bridge_parachains::Config, @@ -141,7 +136,7 @@ where params.message_nonces.clone(), params.outbound_lane_data.clone(), params.size, - prepare_inbound_message(¶ms, message_destination), + prepare_inbound_message(¶ms, message_generator), encode_all_messages, encode_lane_data, ); @@ -291,3 +286,53 @@ where pallet_bridge_parachains::initialize_for_benchmarks::(bridged_header); (bridged_block_number, bridged_header_hash) } + +/// Returns callback which generates `BridgeMessage` from Polkadot XCM builder based on +/// `expected_message_size` for benchmark. +pub fn generate_xcm_builder_bridge_message_sample( + destination: InteriorMultiLocation, +) -> impl Fn(usize) -> MessagePayload { + move |expected_message_size| -> MessagePayload { + // For XCM bridge hubs, it is the message that + // will be pushed further to some XCM queue (XCMP/UMP) + let location = xcm::VersionedInteriorMultiLocation::V3(destination); + let location_encoded_size = location.encoded_size(); + + // we don't need to be super-precise with `expected_size` here + let xcm_size = expected_message_size.saturating_sub(location_encoded_size); + let xcm_data_size = xcm_size.saturating_sub( + // minus empty instruction size + xcm::v3::Instruction::<()>::ExpectPallet { + index: 0, + name: vec![], + module_name: vec![], + crate_major: 0, + min_crate_minor: 0, + } + .encoded_size(), + ); + + log::trace!( + target: "runtime::bridge-benchmarks", + "generate_xcm_builder_bridge_message_sample with expected_message_size: {}, location_encoded_size: {}, xcm_size: {}, xcm_data_size: {}", + expected_message_size, location_encoded_size, xcm_size, xcm_data_size, + ); + + let xcm = xcm::VersionedXcm::<()>::V3( + vec![xcm::v3::Instruction::<()>::ExpectPallet { + index: 0, + name: vec![42; xcm_data_size], + module_name: vec![], + crate_major: 0, + min_crate_minor: 0, + }] + .into(), + ); + + // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor + // or public fields, so just tuple + // (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed + // to the storage) + (location, xcm).encode().encode() + } +} diff --git a/bridges/modules/messages/src/weights_ext.rs b/bridges/modules/messages/src/weights_ext.rs index 1be24a738a49..aeb3a581a69e 100644 --- a/bridges/modules/messages/src/weights_ext.rs +++ b/bridges/modules/messages/src/weights_ext.rs @@ -29,8 +29,8 @@ pub const EXPECTED_DEFAULT_MESSAGE_LENGTH: u32 = 128; /// calls we're checking here would fit 1KB. const SIGNED_EXTENSIONS_SIZE: u32 = 1024; -/// Number of extra bytes (excluding size of storage value itself) of storage proof, built at -/// Rialto chain. This mostly depends on number of entries (and their density) in the storage trie. +/// Number of extra bytes (excluding size of storage value itself) of storage proof. +/// This mostly depends on number of entries (and their density) in the storage trie. /// Some reserve is reserved to account future chain growth. pub const EXTRA_STORAGE_PROOF_SIZE: u32 = 1024;