mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 13:17:56 +00:00
Benchmark for message delivery confirmation transaction (#570)
* receive_delivery_proof benchmarks * fix compilation * 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> * 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> * Update modules/message-lane/src/benchmarking.rs Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
b45d65f330
commit
9deea5d251
@@ -802,6 +802,7 @@ impl_runtime_apis! {
|
||||
use pallet_message_lane::benchmarking::{
|
||||
Module as MessageLaneBench,
|
||||
Config as MessageLaneConfig,
|
||||
MessageDeliveryProofParams as MessageLaneMessageDeliveryProofParams,
|
||||
MessageParams as MessageLaneMessageParams,
|
||||
MessageProofParams as MessageLaneMessageProofParams,
|
||||
};
|
||||
@@ -811,6 +812,10 @@ impl_runtime_apis! {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn account_balance(account: &Self::AccountId) -> Self::OutboundMessageFee {
|
||||
pallet_balances::Module::<Runtime>::free_balance(account)
|
||||
}
|
||||
|
||||
fn endow_account(account: &Self::AccountId) {
|
||||
pallet_balances::Module::<Runtime>::make_free_balance_be(
|
||||
account,
|
||||
@@ -913,6 +918,34 @@ impl_runtime_apis! {
|
||||
}.encode(),
|
||||
)
|
||||
}
|
||||
|
||||
fn prepare_message_delivery_proof(
|
||||
params: MessageLaneMessageDeliveryProofParams<Self::AccountId>,
|
||||
) -> millau_messages::FromMillauMessagesDeliveryProof {
|
||||
use crate::millau_messages::{Millau, WithMillauMessageBridge};
|
||||
use bridge_runtime_common::{
|
||||
messages::ChainWithMessageLanes,
|
||||
messages_benchmarking::prepare_message_delivery_proof,
|
||||
};
|
||||
use sp_runtime::traits::Header;
|
||||
|
||||
prepare_message_delivery_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, _, _>(
|
||||
params,
|
||||
|lane_id| pallet_message_lane::storage_keys::inbound_lane_data_key::<
|
||||
Runtime,
|
||||
<Millau as ChainWithMessageLanes>::MessageLaneInstance,
|
||||
>(
|
||||
&lane_id,
|
||||
).0,
|
||||
|state_root| bp_millau::Header::new(
|
||||
0,
|
||||
Default::default(),
|
||||
state_root,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
add_benchmark!(params, batches, pallet_bridge_eth_poa, BridgeKovan);
|
||||
|
||||
@@ -74,7 +74,8 @@ pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDi
|
||||
pub type FromMillauMessagesProof = messages::target::FromBridgedChainMessagesProof<WithMillauMessageBridge>;
|
||||
|
||||
/// Messages delivery proof for Rialto -> Millau messages.
|
||||
type ToMillauMessagesDeliveryProof = messages::source::FromBridgedChainMessagesDeliveryProof<WithMillauMessageBridge>;
|
||||
pub type FromMillauMessagesDeliveryProof =
|
||||
messages::source::FromBridgedChainMessagesDeliveryProof<WithMillauMessageBridge>;
|
||||
|
||||
/// Millau <-> Rialto message bridge.
|
||||
#[derive(RuntimeDebug, Clone, Copy)]
|
||||
@@ -168,7 +169,7 @@ impl TargetHeaderChain<ToMillauMessagePayload, bp_millau::AccountId> for Millau
|
||||
// - hash of the header this proof has been created with;
|
||||
// - the storage proof of one or several keys;
|
||||
// - id of the lane we prove state of.
|
||||
type MessagesDeliveryProof = ToMillauMessagesDeliveryProof;
|
||||
type MessagesDeliveryProof = FromMillauMessagesDeliveryProof;
|
||||
|
||||
fn verify_message(payload: &ToMillauMessagePayload) -> Result<(), Self::Error> {
|
||||
messages::source::verify_chain_message::<WithMillauMessageBridge>(payload)
|
||||
|
||||
@@ -90,7 +90,7 @@ pub trait ChainWithMessageLanes {
|
||||
/// Hash used in the chain.
|
||||
type Hash: Decode;
|
||||
/// Accound id on the chain.
|
||||
type AccountId: Decode;
|
||||
type AccountId: Encode + Decode;
|
||||
/// Public key of the chain account that may be used to verify signatures.
|
||||
type Signer: Decode;
|
||||
/// Signature type used on the chain.
|
||||
|
||||
@@ -19,13 +19,16 @@
|
||||
|
||||
#![cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
use crate::messages::{target::FromBridgedChainMessagesProof, BalanceOf, BridgedChain, HashOf, MessageBridge};
|
||||
use crate::messages::{
|
||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, AccountIdOf, BalanceOf,
|
||||
BridgedChain, HashOf, MessageBridge, ThisChain,
|
||||
};
|
||||
|
||||
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 pallet_message_lane::benchmarking::{MessageDeliveryProofParams, MessageProofParams};
|
||||
use sp_core::Hasher;
|
||||
use sp_runtime::traits::Header;
|
||||
use sp_std::prelude::*;
|
||||
@@ -142,3 +145,47 @@ where
|
||||
.expect("too many messages requested by benchmark"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Prepare proof of messages delivery for the `receive_messages_delivery_proof` call.
|
||||
pub fn prepare_message_delivery_proof<B, H, R, ML, MH>(
|
||||
params: MessageDeliveryProofParams<AccountIdOf<ThisChain<B>>>,
|
||||
make_bridged_inbound_lane_data_key: ML,
|
||||
make_bridged_header: MH,
|
||||
) -> FromBridgedChainMessagesDeliveryProof<B>
|
||||
where
|
||||
B: MessageBridge,
|
||||
H: Hasher,
|
||||
R: pallet_substrate_bridge::Config,
|
||||
<R::BridgedChain as bp_runtime::Chain>::Hash: Into<HashOf<BridgedChain<B>>>,
|
||||
ML: Fn(LaneId) -> Vec<u8>,
|
||||
MH: Fn(H::Out) -> <R::BridgedChain as bp_runtime::Chain>::Header,
|
||||
{
|
||||
// prepare Bridged chain storage with inbound lane state
|
||||
let storage_key = make_bridged_inbound_lane_data_key(params.lane);
|
||||
let mut root = Default::default();
|
||||
let mut mdb = MemoryDB::default();
|
||||
{
|
||||
let mut trie = TrieDBMut::<H>::new(&mut mdb, &mut root);
|
||||
trie.insert(&storage_key, ¶ms.inbound_lane_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
}
|
||||
|
||||
// generate storage proof to be delivered to This chain
|
||||
let mut proof_recorder = Recorder::<H::Out>::new();
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,19 +16,23 @@
|
||||
|
||||
//! Message lane pallet benchmarking.
|
||||
|
||||
use crate::{inbound_lane::InboundLaneStorage, inbound_lane_storage, outbound_lane, Call, Instance};
|
||||
use crate::{
|
||||
inbound_lane::InboundLaneStorage, inbound_lane_storage, outbound_lane, relayer_fund_account_id, Call, Instance,
|
||||
};
|
||||
|
||||
use bp_message_lane::{
|
||||
target_chain::SourceHeaderChain, InboundLaneData, LaneId, MessageData, MessageNonce, OutboundLaneData,
|
||||
source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, InboundLaneData, LaneId, MessageData,
|
||||
MessageNonce, OutboundLaneData,
|
||||
};
|
||||
use frame_benchmarking::{account, benchmarks_instance};
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use frame_system::RawOrigin;
|
||||
use num_traits::Zero;
|
||||
use sp_std::{ops::RangeInclusive, prelude::*};
|
||||
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;
|
||||
|
||||
const SEED: u32 = 0;
|
||||
|
||||
@@ -55,10 +59,20 @@ pub struct MessageProofParams {
|
||||
pub outbound_lane_data: Option<OutboundLaneData>,
|
||||
}
|
||||
|
||||
/// Benchmark-specific message delivery proof parameters.
|
||||
pub struct MessageDeliveryProofParams<ThisChainAccountId> {
|
||||
/// Id of the lane.
|
||||
pub lane: LaneId,
|
||||
/// The proof needs to include this inbound lane data.
|
||||
pub inbound_lane_data: InboundLaneData<ThisChainAccountId>,
|
||||
}
|
||||
|
||||
/// 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;
|
||||
/// Return balance of given account.
|
||||
fn account_balance(account: &Self::AccountId) -> Self::OutboundMessageFee;
|
||||
/// Create given account and give it enough balance for test purposes.
|
||||
fn endow_account(account: &Self::AccountId);
|
||||
/// Prepare message to send over lane.
|
||||
@@ -72,6 +86,10 @@ pub trait Config<I: Instance>: crate::Config<I> {
|
||||
<Self::SourceHeaderChain as SourceHeaderChain<Self::InboundMessageFee>>::MessagesProof,
|
||||
Weight,
|
||||
);
|
||||
/// Prepare messages delivery proof to receive by the module.
|
||||
fn prepare_message_delivery_proof(
|
||||
params: MessageDeliveryProofParams<Self::AccountId>,
|
||||
) -> <Self::TargetHeaderChain as TargetHeaderChain<Self::OutboundPayload, Self::AccountId>>::MessagesDeliveryProof;
|
||||
}
|
||||
|
||||
benchmarks_instance! {
|
||||
@@ -200,6 +218,111 @@ benchmarks_instance! {
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `receive_messages_delivery_proof` extrinsic with following conditions:
|
||||
// * single relayer is rewarded for relaying single message;
|
||||
// * 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 {
|
||||
let relayers_fund_id = relayer_fund_account_id::<T, I>();
|
||||
let relayer_id: T::AccountId = account("relayer", 0, SEED);
|
||||
let relayer_balance = T::account_balance(&relayer_id);
|
||||
T::endow_account(&relayers_fund_id);
|
||||
|
||||
// send message that we're going to confirm
|
||||
send_regular_message::<T, I>();
|
||||
|
||||
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
|
||||
lane: bench_lane_id(),
|
||||
inbound_lane_data: InboundLaneData {
|
||||
relayers: vec![(1, 1, relayer_id.clone())].into_iter().collect(),
|
||||
latest_received_nonce: 1,
|
||||
latest_confirmed_nonce: 0,
|
||||
}
|
||||
});
|
||||
}: receive_messages_delivery_proof(RawOrigin::Signed(relayer_id.clone()), proof)
|
||||
verify {
|
||||
assert_eq!(
|
||||
T::account_balance(&relayer_id),
|
||||
relayer_balance + MESSAGE_FEE.into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `receive_messages_delivery_proof` extrinsic with following conditions:
|
||||
// * single relayer is rewarded for relaying two messages;
|
||||
// * relayer account does not exist (in practice it needs to exist in production environment).
|
||||
//
|
||||
// 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 {
|
||||
let relayers_fund_id = relayer_fund_account_id::<T, I>();
|
||||
let relayer_id: T::AccountId = account("relayer", 0, SEED);
|
||||
let relayer_balance = T::account_balance(&relayer_id);
|
||||
T::endow_account(&relayers_fund_id);
|
||||
|
||||
// send message that we're going to confirm
|
||||
send_regular_message::<T, I>();
|
||||
send_regular_message::<T, I>();
|
||||
|
||||
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
|
||||
lane: bench_lane_id(),
|
||||
inbound_lane_data: InboundLaneData {
|
||||
relayers: vec![(1, 2, relayer_id.clone())].into_iter().collect(),
|
||||
latest_received_nonce: 2,
|
||||
latest_confirmed_nonce: 0,
|
||||
}
|
||||
});
|
||||
}: receive_messages_delivery_proof(RawOrigin::Signed(relayer_id.clone()), proof)
|
||||
verify {
|
||||
assert_eq!(
|
||||
T::account_balance(&relayer_id),
|
||||
relayer_balance + (MESSAGE_FEE * 2).into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `receive_messages_delivery_proof` extrinsic with following conditions:
|
||||
// * two relayers are rewarded for relaying single message each;
|
||||
// * relayer account does not exist (in practice it needs to exist in production environment).
|
||||
//
|
||||
// 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 {
|
||||
let relayers_fund_id = relayer_fund_account_id::<T, I>();
|
||||
let relayer1_id: T::AccountId = account("relayer1", 1, SEED);
|
||||
let relayer1_balance = T::account_balance(&relayer1_id);
|
||||
let relayer2_id: T::AccountId = account("relayer2", 2, SEED);
|
||||
let relayer2_balance = T::account_balance(&relayer2_id);
|
||||
T::endow_account(&relayers_fund_id);
|
||||
|
||||
// send message that we're going to confirm
|
||||
send_regular_message::<T, I>();
|
||||
send_regular_message::<T, I>();
|
||||
|
||||
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
|
||||
lane: bench_lane_id(),
|
||||
inbound_lane_data: InboundLaneData {
|
||||
relayers: vec![
|
||||
(1, 1, relayer1_id.clone()),
|
||||
(2, 2, relayer2_id.clone()),
|
||||
].into_iter().collect(),
|
||||
latest_received_nonce: 2,
|
||||
latest_confirmed_nonce: 0,
|
||||
}
|
||||
});
|
||||
}: receive_messages_delivery_proof(RawOrigin::Signed(relayer1_id.clone()), proof)
|
||||
verify {
|
||||
assert_eq!(
|
||||
T::account_balance(&relayer1_id),
|
||||
relayer1_balance + MESSAGE_FEE.into(),
|
||||
);
|
||||
assert_eq!(
|
||||
T::account_balance(&relayer2_id),
|
||||
relayer2_balance + MESSAGE_FEE.into(),
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Benchmarks for manual checks.
|
||||
//
|
||||
@@ -284,6 +407,86 @@ benchmarks_instance! {
|
||||
20,
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `receive_messages_delivery_proof` extrinsic where single relayer delivers multiple messages.
|
||||
receive_delivery_proof_for_multiple_messages_by_single_relayer {
|
||||
// there actually should be used value of `MaxUnrewardedRelayerEntriesAtInboundLane` from the bridged
|
||||
// chain, but we're more interested in additional weight/message than in max weight
|
||||
let i in 1..T::MaxUnrewardedRelayerEntriesAtInboundLane::get()
|
||||
.try_into()
|
||||
.expect("Value of MaxUnrewardedRelayerEntriesAtInboundLane is too large");
|
||||
|
||||
let relayers_fund_id = relayer_fund_account_id::<T, I>();
|
||||
let relayer_id: T::AccountId = account("relayer", 0, SEED);
|
||||
let relayer_balance = T::account_balance(&relayer_id);
|
||||
T::endow_account(&relayers_fund_id);
|
||||
|
||||
// send messages that we're going to confirm
|
||||
for _ in 1..=i {
|
||||
send_regular_message::<T, I>();
|
||||
}
|
||||
|
||||
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
|
||||
lane: bench_lane_id(),
|
||||
inbound_lane_data: InboundLaneData {
|
||||
relayers: vec![(1, i as MessageNonce, relayer_id.clone())].into_iter().collect(),
|
||||
latest_received_nonce: i as MessageNonce,
|
||||
latest_confirmed_nonce: 0,
|
||||
}
|
||||
});
|
||||
}: receive_messages_delivery_proof(RawOrigin::Signed(relayer_id.clone()), proof)
|
||||
verify {
|
||||
assert_eq!(
|
||||
T::account_balance(&relayer_id),
|
||||
relayer_balance + (MESSAGE_FEE * i).into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `receive_messages_delivery_proof` extrinsic where every relayer delivers single messages.
|
||||
receive_delivery_proof_for_multiple_messages_by_multiple_relayers {
|
||||
// there actually should be used value of `MaxUnconfirmedMessagesAtInboundLane` from the bridged
|
||||
// chain, but we're more interested in additional weight/message than in max weight
|
||||
let i in 1..T::MaxUnconfirmedMessagesAtInboundLane::get()
|
||||
.try_into()
|
||||
.expect("Value of MaxUnconfirmedMessagesAtInboundLane is too large ");
|
||||
|
||||
let relayers_fund_id = relayer_fund_account_id::<T, I>();
|
||||
let confirmation_relayer_id = account("relayer", 0, SEED);
|
||||
let relayers: BTreeMap<T::AccountId, T::OutboundMessageFee> = (1..=i)
|
||||
.map(|j| {
|
||||
let relayer_id = account("relayer", j + 1, SEED);
|
||||
let relayer_balance = T::account_balance(&relayer_id);
|
||||
(relayer_id, relayer_balance)
|
||||
})
|
||||
.collect();
|
||||
T::endow_account(&relayers_fund_id);
|
||||
|
||||
// send messages that we're going to confirm
|
||||
for _ in 1..=i {
|
||||
send_regular_message::<T, I>();
|
||||
}
|
||||
|
||||
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
|
||||
lane: bench_lane_id(),
|
||||
inbound_lane_data: InboundLaneData {
|
||||
relayers: relayers
|
||||
.keys()
|
||||
.enumerate()
|
||||
.map(|(j, relayer_id)| (j as MessageNonce + 1, j as MessageNonce + 1, relayer_id.clone()))
|
||||
.collect(),
|
||||
latest_received_nonce: i as MessageNonce,
|
||||
latest_confirmed_nonce: 0,
|
||||
}
|
||||
});
|
||||
}: receive_messages_delivery_proof(RawOrigin::Signed(confirmation_relayer_id), proof)
|
||||
verify {
|
||||
for (relayer_id, prev_balance) in relayers {
|
||||
assert_eq!(
|
||||
T::account_balance(&relayer_id),
|
||||
prev_balance + MESSAGE_FEE.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_lane_id() -> LaneId {
|
||||
@@ -294,7 +497,7 @@ fn send_regular_message<T: Config<I>, I: Instance>() {
|
||||
let mut outbound_lane = outbound_lane::<T, I>(bench_lane_id());
|
||||
outbound_lane.send_message(MessageData {
|
||||
payload: vec![],
|
||||
fee: Zero::zero(),
|
||||
fee: MESSAGE_FEE.into(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ use frame_support::{
|
||||
Parameter, StorageMap,
|
||||
};
|
||||
use frame_system::{ensure_signed, RawOrigin};
|
||||
use num_traits::Zero;
|
||||
use num_traits::{SaturatingAdd, Zero};
|
||||
use sp_runtime::{traits::BadOrigin, DispatchResult};
|
||||
use sp_std::{cell::RefCell, marker::PhantomData, prelude::*};
|
||||
|
||||
@@ -92,12 +92,15 @@ pub trait Config<I = DefaultInstance>: frame_system::Config {
|
||||
///
|
||||
/// 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.
|
||||
type MaxUnconfirmedMessagesAtInboundLane: Get<MessageNonce>;
|
||||
|
||||
/// Payload type of outbound messages. This payload is dispatched on the bridged chain.
|
||||
type OutboundPayload: Parameter;
|
||||
/// Message fee type of outbound messages. This fee is paid on this chain.
|
||||
type OutboundMessageFee: Parameter + Zero;
|
||||
type OutboundMessageFee: From<u32> + Parameter + SaturatingAdd + Zero;
|
||||
|
||||
/// Payload type of inbound messages. This payload is dispatched on this chain.
|
||||
type InboundPayload: Decode;
|
||||
@@ -423,24 +426,30 @@ decl_module! {
|
||||
let received_range = lane.confirm_delivery(lane_data.latest_received_nonce);
|
||||
if let Some(received_range) = received_range {
|
||||
Self::deposit_event(RawEvent::MessagesDelivered(lane_id, received_range.0, received_range.1));
|
||||
let relayer_fund_account = relayer_fund_account_id::<T, I>();
|
||||
|
||||
// reward relayers that have delivered messages
|
||||
// this loop is bounded by `T::MaxUnconfirmedMessagesAtInboundLane` on the bridged chain
|
||||
// this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain
|
||||
let relayer_fund_account = relayer_fund_account_id::<T, I>();
|
||||
for (nonce_low, nonce_high, relayer) in lane_data.relayers {
|
||||
let nonce_begin = sp_std::cmp::max(nonce_low, received_range.0);
|
||||
let nonce_end = sp_std::cmp::min(nonce_high, received_range.1);
|
||||
|
||||
// loop won't proceed if current entry is ahead of received range (begin > end).
|
||||
// this loop is bound by `T::MaxUnconfirmedMessagesAtInboundLane` on the bridged chain
|
||||
let mut relayer_fee: T::OutboundMessageFee = Zero::zero();
|
||||
for nonce in nonce_begin..nonce_end + 1 {
|
||||
let message_data = OutboundMessages::<T, I>::get(MessageKey {
|
||||
lane_id,
|
||||
nonce,
|
||||
}).expect("message was just confirmed; we never prune unconfirmed messages; qed");
|
||||
relayer_fee = relayer_fee.saturating_add(&message_data.fee);
|
||||
}
|
||||
|
||||
if !relayer_fee.is_zero() {
|
||||
<T as Config<I>>::MessageDeliveryAndDispatchPayment::pay_relayer_reward(
|
||||
&confirmation_relayer,
|
||||
&relayer,
|
||||
&message_data.fee,
|
||||
&relayer_fee,
|
||||
&relayer_fund_account,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user