diff --git a/bridges/bin/runtime-common/src/integrity.rs b/bridges/bin/runtime-common/src/integrity.rs index 3ea5222d2329c..f661db8a22057 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 9f1b985f23e1b..1dfaa5b002856 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 1a20d4b38174e..25278714666cd 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 cfa869df1e72e..6c77fe19d9c4e 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 cb0bcd3d3da4e..0e0450ed1fb67 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 434f4295691e5..6f022533b0a8e 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 e6540dc33af6b..61d30d2aa74da 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