Benchmarks for message delivery transaction (#567)

* benchmarks for pallet_message_lane::receive_messages_proof

* use CallOrigin::TargetAccount (worst case of CallOrigin)

* fmt

* closures

* Update modules/message-lane/src/benchmarking.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update modules/message-lane/src/benchmarking.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* fix compilation

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
Svyatoslav Nikolsky
2020-12-16 15:40:16 +03:00
committed by Bastian Köcher
parent f26775d690
commit 6317a31e25
11 changed files with 479 additions and 18 deletions
+1
View File
@@ -115,6 +115,7 @@ std = [
"sp-version/std",
]
runtime-benchmarks = [
"bridge-runtime-common/runtime-benchmarks",
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
+75 -1
View File
@@ -806,9 +806,14 @@ impl_runtime_apis! {
Module as MessageLaneBench,
Config as MessageLaneConfig,
MessageParams as MessageLaneMessageParams,
MessageProofParams as MessageLaneMessageProofParams,
};
impl MessageLaneConfig<WithMillauMessageLaneInstance> for Runtime {
fn bridged_relayer_id() -> Self::InboundRelayer {
Default::default()
}
fn endow_account(account: &Self::AccountId) {
pallet_balances::Module::<Runtime>::make_free_balance_be(
account,
@@ -816,7 +821,7 @@ impl_runtime_apis! {
);
}
fn prepare_message(
fn prepare_outbound_message(
params: MessageLaneMessageParams<Self::AccountId>,
) -> (millau_messages::ToMillauMessagePayload, Balance) {
use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge};
@@ -842,6 +847,75 @@ impl_runtime_apis! {
};
(message, 1_000_000_000)
}
fn prepare_message_proof(
params: MessageLaneMessageProofParams,
) -> (millau_messages::FromMillauMessagesProof, Weight) {
use crate::millau_messages::{Millau, WithMillauMessageBridge};
use bp_message_lane::MessageKey;
use bridge_runtime_common::{
messages::ChainWithMessageLanes,
messages_benchmarking::{ed25519_sign, prepare_message_proof},
};
use codec::Encode;
use frame_support::weights::GetDispatchInfo;
use pallet_message_lane::storage_keys;
use sp_runtime::traits::Header;
let call = Call::System(SystemCall::remark(vec![]));
let call_weight = call.get_dispatch_info().weight;
let millau_account_id: bp_millau::AccountId = Default::default();
let (rialto_raw_public, rialto_raw_signature) = ed25519_sign(
&call,
&millau_account_id,
);
let rialto_public = MultiSigner::Ed25519(sp_core::ed25519::Public::from_raw(rialto_raw_public));
let rialto_signature = MultiSignature::Ed25519(sp_core::ed25519::Signature::from_raw(
rialto_raw_signature,
));
let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key::<
Runtime,
<Millau as ChainWithMessageLanes>::MessageLaneInstance,
>(
&message_key.lane_id, message_key.nonce,
).0;
let make_millau_outbound_lane_data_key = |lane_id| storage_keys::outbound_lane_data_key::<
<Millau as ChainWithMessageLanes>::MessageLaneInstance,
>(
&lane_id,
).0;
let make_millau_header = |state_root| bp_millau::Header::new(
0,
Default::default(),
state_root,
Default::default(),
Default::default(),
);
prepare_message_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, _, _, _>(
params,
make_millau_message_key,
make_millau_outbound_lane_data_key,
make_millau_header,
call_weight,
pallet_bridge_call_dispatch::MessagePayload {
spec_version: VERSION.spec_version,
weight: call_weight,
origin: pallet_bridge_call_dispatch::CallOrigin::<
bp_millau::AccountId,
MultiSigner,
Signature,
>::TargetAccount(
millau_account_id,
rialto_public,
rialto_signature,
),
call: call.encode(),
}.encode(),
)
}
}
add_benchmark!(params, batches, pallet_bridge_eth_poa, BridgeKovan);
@@ -71,7 +71,7 @@ pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDi
>;
/// Messages proof for Millau -> Rialto messages.
type FromMillauMessagesProof = messages::target::FromBridgedChainMessagesProof<WithMillauMessageBridge>;
pub type FromMillauMessagesProof = messages::target::FromBridgedChainMessagesProof<WithMillauMessageBridge>;
/// Messages delivery proof for Rialto -> Millau messages.
type ToMillauMessagesDeliveryProof = messages::source::FromBridgedChainMessagesDeliveryProof<WithMillauMessageBridge>;
+11
View File
@@ -9,6 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] }
ed25519-dalek = { version = "1.0", default-features = false, optional = true }
hash-db = { version = "0.15.2", default-features = false }
# Bridge dependencies
@@ -23,7 +24,9 @@ pallet-substrate-bridge = { path = "../../modules/substrate", default-features =
# Substrate dependencies
frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "master" , default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "master" , default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "master" , default-features = false }
sp-state-machine = { git = "https://github.com/paritytech/substrate.git", branch = "master" , default-features = false, optional = true }
sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "master" , default-features = false }
sp-trie = { git = "https://github.com/paritytech/substrate.git", branch = "master" , default-features = false }
@@ -39,7 +42,15 @@ std = [
"pallet-bridge-call-dispatch/std",
"pallet-message-lane/std",
"pallet-substrate-bridge/std",
"sp-core/std",
"sp-runtime/std",
"sp-state-machine/std",
"sp-std/std",
"sp-trie/std",
]
runtime-benchmarks = [
"ed25519-dalek/u64_backend",
"pallet-message-lane/runtime-benchmarks",
"pallet-substrate-bridge/runtime-benchmarks",
"sp-state-machine",
]
+1
View File
@@ -19,3 +19,4 @@
#![cfg_attr(not(feature = "std"), no_std)]
pub mod messages;
pub mod messages_benchmarking;
+9 -3
View File
@@ -27,7 +27,7 @@ use bp_message_lane::{
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
};
use bp_runtime::InstanceId;
use codec::{Compact, Decode, Input};
use codec::{Compact, Decode, Encode, Input};
use frame_support::{traits::Instance, RuntimeDebug};
use hash_db::Hasher;
use pallet_substrate_bridge::StorageProofChecker;
@@ -96,14 +96,14 @@ pub trait ChainWithMessageLanes {
/// Signature type used on the chain.
type Signature: Decode;
/// Call type on the chain.
type Call: Decode;
type Call: Encode + Decode;
/// Type of weight that is used on the chain. This would almost always be a regular
/// `frame_support::weight::Weight`. But since the meaning of weight on different chains
/// may be different, the `WeightOf<>` construct is used to avoid confusion between
/// different weights.
type Weight: From<frame_support::weights::Weight> + PartialOrd;
/// Type of balances that is used on the chain.
type Balance: Decode + CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy;
type Balance: Encode + Decode + CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy;
/// Instance of the message-lane pallet.
type MessageLaneInstance: Instance;
@@ -327,6 +327,12 @@ pub mod target {
/// Message payload for Bridged -> This messages.
pub struct FromBridgedChainMessagePayload<B: MessageBridge>(pub(crate) FromBridgedChainDecodedMessagePayload<B>);
impl<B: MessageBridge> From<FromBridgedChainDecodedMessagePayload<B>> for FromBridgedChainMessagePayload<B> {
fn from(decoded_payload: FromBridgedChainDecodedMessagePayload<B>) -> Self {
Self(decoded_payload)
}
}
impl<B: MessageBridge> Decode for FromBridgedChainMessagePayload<B> {
fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
// for bridged chain our Calls are opaque - they're encoded to Vec<u8> by submitter
@@ -0,0 +1,144 @@
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Everything required to run benchmarks of message-lanes, based on
//! `bridge_runtime_common::messages` implementation.
#![cfg(feature = "runtime-benchmarks")]
use crate::messages::{target::FromBridgedChainMessagesProof, BalanceOf, BridgedChain, HashOf, MessageBridge};
use bp_message_lane::{LaneId, MessageData, MessageKey, MessagePayload};
use codec::Encode;
use ed25519_dalek::{PublicKey, SecretKey, Signer, KEYPAIR_LENGTH, SECRET_KEY_LENGTH};
use frame_support::weights::Weight;
use pallet_message_lane::benchmarking::MessageProofParams;
use sp_core::Hasher;
use sp_runtime::traits::Header;
use sp_std::prelude::*;
use sp_trie::{read_trie_value_with, trie_types::TrieDBMut, Layout, MemoryDB, Recorder, StorageProof, TrieMut};
/// Generate ed25519 signature to be used in `pallet_brdige_call_dispatch::CallOrigin::TargetAccount`.
///
/// Returns public key of the signer and the signature itself.
pub fn ed25519_sign(target_call: &impl Encode, source_account_id: &impl Encode) -> ([u8; 32], [u8; 64]) {
// key from the repo example (https://docs.rs/ed25519-dalek/1.0.1/ed25519_dalek/struct.SecretKey.html)
let target_secret = SecretKey::from_bytes(&[
157, 097, 177, 157, 239, 253, 090, 096, 186, 132, 074, 244, 146, 236, 044, 196, 068, 073, 197, 105, 123, 050,
105, 025, 112, 059, 172, 003, 028, 174, 127, 096,
])
.expect("harcoded key is valid");
let target_public: PublicKey = (&target_secret).into();
let mut target_pair_bytes = [0u8; KEYPAIR_LENGTH];
target_pair_bytes[..SECRET_KEY_LENGTH].copy_from_slice(&target_secret.to_bytes());
target_pair_bytes[SECRET_KEY_LENGTH..].copy_from_slice(&target_public.to_bytes());
let target_pair = ed25519_dalek::Keypair::from_bytes(&target_pair_bytes).expect("hardcoded pair is valid");
let mut signature_message = Vec::new();
target_call.encode_to(&mut signature_message);
source_account_id.encode_to(&mut signature_message);
let target_origin_signature = target_pair
.try_sign(&signature_message)
.expect("Ed25519 try_sign should not fail in benchmarks");
(target_public.to_bytes(), target_origin_signature.to_bytes())
}
/// Prepare proof of messages for the `receive_messages_proof` call.
pub fn prepare_message_proof<B, H, R, MM, ML, MH>(
params: MessageProofParams,
make_bridged_message_storage_key: MM,
make_bridged_outbound_lane_data_key: ML,
make_bridged_header: MH,
message_dispatch_weight: Weight,
message_payload: MessagePayload,
) -> (FromBridgedChainMessagesProof<B>, Weight)
where
B: MessageBridge,
H: Hasher,
R: pallet_substrate_bridge::Config,
<R::BridgedChain as bp_runtime::Chain>::Hash: Into<HashOf<BridgedChain<B>>>,
MM: Fn(MessageKey) -> Vec<u8>,
ML: Fn(LaneId) -> Vec<u8>,
MH: Fn(H::Out) -> <R::BridgedChain as bp_runtime::Chain>::Header,
{
// prepare Bridged chain storage with messages and (optionally) outbound lane state
let message_count = params
.message_nonces
.end()
.saturating_sub(*params.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 = TrieDBMut::<H>::new(&mut mdb, &mut root);
// insert messages
for nonce in params.message_nonces.clone() {
let message_key = MessageKey {
lane_id: params.lane,
nonce,
};
let message_data = MessageData {
fee: BalanceOf::<BridgedChain<B>>::from(0),
payload: message_payload.clone(),
};
let storage_key = make_bridged_message_storage_key(message_key);
trie.insert(&storage_key, &message_data.encode())
.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) = params.outbound_lane_data {
let storage_key = make_bridged_outbound_lane_data_key(params.lane);
trie.insert(&storage_key, &outbound_lane_data.encode())
.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 proof_recorder = Recorder::<H::Out>::new();
for storage_key in storage_keys {
read_trie_value_with::<Layout<H>, _, _>(&mdb, &root, &storage_key, &mut proof_recorder)
.map_err(|_| "read_trie_value_with has failed")
.expect("read_trie_value_with should not fail in benchmarks");
}
let storage_proof = proof_recorder.drain().into_iter().map(|n| n.data.to_vec()).collect();
// prepare Bridged chain header and insert it into the Substrate pallet
let bridged_header = make_bridged_header(root);
let bridged_header_hash = bridged_header.hash();
pallet_substrate_bridge::initialize_for_benchmarks::<R>(bridged_header);
(
(
bridged_header_hash.into(),
StorageProof::new(storage_proof),
params.lane,
*params.message_nonces.start(),
*params.message_nonces.end(),
),
message_dispatch_weight
.checked_mul(message_count)
.expect("too many messages requested by benchmark"),
)
}
+217 -11
View File
@@ -16,14 +16,16 @@
//! Message lane pallet benchmarking.
use crate::{Call, Instance};
use crate::{inbound_lane::InboundLaneStorage, inbound_lane_storage, outbound_lane, Call, Instance};
use bp_message_lane::{LaneId, MessageData, MessageNonce};
use bp_message_lane::{
target_chain::SourceHeaderChain, InboundLaneData, LaneId, MessageData, MessageNonce, OutboundLaneData,
};
use frame_benchmarking::{account, benchmarks_instance};
use frame_support::traits::Get;
use frame_support::{traits::Get, weights::Weight};
use frame_system::RawOrigin;
use num_traits::Zero;
use sp_std::prelude::*;
use sp_std::{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;
@@ -43,27 +45,52 @@ pub struct MessageParams<ThisAccountId> {
pub sender_account: ThisAccountId,
}
/// Benchmark-specific message proof parameters.
pub struct MessageProofParams {
/// Id of the lane.
pub lane: LaneId,
/// Range of messages to include in the proof.
pub message_nonces: RangeInclusive<MessageNonce>,
/// If `Some`, the proof needs to include this outbound lane data.
pub outbound_lane_data: Option<OutboundLaneData>,
}
/// Trait that must be implemented by runtime.
pub trait Config<I: Instance>: crate::Config<I> {
/// Return id of relayer account at the bridged chain.
fn bridged_relayer_id() -> Self::InboundRelayer;
/// Create given account and give it enough balance for test purposes.
fn endow_account(account: &Self::AccountId);
/// Prepare message to send over lane.
fn prepare_message(params: MessageParams<Self::AccountId>) -> (Self::OutboundPayload, Self::OutboundMessageFee);
fn prepare_outbound_message(
params: MessageParams<Self::AccountId>,
) -> (Self::OutboundPayload, Self::OutboundMessageFee);
/// Prepare messages proof to receive by the module.
fn prepare_message_proof(
params: MessageProofParams,
) -> (
<Self::SourceHeaderChain as SourceHeaderChain<Self::InboundMessageFee>>::MessagesProof,
Weight,
);
}
benchmarks_instance! {
_ { }
//
// Benchmarks that are used directly by the runtime.
//
// 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 maximal for the target chain.
//
// Results of this benchmark may be directly used in the `send_message`.
send_message_worst_case {
let i in 1..100;
let lane_id = bench_lane_id();
let sender = account("sender", i, SEED);
let sender = account("sender", 0, SEED);
T::endow_account(&sender);
// 'send' messages that are to be pruned when our message is sent
@@ -72,11 +99,181 @@ benchmarks_instance! {
}
confirm_message_delivery::<T, I>(T::MaxMessagesToPruneAtOnce::get());
let (payload, fee) = T::prepare_message(MessageParams {
let (payload, fee) = T::prepare_outbound_message(MessageParams {
size_factor: WORST_MESSAGE_SIZE_FACTOR,
sender_account: sender.clone(),
});
}: send_message(RawOrigin::Signed(sender), lane_id, payload, fee)
verify {
assert_eq!(
crate::Module::<T, I>::outbound_latest_generated_nonce(bench_lane_id()),
T::MaxMessagesToPruneAtOnce::get() + 1,
);
}
// 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 successfully dispatched;
// * 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);
let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: bench_lane_id(),
message_nonces: 1..=1,
outbound_lane_data: None,
});
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, dispatch_weight)
verify {
assert_eq!(
crate::Module::<T, I>::inbound_latest_received_nonce(bench_lane_id()),
1,
);
}
// 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 successfully dispatched;
// * message requires all heavy checks done by dispatcher.
//
// The weight of single message delivery could be approximated as
// `weight(receive_two_messages_proof) - weight(receive_single_message_proof)`.
// This won't be super-accurate if message has non-zero dispatch weight, but estimation should
// be close enough to real weight.
receive_two_messages_proof {
let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: bench_lane_id(),
message_nonces: 1..=2,
outbound_lane_data: None,
});
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, dispatch_weight)
verify {
assert_eq!(
crate::Module::<T, I>::inbound_latest_received_nonce(bench_lane_id()),
2,
);
}
// 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;
// * 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);
// mark messages 1..=20 as delivered
receive_messages::<T, I>(20);
let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: bench_lane_id(),
message_nonces: 21..=21,
outbound_lane_data: Some(OutboundLaneData {
oldest_unpruned_nonce: 21,
latest_received_nonce: 20,
latest_generated_nonce: 21,
}),
});
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, dispatch_weight)
verify {
assert_eq!(
crate::Module::<T, I>::inbound_latest_received_nonce(bench_lane_id()),
21,
);
assert_eq!(
crate::Module::<T, I>::inbound_latest_confirmed_nonce(bench_lane_id()),
20,
);
}
//
// Benchmarks for manual checks.
//
// 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;
// * message is successfully dispatched;
// * message requires all heavy checks done by dispatcher.
//
// This benchmarks gives us an approximation of single message delivery weight. It is similar to the
// `weight(receive_two_messages_proof) - weight(receive_single_message_proof)`. So it may be used
// to verify that the other approximation is correct.
receive_multiple_messages_proof {
let i in 1..T::MaxMessagesInDeliveryTransaction::get()
.try_into()
.expect("Value of MaxMessagesInDeliveryTransaction is too large");
let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: bench_lane_id(),
message_nonces: 1..=i as _,
outbound_lane_data: None,
});
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, dispatch_weight)
verify {
assert_eq!(
crate::Module::<T, I>::inbound_latest_received_nonce(bench_lane_id()),
i as MessageNonce,
);
}
// Benchmark `receive_messages_proof` extrinsic with multiple minimal-weight messages 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;
// * message requires all heavy checks done by dispatcher.
//
// This benchmarks gives us an approximation of outbound lane state delivery weight. It is similar to the
// `weight(receive_single_message_proof_with_outbound_lane_state) - weight(receive_single_message_proof)`.
// So it may be used to verify that the other approximation is correct.
receive_multiple_messages_proof_with_outbound_lane_state {
let i in 1..T::MaxMessagesInDeliveryTransaction::get()
.try_into()
.expect("Value of MaxMessagesInDeliveryTransaction is too large");
let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
// mark messages 1..=20 as delivered
receive_messages::<T, I>(20);
let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: bench_lane_id(),
message_nonces: 21..=20 + i as MessageNonce,
outbound_lane_data: Some(OutboundLaneData {
oldest_unpruned_nonce: 21,
latest_received_nonce: 20,
latest_generated_nonce: 21,
}),
});
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, dispatch_weight)
verify {
assert_eq!(
crate::Module::<T, I>::inbound_latest_received_nonce(bench_lane_id()),
20 + i as MessageNonce,
);
assert_eq!(
crate::Module::<T, I>::inbound_latest_confirmed_nonce(bench_lane_id()),
20,
);
}
}
fn bench_lane_id() -> LaneId {
@@ -84,7 +281,7 @@ fn bench_lane_id() -> LaneId {
}
fn send_regular_message<T: Config<I>, I: Instance>() {
let mut outbound_lane = crate::outbound_lane::<T, I>(bench_lane_id());
let mut outbound_lane = outbound_lane::<T, I>(bench_lane_id());
outbound_lane.send_message(MessageData {
payload: vec![],
fee: Zero::zero(),
@@ -92,6 +289,15 @@ fn send_regular_message<T: Config<I>, I: Instance>() {
}
fn confirm_message_delivery<T: Config<I>, I: Instance>(nonce: MessageNonce) {
let mut outbound_lane = crate::outbound_lane::<T, I>(bench_lane_id());
let mut outbound_lane = outbound_lane::<T, I>(bench_lane_id());
assert!(outbound_lane.confirm_delivery(nonce).is_some());
}
fn receive_messages<T: Config<I>, I: Instance>(nonce: MessageNonce) {
let mut inbound_lane_storage = inbound_lane_storage::<T, I>(bench_lane_id());
inbound_lane_storage.set_data(InboundLaneData {
relayers: vec![(1, nonce, T::bridged_relayer_id())].into_iter().collect(),
latest_received_nonce: nonce,
latest_confirmed_nonce: 0,
});
}
+7 -2
View File
@@ -558,11 +558,16 @@ fn ensure_operational<T: Config<I>, I: Instance>() -> Result<(), Error<T, I>> {
/// Creates new inbound lane object, backed by runtime storage.
fn inbound_lane<T: Config<I>, I: Instance>(lane_id: LaneId) -> InboundLane<RuntimeInboundLaneStorage<T, I>> {
InboundLane::new(RuntimeInboundLaneStorage {
InboundLane::new(inbound_lane_storage::<T, I>(lane_id))
}
/// Creates new runtime inbound lane storage.
fn inbound_lane_storage<T: Config<I>, I: Instance>(lane_id: LaneId) -> RuntimeInboundLaneStorage<T, I> {
RuntimeInboundLaneStorage {
lane_id,
cached_data: RefCell::new(None),
_phantom: Default::default(),
})
}
}
/// Creates new outbound lane object, backed by runtime storage.
+1
View File
@@ -47,3 +47,4 @@ std = [
"sp-std/std",
"sp-trie/std",
]
runtime-benchmarks = []
+12
View File
@@ -370,6 +370,18 @@ fn ensure_operational<T: Config>() -> Result<(), Error<T>> {
}
}
/// (Re)initialize bridge with given header for using it in external benchmarks.
#[cfg(feature = "runtime-benchmarks")]
pub fn initialize_for_benchmarks<T: Config>(header: HeaderOf<T::BridgedChain>) {
initialize_bridge::<T>(InitializationData {
header,
authority_list: Vec::new(), // we don't verify any proofs in external benchmarks
set_id: 0,
scheduled_change: None,
is_halted: false,
});
}
/// Since this writes to storage with no real checks this should only be used in functions that were
/// called by a trusted origin.
fn initialize_bridge<T: Config>(init_params: InitializationData<BridgedHeader<T>>) {