From a9de3b9f6500e5eed334e472281b730ddb03543b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 12 Jan 2021 12:20:40 +0300 Subject: [PATCH] `send_message` weight now depends on message size (#603) * `send_message` weight now depends on message size * fix tests * Update modules/message-lane/src/benchmarking.rs Co-authored-by: Hernando Castano * Update modules/message-lane/src/benchmarking.rs Co-authored-by: Hernando Castano Co-authored-by: Hernando Castano --- bridges/bin/rialto/runtime/src/lib.rs | 20 ++- bridges/modules/call-dispatch/src/lib.rs | 10 +- .../modules/message-lane/src/benchmarking.rs | 126 ++++++++++++++++-- bridges/modules/message-lane/src/lib.rs | 11 +- bridges/modules/message-lane/src/mock.rs | 14 +- bridges/modules/message-lane/src/weights.rs | 95 ++++++++----- .../modules/message-lane/src/weights_ext.rs | 15 ++- bridges/primitives/runtime/src/lib.rs | 9 ++ 8 files changed, 237 insertions(+), 63 deletions(-) diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index be1c66d98ddb..154865c6a03b 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -813,6 +813,8 @@ impl_runtime_apis! { } } + use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge}; + use bridge_runtime_common::messages; use pallet_message_lane::benchmarking::{ Module as MessageLaneBench, Config as MessageLaneConfig, @@ -822,6 +824,10 @@ impl_runtime_apis! { }; impl MessageLaneConfig for Runtime { + fn maximal_message_size() -> u32 { + messages::source::maximal_message_size::() + } + fn bridged_relayer_id() -> Self::InboundRelayer { Default::default() } @@ -840,24 +846,14 @@ impl_runtime_apis! { fn prepare_outbound_message( params: MessageLaneMessageParams, ) -> (millau_messages::ToMillauMessagePayload, Balance) { - use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge}; - use bridge_runtime_common::messages; - use pallet_message_lane::benchmarking::WORST_MESSAGE_SIZE_FACTOR; - - let max_message_size = messages::source::maximal_message_size::(); - let message_size = match params.size_factor { - 0 => 1, - factor => max_message_size / WORST_MESSAGE_SIZE_FACTOR - * sp_std::cmp::min(factor, WORST_MESSAGE_SIZE_FACTOR), - }; - let message_payload = vec![0; message_size as usize]; + let message_payload = vec![0; params.size as usize]; let dispatch_origin = pallet_bridge_call_dispatch::CallOrigin::SourceAccount( params.sender_account, ); let message = ToMillauMessagePayload { spec_version: 0, - weight: message_size as _, + weight: params.size as _, origin: dispatch_origin, call: message_payload, }; diff --git a/bridges/modules/call-dispatch/src/lib.rs b/bridges/modules/call-dispatch/src/lib.rs index 19f1224c906c..74584ee570a8 100644 --- a/bridges/modules/call-dispatch/src/lib.rs +++ b/bridges/modules/call-dispatch/src/lib.rs @@ -25,7 +25,7 @@ #![warn(missing_docs)] use bp_message_dispatch::{MessageDispatch, Weight}; -use bp_runtime::{derive_account_id, InstanceId, SourceAccount}; +use bp_runtime::{derive_account_id, InstanceId, Size, SourceAccount}; use codec::{Decode, Encode}; use frame_support::{ decl_event, decl_module, decl_storage, @@ -104,6 +104,14 @@ pub struct MessagePayload Size + for MessagePayload> +{ + fn size_hint(&self) -> u32 { + self.call.len() as _ + } +} + /// The module configuration trait. pub trait Config: frame_system::Config { /// The overarching event type. diff --git a/bridges/modules/message-lane/src/benchmarking.rs b/bridges/modules/message-lane/src/benchmarking.rs index d1aef1140b8d..3243a25f1631 100644 --- a/bridges/modules/message-lane/src/benchmarking.rs +++ b/bridges/modules/message-lane/src/benchmarking.rs @@ -27,8 +27,6 @@ use frame_support::{traits::Get, weights::Weight}; use frame_system::RawOrigin; use sp_std::{collections::btree_map::BTreeMap, convert::TryInto, ops::RangeInclusive, prelude::*}; -/// Message crafted with this size factor should be the largest possible message. -pub const WORST_MESSAGE_SIZE_FACTOR: u32 = 1000; /// Fee paid by submitter for single message delivery. const MESSAGE_FEE: u32 = 1_000_000; @@ -39,10 +37,8 @@ pub struct Module, I: crate::Instance>(crate::Module); /// Benchmark-specific message parameters. pub struct MessageParams { - /// Size factor of the message payload. Message payload grows with every factor - /// increment. Zero is the smallest possible message and the `WORST_MESSAGE_SIZE_FACTOR` is - /// largest possible message. - pub size_factor: u32, + /// Size of the message payload. + pub size: u32, /// Message sender account. pub sender_account: ThisAccountId, } @@ -67,6 +63,8 @@ pub struct MessageDeliveryProofParams { /// Trait that must be implemented by runtime. pub trait Config: crate::Config { + /// Get maximal size of the message payload. + fn maximal_message_size() -> u32; /// Return id of relayer account at the bridged chain. fn bridged_relayer_id() -> Self::InboundRelayer; /// Return balance of given account. @@ -101,10 +99,12 @@ benchmarks_instance! { // * outbound lane already has state, so it needs to be read and decoded; // * relayers fund account does not exists (in practice it needs to exist in production environment); // * maximal number of messages is being pruned during the call; - // * message size is maximal for the target chain. + // * message size is minimal for the target chain. // - // Results of this benchmark may be directly used in the `send_message`. - send_message_worst_case { + // Result of this benchmark is used as a base weight for `send_message` call. Then the 'message weight' + // (estimated using `send_half_maximal_message_worst_case` and `send_maximal_message_worst_case`) is + // added. + send_minimal_message_worst_case { let lane_id = bench_lane_id(); let sender = account("sender", 0, SEED); T::endow_account(&sender); @@ -116,7 +116,81 @@ benchmarks_instance! { confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); let (payload, fee) = T::prepare_outbound_message(MessageParams { - size_factor: WORST_MESSAGE_SIZE_FACTOR, + size: 0, + sender_account: sender.clone(), + }); + }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) + verify { + assert_eq!( + crate::Module::::outbound_latest_generated_nonce(bench_lane_id()), + T::MaxMessagesToPruneAtOnce::get() + 1, + ); + } + + // Benchmark `send_message` extrinsic with the worst possible conditions: + // * outbound lane already has state, so it needs to be read and decoded; + // * relayers fund account does not exists (in practice it needs to exist in production environment); + // * maximal number of messages is being pruned during the call; + // * message size is 1KB. + // + // With single KB of message size, the weight of the call is increased (roughly) by + // `(send_16_kb_message_worst_case - send_1_kb_message_worst_case) / 15`. + send_1_kb_message_worst_case { + let lane_id = bench_lane_id(); + let sender = account("sender", 0, SEED); + T::endow_account(&sender); + + // 'send' messages that are to be pruned when our message is sent + for _nonce in 1..=T::MaxMessagesToPruneAtOnce::get() { + send_regular_message::(); + } + confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); + + let size = 1024; + assert!( + T::maximal_message_size() > size, + "This benchmark can only be used with runtime that accepts 1KB messages", + ); + + let (payload, fee) = T::prepare_outbound_message(MessageParams { + size, + sender_account: sender.clone(), + }); + }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) + verify { + assert_eq!( + crate::Module::::outbound_latest_generated_nonce(bench_lane_id()), + T::MaxMessagesToPruneAtOnce::get() + 1, + ); + } + + // Benchmark `send_message` extrinsic with the worst possible conditions: + // * outbound lane already has state, so it needs to be read and decoded; + // * relayers fund account does not exists (in practice it needs to exist in production environment); + // * maximal number of messages is being pruned during the call; + // * message size is 16KB. + // + // With single KB of message size, the weight of the call is increased (roughly) by + // `(send_16_kb_message_worst_case - send_1_kb_message_worst_case) / 15`. + send_16_kb_message_worst_case { + let lane_id = bench_lane_id(); + let sender = account("sender", 0, SEED); + T::endow_account(&sender); + + // 'send' messages that are to be pruned when our message is sent + for _nonce in 1..=T::MaxMessagesToPruneAtOnce::get() { + send_regular_message::(); + } + confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); + + let size = 16 * 1024; + assert!( + T::maximal_message_size() > size, + "This benchmark can only be used with runtime that accepts 16KB messages", + ); + + let (payload, fee) = T::prepare_outbound_message(MessageParams { + size, sender_account: sender.clone(), }); }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) @@ -340,6 +414,38 @@ benchmarks_instance! { // Benchmarks for manual checks. // + // Benchmark `send_message` extrinsic with following conditions: + // * outbound lane already has state, so it needs to be read and decoded; + // * relayers fund account does not exists (in practice it needs to exist in production environment); + // * maximal number of messages is being pruned during the call; + // * message size varies from minimal to maximal for the target chain. + // + // Results of this benchmark may be used to check how message size affects `send_message` performance. + send_messages_of_various_lengths { + let i in 0..T::maximal_message_size().try_into().unwrap_or_default(); + + let lane_id = bench_lane_id(); + let sender = account("sender", 0, SEED); + T::endow_account(&sender); + + // 'send' messages that are to be pruned when our message is sent + for _nonce in 1..=T::MaxMessagesToPruneAtOnce::get() { + send_regular_message::(); + } + confirm_message_delivery::(T::MaxMessagesToPruneAtOnce::get()); + + let (payload, fee) = T::prepare_outbound_message(MessageParams { + size: i as _, + sender_account: sender.clone(), + }); + }: send_message(RawOrigin::Signed(sender), lane_id, payload, fee) + verify { + assert_eq!( + crate::Module::::outbound_latest_generated_nonce(bench_lane_id()), + T::MaxMessagesToPruneAtOnce::get() + 1, + ); + } + // Benchmark `receive_messages_proof` extrinsic with multiple 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; diff --git a/bridges/modules/message-lane/src/lib.rs b/bridges/modules/message-lane/src/lib.rs index 9840048f0053..88dd033cbcac 100644 --- a/bridges/modules/message-lane/src/lib.rs +++ b/bridges/modules/message-lane/src/lib.rs @@ -39,7 +39,6 @@ pub use crate::weights_ext::{ensure_weights_are_correct, WeightInfoExt}; use crate::inbound_lane::{InboundLane, InboundLaneStorage}; use crate::outbound_lane::{OutboundLane, OutboundLaneStorage}; -use crate::weights::WeightInfo; use bp_message_lane::{ source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain}, @@ -47,6 +46,7 @@ use bp_message_lane::{ total_unrewarded_messages, InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, UnrewardedRelayersState, }; +use bp_runtime::Size; use codec::{Decode, Encode}; use frame_support::{ decl_error, decl_event, decl_module, decl_storage, ensure, @@ -104,7 +104,7 @@ pub trait Config: frame_system::Config { type MaxUnconfirmedMessagesAtInboundLane: Get; /// Payload type of outbound messages. This payload is dispatched on the bridged chain. - type OutboundPayload: Parameter; + type OutboundPayload: Parameter + Size; /// Message fee type of outbound messages. This fee is paid on this chain. type OutboundMessageFee: From + Parameter + SaturatingAdd + Zero; @@ -261,10 +261,9 @@ decl_module! { } /// Send message over lane. - /// - /// The weight of the call assumes that the largest possible message is sent in - /// worst possible environment. - #[weight = T::WeightInfo::send_message_worst_case()] + #[weight = T::WeightInfo::send_message_overhead() + .saturating_add(T::WeightInfo::send_message_size_overhead(Size::size_hint(payload))) + ] pub fn send_message( origin, lane_id: LaneId, diff --git a/bridges/modules/message-lane/src/mock.rs b/bridges/modules/message-lane/src/mock.rs index 59ca1ab0b769..f4d98f4c6dc4 100644 --- a/bridges/modules/message-lane/src/mock.rs +++ b/bridges/modules/message-lane/src/mock.rs @@ -21,6 +21,7 @@ use bp_message_lane::{ target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, }; +use bp_runtime::Size; use codec::{Decode, Encode}; use frame_support::{impl_outer_event, impl_outer_origin, parameter_types, weights::Weight}; use sp_core::H256; @@ -32,7 +33,8 @@ use sp_runtime::{ use std::collections::BTreeMap; pub type AccountId = u64; -pub type TestPayload = (u64, Weight); +#[derive(Decode, Encode, Clone, Debug, PartialEq, Eq)] +pub struct TestPayload(pub u64, pub Weight); pub type TestMessageFee = u64; pub type TestRelayer = u64; @@ -123,6 +125,12 @@ impl Config for TestRuntime { type MessageDispatch = TestMessageDispatch; } +impl Size for TestPayload { + fn size_hint(&self) -> u32 { + 16 + } +} + /// Account id of test relayer. pub const TEST_RELAYER_A: AccountId = 100; @@ -139,10 +147,10 @@ pub const TEST_ERROR: &str = "Test error"; pub const TEST_LANE_ID: LaneId = [0, 0, 0, 1]; /// Regular message payload. -pub const REGULAR_PAYLOAD: TestPayload = (0, 50); +pub const REGULAR_PAYLOAD: TestPayload = TestPayload(0, 50); /// Payload that is rejected by `TestTargetHeaderChain`. -pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = (1, 50); +pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = TestPayload(1, 50); /// Vec of proved messages, grouped by lane. pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages>)>; diff --git a/bridges/modules/message-lane/src/weights.rs b/bridges/modules/message-lane/src/weights.rs index d819e5d57443..016af708a66b 100644 --- a/bridges/modules/message-lane/src/weights.rs +++ b/bridges/modules/message-lane/src/weights.rs @@ -17,7 +17,7 @@ //! Autogenerated weights for pallet_message_lane //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-12-22, STEPS: [50, ], REPEAT: 20 +//! DATE: 2020-12-28, STEPS: [50, ], REPEAT: 20 //! LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled //! CHAIN: Some("local"), DB CACHE: 128 @@ -48,13 +48,16 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_message_lane. pub trait WeightInfo { - fn send_message_worst_case() -> Weight; + fn send_minimal_message_worst_case() -> Weight; + fn send_1_kb_message_worst_case() -> Weight; + fn send_16_kb_message_worst_case() -> Weight; fn receive_single_message_proof() -> Weight; fn receive_two_messages_proof() -> Weight; fn receive_single_message_proof_with_outbound_lane_state() -> 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 send_messages_of_various_lengths(i: u32) -> Weight; fn receive_multiple_messages_proof(i: u32) -> Weight; fn receive_multiple_messages_proof_with_outbound_lane_state(i: u32) -> Weight; fn receive_delivery_proof_for_multiple_messages_by_single_relayer(i: u32) -> Weight; @@ -64,63 +67,79 @@ pub trait WeightInfo { /// Weights for pallet_message_lane using the Rialto node and recommended hardware. pub struct RialtoWeight(PhantomData); impl WeightInfo for RialtoWeight { - fn send_message_worst_case() -> Weight { - (4_289_189_000 as Weight) + fn send_minimal_message_worst_case() -> Weight { + (249_486_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(12 as Weight)) + } + fn send_1_kb_message_worst_case() -> Weight { + (257_454_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(12 as Weight)) + } + fn send_16_kb_message_worst_case() -> Weight { + (344_817_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(12 as Weight)) } fn receive_single_message_proof() -> Weight { - (186_909_000 as Weight) + (197_341_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn receive_two_messages_proof() -> Weight { - (339_281_000 as Weight) + (341_056_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn receive_single_message_proof_with_outbound_lane_state() -> Weight { - (215_607_000 as Weight) + (227_735_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn receive_delivery_proof_for_single_message() -> Weight { - (202_085_000 as Weight) + (208_305_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { - (213_142_000 as Weight) + (239_511_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { - (300_159_000 as Weight) + (341_307_000 as Weight) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } + fn send_messages_of_various_lengths(i: u32) -> Weight { + (206_352_000 as Weight) + .saturating_add((5_000 as Weight).saturating_mul(i as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(12 as Weight)) + } fn receive_multiple_messages_proof(i: u32) -> Weight { (0 as Weight) - .saturating_add((150_558_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((157_613_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn receive_multiple_messages_proof_with_outbound_lane_state(i: u32) -> Weight { (0 as Weight) - .saturating_add((204_949_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((166_416_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn receive_delivery_proof_for_multiple_messages_by_single_relayer(i: u32) -> Weight { - (79_087_000 as Weight) - .saturating_add((12_889_000 as Weight).saturating_mul(i as Weight)) + (107_561_000 as Weight) + .saturating_add((12_218_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight))) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn receive_delivery_proof_for_multiple_messages_by_multiple_relayers(i: u32) -> Weight { - (131_794_000 as Weight) - .saturating_add((108_620_000 as Weight).saturating_mul(i as Weight)) + (124_619_000 as Weight) + .saturating_add((104_750_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(i as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) @@ -130,63 +149,79 @@ impl WeightInfo for RialtoWeight { // For backwards compatibility and tests impl WeightInfo for () { - fn send_message_worst_case() -> Weight { - (4_289_189_000 as Weight) + fn send_minimal_message_worst_case() -> Weight { + (249_486_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(12 as Weight)) + } + fn send_1_kb_message_worst_case() -> Weight { + (257_454_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(12 as Weight)) + } + fn send_16_kb_message_worst_case() -> Weight { + (344_817_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(12 as Weight)) } fn receive_single_message_proof() -> Weight { - (186_909_000 as Weight) + (197_341_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn receive_two_messages_proof() -> Weight { - (339_281_000 as Weight) + (341_056_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn receive_single_message_proof_with_outbound_lane_state() -> Weight { - (215_607_000 as Weight) + (227_735_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn receive_delivery_proof_for_single_message() -> Weight { - (202_085_000 as Weight) + (208_305_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { - (213_142_000 as Weight) + (239_511_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { - (300_159_000 as Weight) + (341_307_000 as Weight) .saturating_add(RocksDbWeight::get().reads(8 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } + fn send_messages_of_various_lengths(i: u32) -> Weight { + (206_352_000 as Weight) + .saturating_add((5_000 as Weight).saturating_mul(i as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(12 as Weight)) + } fn receive_multiple_messages_proof(i: u32) -> Weight { (0 as Weight) - .saturating_add((150_558_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((157_613_000 as Weight).saturating_mul(i as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn receive_multiple_messages_proof_with_outbound_lane_state(i: u32) -> Weight { (0 as Weight) - .saturating_add((204_949_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((166_416_000 as Weight).saturating_mul(i as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn receive_delivery_proof_for_multiple_messages_by_single_relayer(i: u32) -> Weight { - (79_087_000 as Weight) - .saturating_add((12_889_000 as Weight).saturating_mul(i as Weight)) + (107_561_000 as Weight) + .saturating_add((12_218_000 as Weight).saturating_mul(i as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(i as Weight))) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn receive_delivery_proof_for_multiple_messages_by_multiple_relayers(i: u32) -> Weight { - (131_794_000 as Weight) - .saturating_add((108_620_000 as Weight).saturating_mul(i as Weight)) + (124_619_000 as Weight) + .saturating_add((104_750_000 as Weight).saturating_mul(i as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(i as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) diff --git a/bridges/modules/message-lane/src/weights_ext.rs b/bridges/modules/message-lane/src/weights_ext.rs index 5e1f1c88615c..b9b33a6f21f9 100644 --- a/bridges/modules/message-lane/src/weights_ext.rs +++ b/bridges/modules/message-lane/src/weights_ext.rs @@ -23,7 +23,8 @@ use frame_support::weights::Weight; /// Ensure that weights from `WeightInfoExt` implementation are looking correct. pub fn ensure_weights_are_correct() { - assert_ne!(W::send_message_worst_case(), 0); + assert_ne!(W::send_message_overhead(), 0); + assert_ne!(W::send_message_size_overhead(0), 0); assert_ne!(W::receive_messages_proof_overhead(), 0); assert_ne!(W::receive_messages_proof_messages_overhead(1), 0); @@ -36,6 +37,18 @@ pub fn ensure_weights_are_correct() { /// Extended weight info. pub trait WeightInfoExt: WeightInfo { + /// Returns weight of message send transaction (`send_message`). + fn send_message_overhead() -> Weight { + Self::send_minimal_message_worst_case() + } + + /// Returns weight that needs to be accounted when message of given size is sent (`send_message`). + fn send_message_size_overhead(message_size: u32) -> Weight { + let message_size_in_kb = (1024u64 + message_size as u64) / 1024; + let single_kb_weight = (Self::send_16_kb_message_worst_case() - Self::send_1_kb_message_worst_case()) / 15; + message_size_in_kb * single_kb_weight + } + /// 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); diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index e23a8d887cec..b0a352b7dd2c 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -95,3 +95,12 @@ where pub fn derive_relayer_fund_account_id(bridge_id: InstanceId) -> H256 { ("relayer-fund-account", bridge_id).using_encoded(blake2_256).into() } + +/// Anything that has size. +pub trait Size { + /// Return approximate size of this object (in bytes). + /// + /// This function should be lightweight. The result should not necessary be absolutely + /// accurate. + fn size_hint(&self) -> u32; +}