mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 14:31:02 +00:00
Remove message fee + message send calls (#1642)
* remove message fee * it is compiling! * fixes + fmt * more cleanup * more cleanup * restore MessageDeliveryAndDispatchPayment since we'll need relayer rewards * started rational relayer removal * more removal * removed estimate fee subcommand * remove DispatchFeePayment * more removals * removed conversion rates && some metrics * - unneeded associated type * - OutboundMessageFee * fix benchmarks compilation * fmt * test + fix benchmarks * fix send message * clippy
This commit is contained in:
committed by
Bastian Köcher
parent
1217b2cf80
commit
8c845602cf
@@ -18,35 +18,25 @@
|
||||
|
||||
use crate::{
|
||||
inbound_lane::InboundLaneStorage, inbound_lane_storage, outbound_lane,
|
||||
outbound_lane::ReceivalConfirmationResult, weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH, Call,
|
||||
OutboundLanes, OutboundMessages,
|
||||
weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH, Call, OutboundLanes,
|
||||
};
|
||||
|
||||
use bp_messages::{
|
||||
source_chain::TargetHeaderChain, target_chain::SourceHeaderChain, DeliveredMessages,
|
||||
InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
||||
UnrewardedRelayer, UnrewardedRelayersState,
|
||||
InboundLaneData, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer,
|
||||
UnrewardedRelayersState,
|
||||
};
|
||||
use bp_runtime::{messages::DispatchFeePayment, StorageProofSize};
|
||||
use bp_runtime::StorageProofSize;
|
||||
use frame_benchmarking::{account, benchmarks_instance_pallet};
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use frame_support::weights::Weight;
|
||||
use frame_system::RawOrigin;
|
||||
use sp_std::{collections::vec_deque::VecDeque, convert::TryInto, ops::RangeInclusive, prelude::*};
|
||||
use sp_std::{ops::RangeInclusive, prelude::*};
|
||||
|
||||
const SEED: u32 = 0;
|
||||
|
||||
/// Pallet we're benchmarking here.
|
||||
pub struct Pallet<T: Config<I>, I: 'static>(crate::Pallet<T, I>);
|
||||
|
||||
/// Benchmark-specific message parameters.
|
||||
#[derive(Debug)]
|
||||
pub struct MessageParams<ThisAccountId> {
|
||||
/// Size of the message payload.
|
||||
pub size: u32,
|
||||
/// Message sender account.
|
||||
pub sender_account: ThisAccountId,
|
||||
}
|
||||
|
||||
/// Benchmark-specific message proof parameters.
|
||||
#[derive(Debug)]
|
||||
pub struct MessageProofParams {
|
||||
@@ -58,8 +48,6 @@ pub struct MessageProofParams {
|
||||
pub outbound_lane_data: Option<OutboundLaneData>,
|
||||
/// Proof size requirements.
|
||||
pub size: StorageProofSize,
|
||||
/// Where the fee for dispatching message is paid?
|
||||
pub dispatch_fee_payment: DispatchFeePayment,
|
||||
}
|
||||
|
||||
/// Benchmark-specific message delivery proof parameters.
|
||||
@@ -79,29 +67,14 @@ pub trait Config<I: 'static>: crate::Config<I> {
|
||||
fn bench_lane_id() -> LaneId {
|
||||
Default::default()
|
||||
}
|
||||
/// 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.
|
||||
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);
|
||||
/// Fee paid by submitter for single message delivery.
|
||||
fn message_fee() -> Self::OutboundMessageFee {
|
||||
100_000_000_000_000.into()
|
||||
}
|
||||
/// Prepare message to send over lane.
|
||||
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,
|
||||
);
|
||||
) -> (<Self::SourceHeaderChain as SourceHeaderChain>::MessagesProof, Weight);
|
||||
/// Prepare messages delivery proof to receive by the module.
|
||||
fn prepare_message_delivery_proof(
|
||||
params: MessageDeliveryProofParams<Self::AccountId>,
|
||||
@@ -115,156 +88,6 @@ benchmarks_instance_pallet! {
|
||||
// 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 minimal for the target chain.
|
||||
//
|
||||
// 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 = T::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::<T, I>();
|
||||
}
|
||||
confirm_message_delivery::<T, I>(T::MaxMessagesToPruneAtOnce::get());
|
||||
|
||||
let (payload, fee) = T::prepare_outbound_message(MessageParams {
|
||||
size: 0,
|
||||
sender_account: sender.clone(),
|
||||
});
|
||||
}: send_message(RawOrigin::Signed(sender), lane_id, payload, fee)
|
||||
verify {
|
||||
assert_eq!(
|
||||
crate::OutboundLanes::<T, I>::get(&T::bench_lane_id()).latest_generated_nonce,
|
||||
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 = T::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::<T, I>();
|
||||
}
|
||||
confirm_message_delivery::<T, I>(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::OutboundLanes::<T, I>::get(&T::bench_lane_id()).latest_generated_nonce,
|
||||
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 = T::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::<T, I>();
|
||||
}
|
||||
confirm_message_delivery::<T, I>(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)
|
||||
verify {
|
||||
assert_eq!(
|
||||
crate::OutboundLanes::<T, I>::get(&T::bench_lane_id()).latest_generated_nonce,
|
||||
T::MaxMessagesToPruneAtOnce::get() + 1,
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `increase_message_fee` with following conditions:
|
||||
// * message has maximal message;
|
||||
// * submitter account is killed because its balance is less than ED after payment.
|
||||
//
|
||||
// Result of this benchmark is directly used by weight formula of the call.
|
||||
maximal_increase_message_fee {
|
||||
let sender = account("sender", 42, SEED);
|
||||
T::endow_account(&sender);
|
||||
|
||||
let additional_fee = T::account_balance(&sender);
|
||||
let lane_id = T::bench_lane_id();
|
||||
let nonce = 1;
|
||||
|
||||
send_regular_message_with_payload::<T, I>(vec![42u8; T::maximal_message_size() as _]);
|
||||
}: increase_message_fee(RawOrigin::Signed(sender.clone()), lane_id, nonce, additional_fee)
|
||||
verify {
|
||||
assert_eq!(
|
||||
OutboundMessages::<T, I>::get(MessageKey { lane_id, nonce }).unwrap().fee,
|
||||
T::message_fee() + additional_fee,
|
||||
);
|
||||
}
|
||||
|
||||
// Benchmark `increase_message_fee` with following conditions:
|
||||
// * message size varies from minimal to maximal;
|
||||
// * submitter account is killed because its balance is less than ED after payment.
|
||||
increase_message_fee {
|
||||
let i in 0..T::maximal_message_size().try_into().unwrap_or_default();
|
||||
|
||||
let sender = account("sender", 42, SEED);
|
||||
T::endow_account(&sender);
|
||||
|
||||
let additional_fee = T::account_balance(&sender);
|
||||
let lane_id = T::bench_lane_id();
|
||||
let nonce = 1;
|
||||
|
||||
send_regular_message_with_payload::<T, I>(vec![42u8; i as _]);
|
||||
}: increase_message_fee(RawOrigin::Signed(sender.clone()), lane_id, nonce, additional_fee)
|
||||
verify {
|
||||
assert_eq!(
|
||||
OutboundMessages::<T, I>::get(MessageKey { lane_id, nonce }).unwrap().fee,
|
||||
T::message_fee() + additional_fee,
|
||||
);
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -286,7 +109,6 @@ benchmarks_instance_pallet! {
|
||||
message_nonces: 21..=21,
|
||||
outbound_lane_data: None,
|
||||
size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
});
|
||||
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight)
|
||||
verify {
|
||||
@@ -321,7 +143,6 @@ benchmarks_instance_pallet! {
|
||||
message_nonces: 21..=22,
|
||||
outbound_lane_data: None,
|
||||
size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
});
|
||||
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 2, dispatch_weight)
|
||||
verify {
|
||||
@@ -360,7 +181,6 @@ benchmarks_instance_pallet! {
|
||||
latest_generated_nonce: 21,
|
||||
}),
|
||||
size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
});
|
||||
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight)
|
||||
verify {
|
||||
@@ -392,7 +212,6 @@ benchmarks_instance_pallet! {
|
||||
message_nonces: 21..=21,
|
||||
outbound_lane_data: None,
|
||||
size: StorageProofSize::HasExtraNodes(1024),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
});
|
||||
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight)
|
||||
verify {
|
||||
@@ -427,7 +246,6 @@ benchmarks_instance_pallet! {
|
||||
message_nonces: 21..=21,
|
||||
outbound_lane_data: None,
|
||||
size: StorageProofSize::HasExtraNodes(16 * 1024),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
});
|
||||
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight)
|
||||
verify {
|
||||
@@ -461,7 +279,6 @@ benchmarks_instance_pallet! {
|
||||
message_nonces: 21..=21,
|
||||
outbound_lane_data: None,
|
||||
size: StorageProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
});
|
||||
}: receive_messages_proof(RawOrigin::Signed(relayer_id_on_target), relayer_id_on_source, proof, 1, dispatch_weight)
|
||||
verify {
|
||||
@@ -479,7 +296,6 @@ benchmarks_instance_pallet! {
|
||||
// This is base benchmark for all other confirmations delivery benchmarks.
|
||||
receive_delivery_proof_for_single_message {
|
||||
let relayer_id: T::AccountId = account("relayer", 0, SEED);
|
||||
let relayer_balance = T::account_balance(&relayer_id);
|
||||
|
||||
// send message that we're going to confirm
|
||||
send_regular_message::<T, I>();
|
||||
@@ -515,7 +331,6 @@ benchmarks_instance_pallet! {
|
||||
// - weight(receive_delivery_proof_for_single_message)`.
|
||||
receive_delivery_proof_for_two_messages_by_single_relayer {
|
||||
let relayer_id: T::AccountId = account("relayer", 0, SEED);
|
||||
let relayer_balance = T::account_balance(&relayer_id);
|
||||
|
||||
// send message that we're going to confirm
|
||||
send_regular_message::<T, I>();
|
||||
@@ -554,9 +369,7 @@ benchmarks_instance_pallet! {
|
||||
// - weight(receive_delivery_proof_for_two_messages_by_single_relayer)`.
|
||||
receive_delivery_proof_for_two_messages_by_two_relayers {
|
||||
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);
|
||||
|
||||
// send message that we're going to confirm
|
||||
send_regular_message::<T, I>();
|
||||
@@ -593,28 +406,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
fn send_regular_message<T: Config<I>, I: 'static>() {
|
||||
let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id());
|
||||
outbound_lane.send_message(MessageData { payload: vec![], fee: T::message_fee() });
|
||||
}
|
||||
|
||||
fn send_regular_message_with_payload<T: Config<I>, I: 'static>(payload: Vec<u8>) {
|
||||
let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id());
|
||||
outbound_lane.send_message(MessageData { payload, fee: T::message_fee() });
|
||||
}
|
||||
|
||||
fn confirm_message_delivery<T: Config<I>, I: 'static>(nonce: MessageNonce) {
|
||||
let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id());
|
||||
let latest_received_nonce = outbound_lane.data().latest_received_nonce;
|
||||
let mut relayers = VecDeque::with_capacity((nonce - latest_received_nonce) as usize);
|
||||
for nonce in latest_received_nonce + 1..=nonce {
|
||||
relayers.push_back(UnrewardedRelayer {
|
||||
relayer: (),
|
||||
messages: DeliveredMessages::new(nonce, true),
|
||||
});
|
||||
}
|
||||
assert!(matches!(
|
||||
outbound_lane.confirm_delivery(nonce - latest_received_nonce, nonce, &relayers),
|
||||
ReceivalConfirmationResult::ConfirmedMessages(_),
|
||||
));
|
||||
outbound_lane.send_message(vec![]);
|
||||
}
|
||||
|
||||
fn receive_messages<T: Config<I>, I: 'static>(nonce: MessageNonce) {
|
||||
|
||||
@@ -31,8 +31,6 @@ use sp_std::prelude::PartialEq;
|
||||
|
||||
/// Inbound lane storage.
|
||||
pub trait InboundLaneStorage {
|
||||
/// Delivery and dispatch fee type on source chain.
|
||||
type MessageFee;
|
||||
/// Id of relayer on source chain.
|
||||
type Relayer: Clone + PartialEq;
|
||||
|
||||
@@ -183,12 +181,12 @@ impl<S: InboundLaneStorage> InboundLane<S> {
|
||||
}
|
||||
|
||||
/// Receive new message.
|
||||
pub fn receive_message<P: MessageDispatch<AccountId, S::MessageFee>, AccountId>(
|
||||
pub fn receive_message<P: MessageDispatch<AccountId>, AccountId>(
|
||||
&mut self,
|
||||
relayer_at_bridged_chain: &S::Relayer,
|
||||
relayer_at_this_chain: &AccountId,
|
||||
nonce: MessageNonce,
|
||||
message_data: DispatchMessageData<P::DispatchPayload, S::MessageFee>,
|
||||
message_data: DispatchMessageData<P::DispatchPayload>,
|
||||
) -> ReceivalResult {
|
||||
let mut data = self.storage.data();
|
||||
let is_correct_message = nonce == data.last_delivered_nonce() + 1;
|
||||
@@ -242,9 +240,9 @@ mod tests {
|
||||
use crate::{
|
||||
inbound_lane,
|
||||
mock::{
|
||||
dispatch_result, message_data, run_test, unrewarded_relayer, TestMessageDispatch,
|
||||
TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B,
|
||||
TEST_RELAYER_C,
|
||||
dispatch_result, inbound_message_data, run_test, unrewarded_relayer,
|
||||
TestMessageDispatch, TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A,
|
||||
TEST_RELAYER_B, TEST_RELAYER_C,
|
||||
},
|
||||
RuntimeInboundLaneStorage,
|
||||
};
|
||||
@@ -258,7 +256,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
nonce,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -386,7 +384,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
10,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::InvalidNonce
|
||||
);
|
||||
@@ -406,7 +404,7 @@ mod tests {
|
||||
&(TEST_RELAYER_A + current_nonce),
|
||||
&(TEST_RELAYER_A + current_nonce),
|
||||
current_nonce,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -417,7 +415,7 @@ mod tests {
|
||||
&(TEST_RELAYER_A + max_nonce + 1),
|
||||
&(TEST_RELAYER_A + max_nonce + 1),
|
||||
max_nonce + 1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::TooManyUnrewardedRelayers,
|
||||
);
|
||||
@@ -427,7 +425,7 @@ mod tests {
|
||||
&(TEST_RELAYER_A + max_nonce),
|
||||
&(TEST_RELAYER_A + max_nonce),
|
||||
max_nonce + 1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::TooManyUnrewardedRelayers,
|
||||
);
|
||||
@@ -445,7 +443,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
current_nonce,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -456,7 +454,7 @@ mod tests {
|
||||
&TEST_RELAYER_B,
|
||||
&TEST_RELAYER_B,
|
||||
max_nonce + 1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::TooManyUnconfirmedMessages,
|
||||
);
|
||||
@@ -466,7 +464,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
max_nonce + 1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::TooManyUnconfirmedMessages,
|
||||
);
|
||||
@@ -482,7 +480,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -491,7 +489,7 @@ mod tests {
|
||||
&TEST_RELAYER_B,
|
||||
&TEST_RELAYER_B,
|
||||
2,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -500,7 +498,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
3,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -524,7 +522,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(0))
|
||||
);
|
||||
@@ -533,7 +531,7 @@ mod tests {
|
||||
&TEST_RELAYER_B,
|
||||
&TEST_RELAYER_B,
|
||||
1,
|
||||
message_data(REGULAR_PAYLOAD).into()
|
||||
inbound_message_data(REGULAR_PAYLOAD)
|
||||
),
|
||||
ReceivalResult::InvalidNonce,
|
||||
);
|
||||
@@ -560,7 +558,7 @@ mod tests {
|
||||
&TEST_RELAYER_A,
|
||||
&TEST_RELAYER_A,
|
||||
1,
|
||||
message_data(payload).into()
|
||||
inbound_message_data(payload)
|
||||
),
|
||||
ReceivalResult::Dispatched(dispatch_result(1))
|
||||
);
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#![allow(clippy::unused_unit)]
|
||||
|
||||
pub use inbound_lane::StoredInboundLaneData;
|
||||
pub use outbound_lane::StoredMessageData;
|
||||
pub use outbound_lane::StoredMessagePayload;
|
||||
pub use weights::WeightInfo;
|
||||
pub use weights_ext::{
|
||||
ensure_able_to_receive_confirmation, ensure_able_to_receive_message,
|
||||
@@ -59,17 +59,16 @@ use bp_messages::{
|
||||
DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain,
|
||||
},
|
||||
total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId,
|
||||
MessageData, MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData,
|
||||
OutboundMessageDetails, Parameter as MessagesParameter, UnrewardedRelayer,
|
||||
UnrewardedRelayersState,
|
||||
MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData,
|
||||
OutboundMessageDetails, UnrewardedRelayer, UnrewardedRelayersState,
|
||||
};
|
||||
use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, Size};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get};
|
||||
use num_traits::{SaturatingAdd, Zero};
|
||||
use num_traits::Zero;
|
||||
use sp_std::{
|
||||
cell::RefCell, cmp::PartialOrd, collections::vec_deque::VecDeque, marker::PhantomData,
|
||||
ops::RangeInclusive, prelude::*,
|
||||
cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
mod inbound_lane;
|
||||
@@ -108,11 +107,6 @@ pub mod pallet {
|
||||
/// Gets the chain id value from the instance.
|
||||
#[pallet::constant]
|
||||
type BridgedChainId: Get<ChainId>;
|
||||
/// Pallet parameter that is opaque to the pallet itself, but may be used by the runtime
|
||||
/// for integrating the pallet.
|
||||
///
|
||||
/// All pallet parameters may only be updated either by the root, or by the pallet owner.
|
||||
type Parameter: MessagesParameter;
|
||||
|
||||
/// Maximal number of messages that may be pruned during maintenance. Maintenance occurs
|
||||
/// whenever new message is sent. The reason is that if you want to use lane, you should
|
||||
@@ -142,25 +136,14 @@ pub mod pallet {
|
||||
/// these messages are from different lanes.
|
||||
type MaxUnconfirmedMessagesAtInboundLane: Get<MessageNonce>;
|
||||
|
||||
/// Maximal size of the outbound payload.
|
||||
/// Maximal encoded size of the outbound payload.
|
||||
#[pallet::constant]
|
||||
type MaximalOutboundPayloadSize: Get<u32>;
|
||||
/// Payload type of outbound messages. This payload is dispatched on the bridged chain.
|
||||
type OutboundPayload: Parameter + Size;
|
||||
/// Message fee type of outbound messages. This fee is paid on this chain.
|
||||
type OutboundMessageFee: Default
|
||||
+ From<u64>
|
||||
+ PartialOrd
|
||||
+ Parameter
|
||||
+ SaturatingAdd
|
||||
+ Zero
|
||||
+ Copy
|
||||
+ MaxEncodedLen;
|
||||
|
||||
/// Payload type of inbound messages. This payload is dispatched on this chain.
|
||||
type InboundPayload: Decode;
|
||||
/// Message fee type of inbound messages. This fee is paid on the bridged chain.
|
||||
type InboundMessageFee: Decode + Zero;
|
||||
/// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the
|
||||
/// bridged chain.
|
||||
type InboundRelayer: Parameter + MaxEncodedLen;
|
||||
@@ -170,16 +153,11 @@ pub mod pallet {
|
||||
/// Target header chain.
|
||||
type TargetHeaderChain: TargetHeaderChain<Self::OutboundPayload, Self::AccountId>;
|
||||
/// Message payload verifier.
|
||||
type LaneMessageVerifier: LaneMessageVerifier<
|
||||
Self::RuntimeOrigin,
|
||||
Self::OutboundPayload,
|
||||
Self::OutboundMessageFee,
|
||||
>;
|
||||
type LaneMessageVerifier: LaneMessageVerifier<Self::RuntimeOrigin, Self::OutboundPayload>;
|
||||
/// Message delivery payment.
|
||||
type MessageDeliveryAndDispatchPayment: MessageDeliveryAndDispatchPayment<
|
||||
Self::RuntimeOrigin,
|
||||
Self::AccountId,
|
||||
Self::OutboundMessageFee,
|
||||
>;
|
||||
/// Handler for accepted messages.
|
||||
type OnMessageAccepted: OnMessageAccepted;
|
||||
@@ -189,19 +167,17 @@ pub mod pallet {
|
||||
// Types that are used by inbound_lane (on target chain).
|
||||
|
||||
/// Source header chain, as it is represented on target chain.
|
||||
type SourceHeaderChain: SourceHeaderChain<Self::InboundMessageFee>;
|
||||
type SourceHeaderChain: SourceHeaderChain;
|
||||
/// Message dispatch.
|
||||
type MessageDispatch: MessageDispatch<
|
||||
Self::AccountId,
|
||||
Self::InboundMessageFee,
|
||||
DispatchPayload = Self::InboundPayload,
|
||||
>;
|
||||
}
|
||||
|
||||
/// Shortcut to messages proof type for Config.
|
||||
type MessagesProofOf<T, I> = <<T as Config<I>>::SourceHeaderChain as SourceHeaderChain<
|
||||
<T as Config<I>>::InboundMessageFee,
|
||||
>>::MessagesProof;
|
||||
type MessagesProofOf<T, I> =
|
||||
<<T as Config<I>>::SourceHeaderChain as SourceHeaderChain>::MessagesProof;
|
||||
/// Shortcut to messages delivery proof type for Config.
|
||||
type MessagesDeliveryProofOf<T, I> =
|
||||
<<T as Config<I>>::TargetHeaderChain as TargetHeaderChain<
|
||||
@@ -241,101 +217,6 @@ pub mod pallet {
|
||||
<Self as OwnedBridgeModule<_>>::set_operating_mode(origin, operating_mode)
|
||||
}
|
||||
|
||||
/// Update pallet parameter.
|
||||
///
|
||||
/// May only be called either by root, or by `PalletOwner`.
|
||||
///
|
||||
/// The weight is: single read for permissions check + 2 writes for parameter value and
|
||||
/// event.
|
||||
#[pallet::weight((T::DbWeight::get().reads_writes(1, 2), DispatchClass::Operational))]
|
||||
pub fn update_pallet_parameter(
|
||||
origin: OriginFor<T>,
|
||||
parameter: T::Parameter,
|
||||
) -> DispatchResult {
|
||||
Self::ensure_owner_or_root(origin)?;
|
||||
parameter.save();
|
||||
Self::deposit_event(Event::ParameterUpdated { parameter });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send message over lane.
|
||||
#[pallet::weight(T::WeightInfo::send_message_weight(payload, T::DbWeight::get()))]
|
||||
pub fn send_message(
|
||||
origin: OriginFor<T>,
|
||||
lane_id: LaneId,
|
||||
payload: T::OutboundPayload,
|
||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
crate::send_message::<T, I>(origin, lane_id, payload, delivery_and_dispatch_fee).map(
|
||||
|sent_message| PostDispatchInfo {
|
||||
actual_weight: Some(sent_message.weight),
|
||||
pays_fee: Pays::Yes,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Pay additional fee for the message.
|
||||
#[pallet::weight(T::WeightInfo::maximal_increase_message_fee())]
|
||||
pub fn increase_message_fee(
|
||||
origin: OriginFor<T>,
|
||||
lane_id: LaneId,
|
||||
nonce: MessageNonce,
|
||||
additional_fee: T::OutboundMessageFee,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
Self::ensure_not_halted().map_err(Error::<T, I>::BridgeModule)?;
|
||||
// if someone tries to pay for already-delivered message, we're rejecting this intention
|
||||
// (otherwise this additional fee will be locked forever in relayers fund)
|
||||
//
|
||||
// if someone tries to pay for not-yet-sent message, we're rejecting this intention, or
|
||||
// we're risking to have mess in the storage
|
||||
let lane = outbound_lane::<T, I>(lane_id);
|
||||
ensure!(
|
||||
nonce > lane.data().latest_received_nonce,
|
||||
Error::<T, I>::MessageIsAlreadyDelivered
|
||||
);
|
||||
ensure!(
|
||||
nonce <= lane.data().latest_generated_nonce,
|
||||
Error::<T, I>::MessageIsNotYetSent
|
||||
);
|
||||
|
||||
// withdraw additional fee from submitter
|
||||
T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee(
|
||||
&origin,
|
||||
&additional_fee,
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Submitter can't pay additional fee {:?} for the message {:?}/{:?}: {:?}",
|
||||
additional_fee,
|
||||
lane_id,
|
||||
nonce,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::FailedToWithdrawMessageFee
|
||||
})?;
|
||||
|
||||
// and finally update fee in the storage
|
||||
let message_key = MessageKey { lane_id, nonce };
|
||||
let message_size = OutboundMessages::<T, I>::mutate(message_key, |message_data| {
|
||||
// saturating_add is fine here - overflow here means that someone controls all
|
||||
// chain funds, which shouldn't ever happen + `pay_delivery_and_dispatch_fee`
|
||||
// above will fail before we reach here
|
||||
let message_data = message_data.as_mut().expect(
|
||||
"the message is sent and not yet delivered; so it is in the storage; qed",
|
||||
);
|
||||
message_data.fee = message_data.fee.saturating_add(&additional_fee);
|
||||
message_data.payload.len()
|
||||
});
|
||||
|
||||
// compute actual dispatch weight that depends on the stored message size
|
||||
let actual_weight = T::WeightInfo::maximal_increase_message_fee()
|
||||
.min(T::WeightInfo::increase_message_fee(message_size as _));
|
||||
|
||||
Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee: Pays::Yes })
|
||||
}
|
||||
|
||||
/// Receive messages proof from bridged chain.
|
||||
///
|
||||
/// The weight of the call assumes that the transaction always brings outbound lane
|
||||
@@ -378,7 +259,6 @@ pub mod pallet {
|
||||
// verify messages proof && convert proof into messages
|
||||
let messages = verify_and_decode_messages_proof::<
|
||||
T::SourceHeaderChain,
|
||||
T::InboundMessageFee,
|
||||
T::InboundPayload,
|
||||
>(proof, messages_count)
|
||||
.map_err(|err| {
|
||||
@@ -636,8 +516,6 @@ pub mod pallet {
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
pub enum Event<T: Config<I>, I: 'static = ()> {
|
||||
/// Pallet parameter has been updated.
|
||||
ParameterUpdated { parameter: T::Parameter },
|
||||
/// Message has been accepted and is waiting to be delivered.
|
||||
MessageAccepted { lane_id: LaneId, nonce: MessageNonce },
|
||||
/// Messages in the inclusive range have been delivered to the bridged chain.
|
||||
@@ -709,7 +587,7 @@ pub mod pallet {
|
||||
/// All queued outbound messages.
|
||||
#[pallet::storage]
|
||||
pub type OutboundMessages<T: Config<I>, I: 'static = ()> =
|
||||
StorageMap<_, Blake2_128Concat, MessageKey, StoredMessageData<T, I>>;
|
||||
StorageMap<_, Blake2_128Concat, MessageKey, StoredMessagePayload<T, I>>;
|
||||
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
|
||||
@@ -744,10 +622,7 @@ pub mod pallet {
|
||||
|
||||
impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
/// Get stored data of the outbound message with given nonce.
|
||||
pub fn outbound_message_data(
|
||||
lane: LaneId,
|
||||
nonce: MessageNonce,
|
||||
) -> Option<MessageData<T::OutboundMessageFee>> {
|
||||
pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option<MessagePayload> {
|
||||
OutboundMessages::<T, I>::get(MessageKey { lane_id: lane, nonce }).map(Into::into)
|
||||
}
|
||||
|
||||
@@ -755,12 +630,11 @@ pub mod pallet {
|
||||
pub fn inbound_message_data(
|
||||
lane: LaneId,
|
||||
payload: MessagePayload,
|
||||
outbound_details: OutboundMessageDetails<T::InboundMessageFee>,
|
||||
outbound_details: OutboundMessageDetails,
|
||||
) -> InboundMessageDetails {
|
||||
let mut dispatch_message = DispatchMessage {
|
||||
key: MessageKey { lane_id: lane, nonce: outbound_details.nonce },
|
||||
data: MessageData { payload, fee: outbound_details.delivery_and_dispatch_fee }
|
||||
.into(),
|
||||
data: payload.into(),
|
||||
};
|
||||
InboundMessageDetails {
|
||||
dispatch_weight: T::MessageDispatch::dispatch_weight(&mut dispatch_message),
|
||||
@@ -769,12 +643,8 @@ pub mod pallet {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I>
|
||||
bp_messages::source_chain::MessagesBridge<
|
||||
T::RuntimeOrigin,
|
||||
T::OutboundMessageFee,
|
||||
T::OutboundPayload,
|
||||
> for Pallet<T, I>
|
||||
impl<T, I> bp_messages::source_chain::MessagesBridge<T::RuntimeOrigin, T::OutboundPayload>
|
||||
for Pallet<T, I>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
@@ -785,9 +655,8 @@ where
|
||||
sender: T::RuntimeOrigin,
|
||||
lane: LaneId,
|
||||
message: T::OutboundPayload,
|
||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||
) -> Result<SendMessageArtifacts, Self::Error> {
|
||||
crate::send_message::<T, I>(sender, lane, message, delivery_and_dispatch_fee)
|
||||
crate::send_message::<T, I>(sender, lane, message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,21 +665,14 @@ fn send_message<T: Config<I>, I: 'static>(
|
||||
submitter: T::RuntimeOrigin,
|
||||
lane_id: LaneId,
|
||||
payload: T::OutboundPayload,
|
||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||
) -> sp_std::result::Result<
|
||||
SendMessageArtifacts,
|
||||
sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>,
|
||||
> {
|
||||
ensure_normal_operating_mode::<T, I>()?;
|
||||
|
||||
// the most lightweigh check is the message size check
|
||||
ensure!(
|
||||
payload.size() <= T::MaximalOutboundPayloadSize::get(),
|
||||
Error::<T, I>::MessageIsTooLarge,
|
||||
);
|
||||
|
||||
// initially, actual (post-dispatch) weight is equal to pre-dispatch weight
|
||||
let mut actual_weight = T::WeightInfo::send_message_weight(&payload, T::DbWeight::get());
|
||||
let mut actual_weight = frame_support::weights::Weight::zero(); // TODO (https://github.com/paritytech/parity-bridges-common/issues/1647): remove this
|
||||
|
||||
// let's first check if message can be delivered to target chain
|
||||
T::TargetHeaderChain::verify_message(&payload).map_err(|err| {
|
||||
@@ -826,46 +688,28 @@ fn send_message<T: Config<I>, I: 'static>(
|
||||
|
||||
// now let's enforce any additional lane rules
|
||||
let mut lane = outbound_lane::<T, I>(lane_id);
|
||||
T::LaneMessageVerifier::verify_message(
|
||||
&submitter,
|
||||
&delivery_and_dispatch_fee,
|
||||
&lane_id,
|
||||
&lane.data(),
|
||||
&payload,
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Message to lane {:?} is rejected by lane verifier: {:?}",
|
||||
lane_id,
|
||||
err,
|
||||
);
|
||||
T::LaneMessageVerifier::verify_message(&submitter, &lane_id, &lane.data(), &payload).map_err(
|
||||
|err| {
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Message to lane {:?} is rejected by lane verifier: {:?}",
|
||||
lane_id,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::MessageRejectedByLaneVerifier
|
||||
})?;
|
||||
|
||||
// let's withdraw delivery and dispatch fee from submitter
|
||||
T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee(
|
||||
&submitter,
|
||||
&delivery_and_dispatch_fee,
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Message to lane {:?} is rejected because submitter is unable to pay fee {:?}: {:?}",
|
||||
lane_id,
|
||||
delivery_and_dispatch_fee,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::FailedToWithdrawMessageFee
|
||||
})?;
|
||||
Error::<T, I>::MessageRejectedByLaneVerifier
|
||||
},
|
||||
)?;
|
||||
|
||||
// finally, save message in outbound storage and emit event
|
||||
let encoded_payload = payload.encode();
|
||||
let encoded_payload_len = encoded_payload.len();
|
||||
let nonce =
|
||||
lane.send_message(MessageData { payload: encoded_payload, fee: delivery_and_dispatch_fee });
|
||||
ensure!(
|
||||
encoded_payload_len <= T::MaximalOutboundPayloadSize::get() as usize,
|
||||
Error::<T, I>::MessageIsTooLarge
|
||||
);
|
||||
let nonce = lane.send_message(encoded_payload);
|
||||
|
||||
// Guaranteed to be called outside only when the message is accepted.
|
||||
// We assume that the maximum weight call back used is `single_message_callback_overhead`, so do
|
||||
// not perform complex db operation in callback. If you want to, put these magic logic in
|
||||
@@ -920,32 +764,26 @@ fn send_message<T: Config<I>, I: 'static>(
|
||||
Ok(SendMessageArtifacts { nonce, weight: actual_weight })
|
||||
}
|
||||
|
||||
/// Calculate the relayers rewards
|
||||
/// Calculate the number of messages that the relayers have delivered.
|
||||
pub fn calc_relayers_rewards<T, I>(
|
||||
lane_id: LaneId,
|
||||
messages_relayers: VecDeque<UnrewardedRelayer<T::AccountId>>,
|
||||
received_range: &RangeInclusive<MessageNonce>,
|
||||
) -> RelayersRewards<T::AccountId, T::OutboundMessageFee>
|
||||
) -> RelayersRewards<T::AccountId>
|
||||
where
|
||||
T: frame_system::Config + crate::Config<I>,
|
||||
I: 'static,
|
||||
{
|
||||
// remember to reward relayers that have delivered messages
|
||||
// this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain
|
||||
let mut relayers_rewards: RelayersRewards<_, T::OutboundMessageFee> = RelayersRewards::new();
|
||||
let mut relayers_rewards = RelayersRewards::new();
|
||||
for entry in messages_relayers {
|
||||
let nonce_begin = sp_std::cmp::max(entry.messages.begin, *received_range.start());
|
||||
let nonce_end = sp_std::cmp::min(entry.messages.end, *received_range.end());
|
||||
|
||||
// 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_reward = relayers_rewards.entry(entry.relayer).or_default();
|
||||
for nonce in nonce_begin..=nonce_end {
|
||||
let key = MessageKey { lane_id, nonce };
|
||||
let message_data = OutboundMessages::<T, I>::get(key)
|
||||
.expect("message was just confirmed; we never prune unconfirmed messages; qed");
|
||||
relayer_reward.reward = relayer_reward.reward.saturating_add(&message_data.fee);
|
||||
relayer_reward.messages += 1;
|
||||
if nonce_end >= nonce_begin {
|
||||
*relayers_rewards.entry(entry.relayer).or_default() += nonce_end - nonce_begin + 1;
|
||||
}
|
||||
}
|
||||
relayers_rewards
|
||||
@@ -995,7 +833,6 @@ struct RuntimeInboundLaneStorage<T: Config<I>, I: 'static = ()> {
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage<T, I> {
|
||||
type MessageFee = T::InboundMessageFee;
|
||||
type Relayer = T::InboundRelayer;
|
||||
|
||||
fn id(&self) -> LaneId {
|
||||
@@ -1041,8 +878,6 @@ struct RuntimeOutboundLaneStorage<T, I = ()> {
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage<T, I> {
|
||||
type MessageFee = T::OutboundMessageFee;
|
||||
|
||||
fn id(&self) -> LaneId {
|
||||
self.lane_id
|
||||
}
|
||||
@@ -1056,17 +891,20 @@ impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn message(&self, nonce: &MessageNonce) -> Option<MessageData<T::OutboundMessageFee>> {
|
||||
fn message(&self, nonce: &MessageNonce) -> Option<MessagePayload> {
|
||||
OutboundMessages::<T, I>::get(MessageKey { lane_id: self.lane_id, nonce: *nonce })
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn save_message(
|
||||
&mut self,
|
||||
nonce: MessageNonce,
|
||||
mesage_data: MessageData<T::OutboundMessageFee>,
|
||||
) {
|
||||
OutboundMessages::<T, I>::insert(MessageKey { lane_id: self.lane_id, nonce }, mesage_data);
|
||||
fn save_message(&mut self, nonce: MessageNonce, message_payload: MessagePayload) {
|
||||
OutboundMessages::<T, I>::insert(
|
||||
MessageKey { lane_id: self.lane_id, nonce },
|
||||
StoredMessagePayload::<T, I>::try_from(message_payload).expect(
|
||||
"save_message is called after all checks in send_message; \
|
||||
send_message checks message size; \
|
||||
qed",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
fn remove_message(&mut self, nonce: &MessageNonce) {
|
||||
@@ -1075,10 +913,10 @@ impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag
|
||||
}
|
||||
|
||||
/// Verify messages proof and return proved messages with decoded payload.
|
||||
fn verify_and_decode_messages_proof<Chain: SourceHeaderChain<Fee>, Fee, DispatchPayload: Decode>(
|
||||
fn verify_and_decode_messages_proof<Chain: SourceHeaderChain, DispatchPayload: Decode>(
|
||||
proof: Chain::MessagesProof,
|
||||
messages_count: u32,
|
||||
) -> Result<ProvedMessages<DispatchMessage<DispatchPayload, Fee>>, Chain::Error> {
|
||||
) -> Result<ProvedMessages<DispatchMessage<DispatchPayload>>, Chain::Error> {
|
||||
// `receive_messages_proof` weight formula and `MaxUnconfirmedMessagesAtInboundLane` check
|
||||
// guarantees that the `message_count` is sane and Vec<Message> may be allocated.
|
||||
// (tx with too many messages will either be rejected from the pool, or will fail earlier)
|
||||
@@ -1102,12 +940,12 @@ fn verify_and_decode_messages_proof<Chain: SourceHeaderChain<Fee>, Fee, Dispatch
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::mock::{
|
||||
message, message_payload, run_test, unrewarded_relayer, Balance, RuntimeEvent as TestEvent,
|
||||
message, message_payload, run_test, unrewarded_relayer, RuntimeEvent as TestEvent,
|
||||
RuntimeOrigin, TestMessageDeliveryAndDispatchPayment, TestMessagesDeliveryProof,
|
||||
TestMessagesParameter, TestMessagesProof, TestOnDeliveryConfirmed1,
|
||||
TestOnDeliveryConfirmed2, TestOnMessageAccepted, TestRuntime, TokenConversionRate,
|
||||
MAX_OUTBOUND_PAYLOAD_SIZE, PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID,
|
||||
TEST_RELAYER_A, TEST_RELAYER_B,
|
||||
TestMessagesProof, TestOnDeliveryConfirmed1, TestOnDeliveryConfirmed2,
|
||||
TestOnMessageAccepted, TestRuntime, MAX_OUTBOUND_PAYLOAD_SIZE,
|
||||
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A,
|
||||
TEST_RELAYER_B,
|
||||
};
|
||||
use bp_messages::{UnrewardedRelayer, UnrewardedRelayersState};
|
||||
use bp_test_utils::generate_owned_bridge_module_tests;
|
||||
@@ -1146,15 +984,13 @@ mod tests {
|
||||
|
||||
let message_nonce =
|
||||
outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_generated_nonce + 1;
|
||||
let weight = Pallet::<TestRuntime>::send_message(
|
||||
let weight = send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
REGULAR_PAYLOAD.declared_weight.ref_time(),
|
||||
)
|
||||
.expect("send_message has failed")
|
||||
.actual_weight
|
||||
.expect("send_message always returns Some");
|
||||
.weight;
|
||||
|
||||
// check event with assigned nonce
|
||||
assert_eq!(
|
||||
@@ -1169,12 +1005,6 @@ mod tests {
|
||||
}],
|
||||
);
|
||||
|
||||
// check that fee has been withdrawn from submitter
|
||||
assert!(TestMessageDeliveryAndDispatchPayment::is_fee_paid(
|
||||
1,
|
||||
REGULAR_PAYLOAD.declared_weight.ref_time()
|
||||
));
|
||||
|
||||
weight
|
||||
}
|
||||
|
||||
@@ -1217,102 +1047,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pallet_parameter_may_be_updated_by_root() {
|
||||
run_test(|| {
|
||||
get_ready_for_events();
|
||||
|
||||
let parameter = TestMessagesParameter::TokenConversionRate(10.into());
|
||||
assert_ok!(Pallet::<TestRuntime>::update_pallet_parameter(
|
||||
RuntimeOrigin::root(),
|
||||
parameter.clone(),
|
||||
));
|
||||
|
||||
assert_eq!(TokenConversionRate::get(), 10.into());
|
||||
assert_eq!(
|
||||
System::<TestRuntime>::events(),
|
||||
vec![EventRecord {
|
||||
phase: Phase::Initialization,
|
||||
event: TestEvent::Messages(Event::ParameterUpdated { parameter }),
|
||||
topics: vec![],
|
||||
}],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pallet_parameter_may_be_updated_by_owner() {
|
||||
run_test(|| {
|
||||
PalletOwner::<TestRuntime>::put(2);
|
||||
get_ready_for_events();
|
||||
|
||||
let parameter = TestMessagesParameter::TokenConversionRate(10.into());
|
||||
assert_ok!(Pallet::<TestRuntime>::update_pallet_parameter(
|
||||
RuntimeOrigin::signed(2),
|
||||
parameter.clone(),
|
||||
));
|
||||
|
||||
assert_eq!(TokenConversionRate::get(), 10.into());
|
||||
assert_eq!(
|
||||
System::<TestRuntime>::events(),
|
||||
vec![EventRecord {
|
||||
phase: Phase::Initialization,
|
||||
event: TestEvent::Messages(Event::ParameterUpdated { parameter }),
|
||||
topics: vec![],
|
||||
}],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pallet_parameter_cant_be_updated_by_arbitrary_submitter() {
|
||||
run_test(|| {
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::update_pallet_parameter(
|
||||
RuntimeOrigin::signed(2),
|
||||
TestMessagesParameter::TokenConversionRate(10.into()),
|
||||
),
|
||||
DispatchError::BadOrigin,
|
||||
);
|
||||
|
||||
PalletOwner::<TestRuntime>::put(2);
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::update_pallet_parameter(
|
||||
RuntimeOrigin::signed(1),
|
||||
TestMessagesParameter::TokenConversionRate(10.into()),
|
||||
),
|
||||
DispatchError::BadOrigin,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fixed_u128_works_as_i_think() {
|
||||
// this test is here just to be sure that conversion rate may be represented with FixedU128
|
||||
run_test(|| {
|
||||
use sp_runtime::{FixedPointNumber, FixedU128};
|
||||
|
||||
// 1:1 conversion that we use by default for testnets
|
||||
let rialto_token = 1u64;
|
||||
let rialto_token_in_millau_tokens =
|
||||
TokenConversionRate::get().saturating_mul_int(rialto_token);
|
||||
assert_eq!(rialto_token_in_millau_tokens, 1);
|
||||
|
||||
// let's say conversion rate is 1:1.7
|
||||
let conversion_rate = FixedU128::saturating_from_rational(170, 100);
|
||||
let rialto_tokens = 100u64;
|
||||
let rialto_tokens_in_millau_tokens = conversion_rate.saturating_mul_int(rialto_tokens);
|
||||
assert_eq!(rialto_tokens_in_millau_tokens, 170);
|
||||
|
||||
// let's say conversion rate is 1:0.25
|
||||
let conversion_rate = FixedU128::saturating_from_rational(25, 100);
|
||||
let rialto_tokens = 100u64;
|
||||
let rialto_tokens_in_millau_tokens = conversion_rate.saturating_mul_int(rialto_tokens);
|
||||
assert_eq!(rialto_tokens_in_millau_tokens, 25);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pallet_rejects_transactions_if_halted() {
|
||||
run_test(|| {
|
||||
@@ -1324,25 +1058,14 @@ mod tests {
|
||||
));
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::send_message(
|
||||
send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
REGULAR_PAYLOAD.declared_weight.ref_time(),
|
||||
),
|
||||
Error::<TestRuntime, ()>::NotOperatingNormally,
|
||||
);
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
1,
|
||||
),
|
||||
Error::<TestRuntime, ()>::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted),
|
||||
);
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::receive_messages_proof(
|
||||
RuntimeOrigin::signed(1),
|
||||
@@ -1389,22 +1112,14 @@ mod tests {
|
||||
);
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::send_message(
|
||||
send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
REGULAR_PAYLOAD.declared_weight.ref_time(),
|
||||
),
|
||||
Error::<TestRuntime, ()>::NotOperatingNormally,
|
||||
);
|
||||
|
||||
assert_ok!(Pallet::<TestRuntime>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
1,
|
||||
));
|
||||
|
||||
assert_ok!(Pallet::<TestRuntime>::receive_messages_proof(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_RELAYER_A,
|
||||
@@ -1451,25 +1166,23 @@ mod tests {
|
||||
.extra
|
||||
.extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]);
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::send_message(
|
||||
send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
message_payload.clone(),
|
||||
Balance::MAX,
|
||||
),
|
||||
Error::<TestRuntime, ()>::MessageIsTooLarge,
|
||||
);
|
||||
|
||||
// let's check that we're able to send `MAX_OUTBOUND_PAYLOAD_SIZE` messages
|
||||
while message_payload.size() > MAX_OUTBOUND_PAYLOAD_SIZE {
|
||||
while message_payload.encoded_size() as u32 > MAX_OUTBOUND_PAYLOAD_SIZE {
|
||||
message_payload.extra.pop();
|
||||
}
|
||||
assert_eq!(message_payload.size(), MAX_OUTBOUND_PAYLOAD_SIZE);
|
||||
assert_ok!(Pallet::<TestRuntime>::send_message(
|
||||
assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE);
|
||||
assert_ok!(send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
message_payload,
|
||||
Balance::MAX,
|
||||
),);
|
||||
})
|
||||
}
|
||||
@@ -1479,11 +1192,10 @@ mod tests {
|
||||
run_test(|| {
|
||||
// messages with this payload are rejected by target chain verifier
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::send_message(
|
||||
send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
PAYLOAD_REJECTED_BY_TARGET_CHAIN,
|
||||
PAYLOAD_REJECTED_BY_TARGET_CHAIN.declared_weight.ref_time(),
|
||||
),
|
||||
Error::<TestRuntime, ()>::MessageRejectedByChainVerifier,
|
||||
);
|
||||
@@ -1494,34 +1206,15 @@ mod tests {
|
||||
fn lane_verifier_rejects_invalid_message_in_send_message() {
|
||||
run_test(|| {
|
||||
// messages with zero fee are rejected by lane verifier
|
||||
let mut message = REGULAR_PAYLOAD;
|
||||
message.reject_by_lane_verifier = true;
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::send_message(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
0
|
||||
),
|
||||
send_message::<TestRuntime, ()>(RuntimeOrigin::signed(1), TEST_LANE_ID, message,),
|
||||
Error::<TestRuntime, ()>::MessageRejectedByLaneVerifier,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_send_fails_if_submitter_cant_pay_message_fee() {
|
||||
run_test(|| {
|
||||
TestMessageDeliveryAndDispatchPayment::reject_payments();
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::send_message(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
REGULAR_PAYLOAD.declared_weight.ref_time(),
|
||||
),
|
||||
Error::<TestRuntime, ()>::FailedToWithdrawMessageFee,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn receive_messages_proof_works() {
|
||||
run_test(|| {
|
||||
@@ -1665,17 +1358,15 @@ mod tests {
|
||||
#[test]
|
||||
fn receive_messages_delivery_proof_rewards_relayers() {
|
||||
run_test(|| {
|
||||
assert_ok!(Pallet::<TestRuntime>::send_message(
|
||||
assert_ok!(send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
1000,
|
||||
));
|
||||
assert_ok!(Pallet::<TestRuntime>::send_message(
|
||||
assert_ok!(send_message::<TestRuntime, ()>(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
REGULAR_PAYLOAD,
|
||||
2000,
|
||||
));
|
||||
|
||||
// this reports delivery of message 1 => reward is paid to TEST_RELAYER_A
|
||||
@@ -1697,8 +1388,8 @@ mod tests {
|
||||
..Default::default()
|
||||
},
|
||||
));
|
||||
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1000));
|
||||
assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 2000));
|
||||
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1));
|
||||
assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1));
|
||||
|
||||
// this reports delivery of both message 1 and message 2 => reward is paid only to
|
||||
// TEST_RELAYER_B
|
||||
@@ -1723,8 +1414,8 @@ mod tests {
|
||||
..Default::default()
|
||||
},
|
||||
));
|
||||
assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1000));
|
||||
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 2000));
|
||||
assert!(!TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_A, 1));
|
||||
assert!(TestMessageDeliveryAndDispatchPayment::is_reward_paid(TEST_RELAYER_B, 1));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1829,7 +1520,7 @@ mod tests {
|
||||
fn receive_messages_accepts_single_message_with_invalid_payload() {
|
||||
run_test(|| {
|
||||
let mut invalid_message = message(1, REGULAR_PAYLOAD);
|
||||
invalid_message.data.payload = Vec::new();
|
||||
invalid_message.payload = Vec::new();
|
||||
|
||||
assert_ok!(Pallet::<TestRuntime, ()>::receive_messages_proof(
|
||||
RuntimeOrigin::signed(1),
|
||||
@@ -1848,7 +1539,7 @@ mod tests {
|
||||
fn receive_messages_accepts_batch_with_message_with_invalid_payload() {
|
||||
run_test(|| {
|
||||
let mut invalid_message = message(2, REGULAR_PAYLOAD);
|
||||
invalid_message.data.payload = Vec::new();
|
||||
invalid_message.payload = Vec::new();
|
||||
|
||||
assert_ok!(Pallet::<TestRuntime, ()>::receive_messages_proof(
|
||||
RuntimeOrigin::signed(1),
|
||||
@@ -1884,73 +1575,6 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_message_fee_fails_if_message_is_already_delivered() {
|
||||
run_test(|| {
|
||||
send_regular_message();
|
||||
receive_messages_delivery_proof();
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime, ()>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
100,
|
||||
),
|
||||
Error::<TestRuntime, ()>::MessageIsAlreadyDelivered,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_message_fee_fails_if_message_is_not_yet_sent() {
|
||||
run_test(|| {
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime, ()>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
100,
|
||||
),
|
||||
Error::<TestRuntime, ()>::MessageIsNotYetSent,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_message_fee_fails_if_submitter_cant_pay_additional_fee() {
|
||||
run_test(|| {
|
||||
send_regular_message();
|
||||
|
||||
TestMessageDeliveryAndDispatchPayment::reject_payments();
|
||||
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime, ()>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
100,
|
||||
),
|
||||
Error::<TestRuntime, ()>::FailedToWithdrawMessageFee,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_message_fee_succeeds() {
|
||||
run_test(|| {
|
||||
send_regular_message();
|
||||
|
||||
assert_ok!(Pallet::<TestRuntime, ()>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
100,
|
||||
),);
|
||||
assert!(TestMessageDeliveryAndDispatchPayment::is_fee_paid(1, 100));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weight_refund_from_receive_messages_proof_works() {
|
||||
run_test(|| {
|
||||
@@ -2187,101 +1811,6 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_message_fee_weight_depends_on_message_size() {
|
||||
run_test(|| {
|
||||
let mut small_payload = message_payload(0, 100);
|
||||
let mut large_payload = message_payload(1, 100);
|
||||
small_payload.extra = vec![1; MAX_OUTBOUND_PAYLOAD_SIZE as usize / 10];
|
||||
large_payload.extra = vec![2; MAX_OUTBOUND_PAYLOAD_SIZE as usize / 5];
|
||||
|
||||
assert_ok!(Pallet::<TestRuntime>::send_message(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
small_payload,
|
||||
100,
|
||||
));
|
||||
assert_ok!(Pallet::<TestRuntime>::send_message(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
large_payload,
|
||||
100,
|
||||
));
|
||||
|
||||
let small_weight = Pallet::<TestRuntime>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
.expect("increase_message_fee has failed")
|
||||
.actual_weight
|
||||
.expect("increase_message_fee always returns Some");
|
||||
|
||||
let large_weight = Pallet::<TestRuntime>::increase_message_fee(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_LANE_ID,
|
||||
2,
|
||||
1,
|
||||
)
|
||||
.expect("increase_message_fee has failed")
|
||||
.actual_weight
|
||||
.expect("increase_message_fee always returns Some");
|
||||
|
||||
assert!(
|
||||
large_weight.ref_time() > small_weight.ref_time(),
|
||||
"Actual post-dispatch weigth for larger message {} must be larger than {} for small message",
|
||||
large_weight,
|
||||
small_weight,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weight_is_refunded_for_messages_that_are_not_pruned() {
|
||||
run_test(|| {
|
||||
// send first MAX messages - no messages are pruned
|
||||
let max_messages_to_prune = crate::mock::MaxMessagesToPruneAtOnce::get();
|
||||
let when_zero_messages_are_pruned = send_regular_message();
|
||||
let mut delivered_messages = DeliveredMessages::new(1, true);
|
||||
for _ in 1..max_messages_to_prune {
|
||||
assert_eq!(send_regular_message(), when_zero_messages_are_pruned);
|
||||
delivered_messages.note_dispatched_message(true);
|
||||
}
|
||||
|
||||
// confirm delivery of all sent messages
|
||||
assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof(
|
||||
RuntimeOrigin::signed(1),
|
||||
TestMessagesDeliveryProof(Ok((
|
||||
TEST_LANE_ID,
|
||||
InboundLaneData {
|
||||
last_confirmed_nonce: 1,
|
||||
relayers: vec![UnrewardedRelayer {
|
||||
relayer: 0,
|
||||
messages: delivered_messages,
|
||||
}]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
},
|
||||
))),
|
||||
UnrewardedRelayersState {
|
||||
unrewarded_relayer_entries: 1,
|
||||
total_messages: max_messages_to_prune,
|
||||
last_delivered_nonce: max_messages_to_prune,
|
||||
..Default::default()
|
||||
},
|
||||
));
|
||||
|
||||
// when next message is sent, MAX messages are pruned
|
||||
let weight_when_max_messages_are_pruned = send_regular_message();
|
||||
assert_eq!(
|
||||
weight_when_max_messages_are_pruned,
|
||||
when_zero_messages_are_pruned +
|
||||
crate::mock::DbWeight::get().writes(max_messages_to_prune),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_accepted_callbacks_are_called() {
|
||||
run_test(|| {
|
||||
@@ -2302,27 +1831,6 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_accepted_refunds_non_zero_weight() {
|
||||
run_test(|| {
|
||||
TestOnMessageAccepted::set_consumed_weight_per_message(
|
||||
crate::mock::DbWeight::get().writes(1),
|
||||
);
|
||||
let actual_callback_weight = send_regular_message();
|
||||
let pre_dispatch_weight = <TestRuntime as Config>::WeightInfo::send_message_weight(
|
||||
®ULAR_PAYLOAD,
|
||||
crate::mock::DbWeight::get(),
|
||||
);
|
||||
let prune_weight = crate::mock::DbWeight::get()
|
||||
.writes(<TestRuntime as Config>::MaxMessagesToPruneAtOnce::get());
|
||||
|
||||
assert_eq!(
|
||||
pre_dispatch_weight.saturating_sub(actual_callback_weight),
|
||||
crate::mock::DbWeight::get().reads(1).saturating_add(prune_weight)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn storage_keys_computed_properly() {
|
||||
assert_eq!(
|
||||
@@ -2360,9 +1868,6 @@ mod tests {
|
||||
nonce: 0,
|
||||
dispatch_weight: Weight::from_ref_time(0),
|
||||
size: 0,
|
||||
delivery_and_dispatch_fee: 0,
|
||||
dispatch_fee_payment:
|
||||
bp_runtime::messages::DispatchFeePayment::AtTargetChain,
|
||||
},
|
||||
),
|
||||
InboundMessageDetails { dispatch_weight: REGULAR_PAYLOAD.declared_weight },
|
||||
|
||||
@@ -26,10 +26,11 @@ use bp_messages::{
|
||||
OnMessageAccepted, TargetHeaderChain,
|
||||
},
|
||||
target_chain::{
|
||||
DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain,
|
||||
DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages,
|
||||
SourceHeaderChain,
|
||||
},
|
||||
DeliveredMessages, InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce,
|
||||
OutboundLaneData, Parameter as MessagesParameter, UnrewardedRelayer,
|
||||
DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload,
|
||||
OutboundLaneData, UnrewardedRelayer,
|
||||
};
|
||||
use bp_runtime::{messages::MessageDispatchResult, Size};
|
||||
use codec::{Decode, Encode};
|
||||
@@ -42,7 +43,7 @@ use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
testing::Header as SubstrateHeader,
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
FixedU128, Perbill,
|
||||
Perbill,
|
||||
};
|
||||
use std::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
@@ -55,6 +56,8 @@ pub type Balance = u64;
|
||||
pub struct TestPayload {
|
||||
/// Field that may be used to identify messages.
|
||||
pub id: u64,
|
||||
/// Reject this message by lane verifier?
|
||||
pub reject_by_lane_verifier: bool,
|
||||
/// Dispatch weight that is declared by the message sender.
|
||||
pub declared_weight: Weight,
|
||||
/// Message dispatch result.
|
||||
@@ -140,38 +143,20 @@ parameter_types! {
|
||||
pub const MaxMessagesToPruneAtOnce: u64 = 10;
|
||||
pub const MaxUnrewardedRelayerEntriesAtInboundLane: u64 = 16;
|
||||
pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 32;
|
||||
pub storage TokenConversionRate: FixedU128 = 1.into();
|
||||
pub const TestBridgedChainId: bp_runtime::ChainId = *b"test";
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)]
|
||||
pub enum TestMessagesParameter {
|
||||
TokenConversionRate(FixedU128),
|
||||
}
|
||||
|
||||
impl MessagesParameter for TestMessagesParameter {
|
||||
fn save(&self) {
|
||||
match *self {
|
||||
TestMessagesParameter::TokenConversionRate(conversion_rate) =>
|
||||
TokenConversionRate::set(&conversion_rate),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config for TestRuntime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type WeightInfo = ();
|
||||
type Parameter = TestMessagesParameter;
|
||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||
|
||||
type MaximalOutboundPayloadSize = frame_support::traits::ConstU32<MAX_OUTBOUND_PAYLOAD_SIZE>;
|
||||
type OutboundPayload = TestPayload;
|
||||
type OutboundMessageFee = TestMessageFee;
|
||||
|
||||
type InboundPayload = TestPayload;
|
||||
type InboundMessageFee = TestMessageFee;
|
||||
type InboundRelayer = TestRelayer;
|
||||
|
||||
type TargetHeaderChain = TestTargetHeaderChain;
|
||||
@@ -219,7 +204,7 @@ pub const REGULAR_PAYLOAD: TestPayload = message_payload(0, 50);
|
||||
pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = message_payload(1, 50);
|
||||
|
||||
/// Vec of proved messages, grouped by lane.
|
||||
pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages<Message<TestMessageFee>>)>;
|
||||
pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages<Message>)>;
|
||||
|
||||
/// Test messages proof.
|
||||
#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo)]
|
||||
@@ -233,14 +218,12 @@ impl Size for TestMessagesProof {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Result<Vec<Message<TestMessageFee>>, ()>> for TestMessagesProof {
|
||||
fn from(result: Result<Vec<Message<TestMessageFee>>, ()>) -> Self {
|
||||
impl From<Result<Vec<Message>, ()>> for TestMessagesProof {
|
||||
fn from(result: Result<Vec<Message>, ()>) -> Self {
|
||||
Self {
|
||||
result: result.map(|messages| {
|
||||
let mut messages_by_lane: BTreeMap<
|
||||
LaneId,
|
||||
ProvedLaneMessages<Message<TestMessageFee>>,
|
||||
> = BTreeMap::new();
|
||||
let mut messages_by_lane: BTreeMap<LaneId, ProvedLaneMessages<Message>> =
|
||||
BTreeMap::new();
|
||||
for message in messages {
|
||||
messages_by_lane.entry(message.key.lane_id).or_default().messages.push(message);
|
||||
}
|
||||
@@ -288,17 +271,16 @@ impl TargetHeaderChain<TestPayload, TestRelayer> for TestTargetHeaderChain {
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TestLaneMessageVerifier;
|
||||
|
||||
impl LaneMessageVerifier<RuntimeOrigin, TestPayload, TestMessageFee> for TestLaneMessageVerifier {
|
||||
impl LaneMessageVerifier<RuntimeOrigin, TestPayload> for TestLaneMessageVerifier {
|
||||
type Error = &'static str;
|
||||
|
||||
fn verify_message(
|
||||
_submitter: &RuntimeOrigin,
|
||||
delivery_and_dispatch_fee: &TestMessageFee,
|
||||
_lane: &LaneId,
|
||||
_lane_outbound_data: &OutboundLaneData,
|
||||
_payload: &TestPayload,
|
||||
payload: &TestPayload,
|
||||
) -> Result<(), Self::Error> {
|
||||
if *delivery_and_dispatch_fee != 0 {
|
||||
if !payload.reject_by_lane_verifier {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TEST_ERROR)
|
||||
@@ -311,18 +293,6 @@ impl LaneMessageVerifier<RuntimeOrigin, TestPayload, TestMessageFee> for TestLan
|
||||
pub struct TestMessageDeliveryAndDispatchPayment;
|
||||
|
||||
impl TestMessageDeliveryAndDispatchPayment {
|
||||
/// Reject all payments.
|
||||
pub fn reject_payments() {
|
||||
frame_support::storage::unhashed::put(b":reject-message-fee:", &true);
|
||||
}
|
||||
|
||||
/// Returns true if given fee has been paid by given submitter.
|
||||
pub fn is_fee_paid(submitter: AccountId, fee: TestMessageFee) -> bool {
|
||||
let raw_origin: Result<frame_system::RawOrigin<_>, _> =
|
||||
RuntimeOrigin::signed(submitter).into();
|
||||
frame_support::storage::unhashed::get(b":message-fee:") == Some((raw_origin.unwrap(), fee))
|
||||
}
|
||||
|
||||
/// Returns true if given relayer has been rewarded with given balance. The reward-paid flag is
|
||||
/// cleared after the call.
|
||||
pub fn is_reward_paid(relayer: AccountId, fee: TestMessageFee) -> bool {
|
||||
@@ -331,34 +301,21 @@ impl TestMessageDeliveryAndDispatchPayment {
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageDeliveryAndDispatchPayment<RuntimeOrigin, AccountId, TestMessageFee>
|
||||
impl MessageDeliveryAndDispatchPayment<RuntimeOrigin, AccountId>
|
||||
for TestMessageDeliveryAndDispatchPayment
|
||||
{
|
||||
type Error = &'static str;
|
||||
|
||||
fn pay_delivery_and_dispatch_fee(
|
||||
submitter: &RuntimeOrigin,
|
||||
fee: &TestMessageFee,
|
||||
) -> Result<(), Self::Error> {
|
||||
if frame_support::storage::unhashed::get(b":reject-message-fee:") == Some(true) {
|
||||
return Err(TEST_ERROR)
|
||||
}
|
||||
|
||||
let raw_origin: Result<frame_system::RawOrigin<_>, _> = submitter.clone().into();
|
||||
frame_support::storage::unhashed::put(b":message-fee:", &(raw_origin.unwrap(), fee));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pay_relayers_rewards(
|
||||
lane_id: LaneId,
|
||||
_lane_id: LaneId,
|
||||
message_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
|
||||
_confirmation_relayer: &AccountId,
|
||||
received_range: &RangeInclusive<MessageNonce>,
|
||||
) {
|
||||
let relayers_rewards =
|
||||
calc_relayers_rewards::<TestRuntime, ()>(lane_id, message_relayers, received_range);
|
||||
calc_relayers_rewards::<TestRuntime, ()>(message_relayers, received_range);
|
||||
for (relayer, reward) in &relayers_rewards {
|
||||
let key = (b":relayer-reward:", relayer, reward.reward).encode();
|
||||
let key = (b":relayer-reward:", relayer, reward).encode();
|
||||
frame_support::storage::unhashed::put(&key, &true);
|
||||
}
|
||||
}
|
||||
@@ -450,7 +407,7 @@ impl OnDeliveryConfirmed for TestOnDeliveryConfirmed2 {
|
||||
#[derive(Debug)]
|
||||
pub struct TestSourceHeaderChain;
|
||||
|
||||
impl SourceHeaderChain<TestMessageFee> for TestSourceHeaderChain {
|
||||
impl SourceHeaderChain for TestSourceHeaderChain {
|
||||
type Error = &'static str;
|
||||
|
||||
type MessagesProof = TestMessagesProof;
|
||||
@@ -458,7 +415,7 @@ impl SourceHeaderChain<TestMessageFee> for TestSourceHeaderChain {
|
||||
fn verify_messages_proof(
|
||||
proof: Self::MessagesProof,
|
||||
_messages_count: u32,
|
||||
) -> Result<ProvedMessages<Message<TestMessageFee>>, Self::Error> {
|
||||
) -> Result<ProvedMessages<Message>, Self::Error> {
|
||||
proof.result.map(|proof| proof.into_iter().collect()).map_err(|_| TEST_ERROR)
|
||||
}
|
||||
}
|
||||
@@ -467,10 +424,10 @@ impl SourceHeaderChain<TestMessageFee> for TestSourceHeaderChain {
|
||||
#[derive(Debug)]
|
||||
pub struct TestMessageDispatch;
|
||||
|
||||
impl MessageDispatch<AccountId, TestMessageFee> for TestMessageDispatch {
|
||||
impl MessageDispatch<AccountId> for TestMessageDispatch {
|
||||
type DispatchPayload = TestPayload;
|
||||
|
||||
fn dispatch_weight(message: &mut DispatchMessage<TestPayload, TestMessageFee>) -> Weight {
|
||||
fn dispatch_weight(message: &mut DispatchMessage<TestPayload>) -> Weight {
|
||||
match message.data.payload.as_ref() {
|
||||
Ok(payload) => payload.declared_weight,
|
||||
Err(_) => Weight::from_ref_time(0),
|
||||
@@ -479,7 +436,7 @@ impl MessageDispatch<AccountId, TestMessageFee> for TestMessageDispatch {
|
||||
|
||||
fn dispatch(
|
||||
_relayer_account: &AccountId,
|
||||
message: DispatchMessage<TestPayload, TestMessageFee>,
|
||||
message: DispatchMessage<TestPayload>,
|
||||
) -> MessageDispatchResult {
|
||||
match message.data.payload.as_ref() {
|
||||
Ok(payload) => payload.dispatch_result.clone(),
|
||||
@@ -489,25 +446,31 @@ impl MessageDispatch<AccountId, TestMessageFee> for TestMessageDispatch {
|
||||
}
|
||||
|
||||
/// Return test lane message with given nonce and payload.
|
||||
pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message<TestMessageFee> {
|
||||
Message { key: MessageKey { lane_id: TEST_LANE_ID, nonce }, data: message_data(payload) }
|
||||
pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message {
|
||||
Message { key: MessageKey { lane_id: TEST_LANE_ID, nonce }, payload: payload.encode() }
|
||||
}
|
||||
|
||||
/// Return valid outbound message data, constructed from given payload.
|
||||
pub fn outbound_message_data(payload: TestPayload) -> MessagePayload {
|
||||
payload.encode()
|
||||
}
|
||||
|
||||
/// Return valid inbound (dispatch) message data, constructed from given payload.
|
||||
pub fn inbound_message_data(payload: TestPayload) -> DispatchMessageData<TestPayload> {
|
||||
DispatchMessageData { payload: Ok(payload) }
|
||||
}
|
||||
|
||||
/// Constructs message payload using given arguments and zero unspent weight.
|
||||
pub const fn message_payload(id: u64, declared_weight: u64) -> TestPayload {
|
||||
TestPayload {
|
||||
id,
|
||||
reject_by_lane_verifier: false,
|
||||
declared_weight: Weight::from_ref_time(declared_weight),
|
||||
dispatch_result: dispatch_result(0),
|
||||
extra: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return message data with valid fee for given payload.
|
||||
pub fn message_data(payload: TestPayload) -> MessageData<TestMessageFee> {
|
||||
MessageData { payload: payload.encode(), fee: 1 }
|
||||
}
|
||||
|
||||
/// Returns message dispatch result with given unspent weight.
|
||||
pub const fn dispatch_result(unspent_weight: u64) -> MessageDispatchResult {
|
||||
MessageDispatchResult {
|
||||
|
||||
@@ -20,19 +20,14 @@ use crate::Config;
|
||||
|
||||
use bitvec::prelude::*;
|
||||
use bp_messages::{
|
||||
DeliveredMessages, DispatchResultsBitVec, LaneId, MessageData, MessageNonce, OutboundLaneData,
|
||||
UnrewardedRelayer,
|
||||
DeliveredMessages, DispatchResultsBitVec, LaneId, MessageNonce, MessagePayload,
|
||||
OutboundLaneData, UnrewardedRelayer,
|
||||
};
|
||||
use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};
|
||||
use frame_support::{traits::Get, RuntimeDebug};
|
||||
use scale_info::{Type, TypeInfo};
|
||||
use frame_support::{BoundedVec, RuntimeDebug};
|
||||
use sp_std::collections::vec_deque::VecDeque;
|
||||
|
||||
/// Outbound lane storage.
|
||||
pub trait OutboundLaneStorage {
|
||||
/// Delivery and dispatch fee type on source chain.
|
||||
type MessageFee;
|
||||
|
||||
/// Lane id.
|
||||
fn id(&self) -> LaneId;
|
||||
/// Get lane data from the storage.
|
||||
@@ -41,64 +36,15 @@ pub trait OutboundLaneStorage {
|
||||
fn set_data(&mut self, data: OutboundLaneData);
|
||||
/// Returns saved outbound message payload.
|
||||
#[cfg(test)]
|
||||
fn message(&self, nonce: &MessageNonce) -> Option<MessageData<Self::MessageFee>>;
|
||||
fn message(&self, nonce: &MessageNonce) -> Option<MessagePayload>;
|
||||
/// Save outbound message in the storage.
|
||||
fn save_message(&mut self, nonce: MessageNonce, message_data: MessageData<Self::MessageFee>);
|
||||
fn save_message(&mut self, nonce: MessageNonce, message_payload: MessagePayload);
|
||||
/// Remove outbound message from the storage.
|
||||
fn remove_message(&mut self, nonce: &MessageNonce);
|
||||
}
|
||||
|
||||
/// Outbound message data wrapper that implements `MaxEncodedLen`.
|
||||
///
|
||||
/// We have already had `MaxEncodedLen`-like functionality before, but its usage has
|
||||
/// been localized and we haven't been passing it everywhere. This wrapper allows us
|
||||
/// to avoid passing these generic bounds all over the code.
|
||||
///
|
||||
/// The encoding of this type matches encoding of the corresponding `MessageData`.
|
||||
#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)]
|
||||
pub struct StoredMessageData<T: Config<I>, I: 'static>(pub MessageData<T::OutboundMessageFee>);
|
||||
|
||||
impl<T: Config<I>, I: 'static> sp_std::ops::Deref for StoredMessageData<T, I> {
|
||||
type Target = MessageData<T::OutboundMessageFee>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> sp_std::ops::DerefMut for StoredMessageData<T, I> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> From<StoredMessageData<T, I>>
|
||||
for MessageData<T::OutboundMessageFee>
|
||||
{
|
||||
fn from(data: StoredMessageData<T, I>) -> Self {
|
||||
data.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> TypeInfo for StoredMessageData<T, I> {
|
||||
type Identity = Self;
|
||||
|
||||
fn type_info() -> Type {
|
||||
MessageData::<T::OutboundMessageFee>::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> EncodeLike<StoredMessageData<T, I>>
|
||||
for MessageData<T::OutboundMessageFee>
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> MaxEncodedLen for StoredMessageData<T, I> {
|
||||
fn max_encoded_len() -> usize {
|
||||
T::OutboundMessageFee::max_encoded_len()
|
||||
.saturating_add(T::MaximalOutboundPayloadSize::get() as usize)
|
||||
}
|
||||
}
|
||||
pub type StoredMessagePayload<T, I> = BoundedVec<u8, <T as Config<I>>::MaximalOutboundPayloadSize>;
|
||||
|
||||
/// Result of messages receival confirmation.
|
||||
#[derive(RuntimeDebug, PartialEq, Eq)]
|
||||
@@ -143,12 +89,12 @@ impl<S: OutboundLaneStorage> OutboundLane<S> {
|
||||
/// Send message over lane.
|
||||
///
|
||||
/// Returns new message nonce.
|
||||
pub fn send_message(&mut self, message_data: MessageData<S::MessageFee>) -> MessageNonce {
|
||||
pub fn send_message(&mut self, message_payload: MessagePayload) -> MessageNonce {
|
||||
let mut data = self.storage.data();
|
||||
let nonce = data.latest_generated_nonce + 1;
|
||||
data.latest_generated_nonce = nonce;
|
||||
|
||||
self.storage.save_message(nonce, message_data);
|
||||
self.storage.save_message(nonce, message_payload);
|
||||
self.storage.set_data(data);
|
||||
|
||||
nonce
|
||||
@@ -295,8 +241,8 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
mock::{
|
||||
message_data, run_test, unrewarded_relayer, TestRelayer, TestRuntime, REGULAR_PAYLOAD,
|
||||
TEST_LANE_ID,
|
||||
outbound_message_data, run_test, unrewarded_relayer, TestRelayer, TestRuntime,
|
||||
REGULAR_PAYLOAD, TEST_LANE_ID,
|
||||
},
|
||||
outbound_lane,
|
||||
};
|
||||
@@ -324,9 +270,9 @@ mod tests {
|
||||
) -> ReceivalConfirmationResult {
|
||||
run_test(|| {
|
||||
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
assert_eq!(lane.storage.data().latest_generated_nonce, 3);
|
||||
assert_eq!(lane.storage.data().latest_received_nonce, 0);
|
||||
let result = lane.confirm_delivery(3, latest_received_nonce, relayers);
|
||||
@@ -341,7 +287,7 @@ mod tests {
|
||||
run_test(|| {
|
||||
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||
assert_eq!(lane.storage.data().latest_generated_nonce, 0);
|
||||
assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 1);
|
||||
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
|
||||
assert!(lane.storage.message(&1).is_some());
|
||||
assert_eq!(lane.storage.data().latest_generated_nonce, 1);
|
||||
});
|
||||
@@ -351,9 +297,9 @@ mod tests {
|
||||
fn confirm_delivery_works() {
|
||||
run_test(|| {
|
||||
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||
assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 1);
|
||||
assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 2);
|
||||
assert_eq!(lane.send_message(message_data(REGULAR_PAYLOAD)), 3);
|
||||
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
|
||||
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2);
|
||||
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3);
|
||||
assert_eq!(lane.storage.data().latest_generated_nonce, 3);
|
||||
assert_eq!(lane.storage.data().latest_received_nonce, 0);
|
||||
assert_eq!(
|
||||
@@ -369,9 +315,9 @@ mod tests {
|
||||
fn confirm_delivery_rejects_nonce_lesser_than_latest_received() {
|
||||
run_test(|| {
|
||||
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
assert_eq!(lane.storage.data().latest_generated_nonce, 3);
|
||||
assert_eq!(lane.storage.data().latest_received_nonce, 0);
|
||||
assert_eq!(
|
||||
@@ -470,9 +416,9 @@ mod tests {
|
||||
assert_eq!(lane.prune_messages(100), 0);
|
||||
assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1);
|
||||
// when nothing is confirmed, nothing is pruned
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
assert_eq!(lane.prune_messages(100), 0);
|
||||
assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1);
|
||||
// after confirmation, some messages are received
|
||||
@@ -496,9 +442,9 @@ mod tests {
|
||||
fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() {
|
||||
run_test(|| {
|
||||
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
|
||||
assert_eq!(
|
||||
lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)),
|
||||
ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(3),
|
||||
|
||||
@@ -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: 2022-10-17, STEPS: 50, REPEAT: 20
|
||||
//! DATE: 2022-11-17, STEPS: 50, REPEAT: 20
|
||||
//! LOW RANGE: [], HIGH RANGE: []
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled
|
||||
//! CHAIN: Some("dev"), DB CACHE: 1024
|
||||
@@ -50,11 +50,6 @@ use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions needed for `pallet_bridge_messages`.
|
||||
pub trait WeightInfo {
|
||||
fn send_minimal_message_worst_case() -> Weight;
|
||||
fn send_1_kb_message_worst_case() -> Weight;
|
||||
fn send_16_kb_message_worst_case() -> Weight;
|
||||
fn maximal_increase_message_fee() -> Weight;
|
||||
fn increase_message_fee(i: u32) -> Weight;
|
||||
fn receive_single_message_proof() -> Weight;
|
||||
fn receive_two_messages_proof() -> Weight;
|
||||
fn receive_single_message_proof_with_outbound_lane_state() -> Weight;
|
||||
@@ -71,150 +66,98 @@ pub trait WeightInfo {
|
||||
/// Those weights are test only and must never be used in production.
|
||||
pub struct BridgeWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for BridgeWeight<T> {
|
||||
fn send_minimal_message_worst_case() -> Weight {
|
||||
Weight::from_ref_time(61_807_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(10 as u64))
|
||||
}
|
||||
fn send_1_kb_message_worst_case() -> Weight {
|
||||
Weight::from_ref_time(65_074_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(10 as u64))
|
||||
}
|
||||
fn send_16_kb_message_worst_case() -> Weight {
|
||||
Weight::from_ref_time(73_584_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(10 as u64))
|
||||
}
|
||||
fn maximal_increase_message_fee() -> Weight {
|
||||
Weight::from_ref_time(2_522_629_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn increase_message_fee(i: u32) -> Weight {
|
||||
Weight::from_ref_time(27_072_000 as u64)
|
||||
.saturating_add(Weight::from_ref_time(892 as u64).saturating_mul(i as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(3 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn receive_single_message_proof() -> Weight {
|
||||
Weight::from_ref_time(49_628_000 as u64)
|
||||
Weight::from_ref_time(50_596_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_two_messages_proof() -> Weight {
|
||||
Weight::from_ref_time(61_514_000 as u64)
|
||||
Weight::from_ref_time(77_041_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_single_message_proof_with_outbound_lane_state() -> Weight {
|
||||
Weight::from_ref_time(65_960_000 as u64)
|
||||
Weight::from_ref_time(58_331_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_single_message_proof_1_kb() -> Weight {
|
||||
Weight::from_ref_time(48_009_000 as u64)
|
||||
Weight::from_ref_time(48_061_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn receive_single_message_proof_16_kb() -> Weight {
|
||||
Weight::from_ref_time(100_439_000 as u64)
|
||||
Weight::from_ref_time(101_601_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn receive_single_prepaid_message_proof() -> Weight {
|
||||
Weight::from_ref_time(50_463_000 as u64)
|
||||
Weight::from_ref_time(49_646_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_delivery_proof_for_single_message() -> Weight {
|
||||
Weight::from_ref_time(57_383_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as u64))
|
||||
Weight::from_ref_time(55_108_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight {
|
||||
Weight::from_ref_time(62_003_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(6 as u64))
|
||||
Weight::from_ref_time(53_917_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight {
|
||||
Weight::from_ref_time(64_401_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(7 as u64))
|
||||
Weight::from_ref_time(57_335_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as u64))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
fn send_minimal_message_worst_case() -> Weight {
|
||||
Weight::from_ref_time(61_807_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(10 as u64))
|
||||
}
|
||||
fn send_1_kb_message_worst_case() -> Weight {
|
||||
Weight::from_ref_time(65_074_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(10 as u64))
|
||||
}
|
||||
fn send_16_kb_message_worst_case() -> Weight {
|
||||
Weight::from_ref_time(73_584_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(10 as u64))
|
||||
}
|
||||
fn maximal_increase_message_fee() -> Weight {
|
||||
Weight::from_ref_time(2_522_629_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(3 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn increase_message_fee(i: u32) -> Weight {
|
||||
Weight::from_ref_time(27_072_000 as u64)
|
||||
.saturating_add(Weight::from_ref_time(892 as u64).saturating_mul(i as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(3 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn receive_single_message_proof() -> Weight {
|
||||
Weight::from_ref_time(49_628_000 as u64)
|
||||
Weight::from_ref_time(50_596_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_two_messages_proof() -> Weight {
|
||||
Weight::from_ref_time(61_514_000 as u64)
|
||||
Weight::from_ref_time(77_041_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_single_message_proof_with_outbound_lane_state() -> Weight {
|
||||
Weight::from_ref_time(65_960_000 as u64)
|
||||
Weight::from_ref_time(58_331_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_single_message_proof_1_kb() -> Weight {
|
||||
Weight::from_ref_time(48_009_000 as u64)
|
||||
Weight::from_ref_time(48_061_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(3 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn receive_single_message_proof_16_kb() -> Weight {
|
||||
Weight::from_ref_time(100_439_000 as u64)
|
||||
Weight::from_ref_time(101_601_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(3 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
fn receive_single_prepaid_message_proof() -> Weight {
|
||||
Weight::from_ref_time(50_463_000 as u64)
|
||||
Weight::from_ref_time(49_646_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_delivery_proof_for_single_message() -> Weight {
|
||||
Weight::from_ref_time(57_383_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as u64))
|
||||
Weight::from_ref_time(55_108_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight {
|
||||
Weight::from_ref_time(62_003_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(6 as u64))
|
||||
Weight::from_ref_time(53_917_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight {
|
||||
Weight::from_ref_time(64_401_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(7 as u64))
|
||||
Weight::from_ref_time(57_335_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(3 as u64))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,82 +35,16 @@ const SIGNED_EXTENSIONS_SIZE: u32 = 1024;
|
||||
pub const EXTRA_STORAGE_PROOF_SIZE: u32 = 1024;
|
||||
|
||||
/// Ensure that weights from `WeightInfoExt` implementation are looking correct.
|
||||
pub fn ensure_weights_are_correct<W: WeightInfoExt>(
|
||||
expected_default_message_delivery_tx_weight: Weight,
|
||||
expected_additional_byte_delivery_weight: Weight,
|
||||
expected_messages_delivery_confirmation_tx_weight: Weight,
|
||||
expected_pay_inbound_dispatch_fee_weight: Weight,
|
||||
db_weight: RuntimeDbWeight,
|
||||
) {
|
||||
// verify `send_message` weight components
|
||||
assert_ne!(W::send_message_overhead(), Weight::zero());
|
||||
assert_ne!(W::send_message_size_overhead(0), Weight::zero());
|
||||
|
||||
pub fn ensure_weights_are_correct<W: WeightInfoExt>() {
|
||||
// verify `receive_messages_proof` weight components
|
||||
assert_ne!(W::receive_messages_proof_overhead(), Weight::zero());
|
||||
assert_ne!(W::receive_messages_proof_messages_overhead(1), Weight::zero());
|
||||
assert_ne!(W::receive_messages_proof_outbound_lane_state_overhead(), Weight::zero());
|
||||
assert_ne!(W::storage_proof_size_overhead(1), Weight::zero());
|
||||
|
||||
// verify that the hardcoded value covers `receive_messages_proof` weight
|
||||
let actual_single_regular_message_delivery_tx_weight = W::receive_messages_proof_weight(
|
||||
&PreComputedSize(
|
||||
(EXPECTED_DEFAULT_MESSAGE_LENGTH + W::expected_extra_storage_proof_size()) as usize,
|
||||
),
|
||||
1,
|
||||
Weight::zero(),
|
||||
);
|
||||
assert!(
|
||||
actual_single_regular_message_delivery_tx_weight
|
||||
.all_lte(expected_default_message_delivery_tx_weight),
|
||||
"Default message delivery transaction weight {} is larger than expected weight {}",
|
||||
actual_single_regular_message_delivery_tx_weight,
|
||||
expected_default_message_delivery_tx_weight,
|
||||
);
|
||||
|
||||
// verify that hardcoded value covers additional byte length of `receive_messages_proof` weight
|
||||
let actual_additional_byte_delivery_weight = W::storage_proof_size_overhead(1);
|
||||
assert!(
|
||||
actual_additional_byte_delivery_weight.all_lte(expected_additional_byte_delivery_weight),
|
||||
"Single additional byte delivery weight {} is larger than expected weight {}",
|
||||
actual_additional_byte_delivery_weight,
|
||||
expected_additional_byte_delivery_weight,
|
||||
);
|
||||
|
||||
// verify `receive_messages_delivery_proof` weight components
|
||||
assert_ne!(W::receive_messages_delivery_proof_overhead(), Weight::zero());
|
||||
assert_ne!(W::storage_proof_size_overhead(1), Weight::zero());
|
||||
|
||||
// `receive_messages_delivery_proof_messages_overhead` and
|
||||
// `receive_messages_delivery_proof_relayers_overhead` may return zero if rewards are not paid
|
||||
// during confirmations delivery, so we're not checking it here
|
||||
|
||||
// verify that the hardcoded value covers `receive_messages_delivery_proof` weight
|
||||
let actual_messages_delivery_confirmation_tx_weight = W::receive_messages_delivery_proof_weight(
|
||||
&PreComputedSize(W::expected_extra_storage_proof_size() as usize),
|
||||
&UnrewardedRelayersState {
|
||||
unrewarded_relayer_entries: 1,
|
||||
total_messages: 1,
|
||||
..Default::default()
|
||||
},
|
||||
db_weight,
|
||||
);
|
||||
assert!(
|
||||
actual_messages_delivery_confirmation_tx_weight
|
||||
.all_lte(expected_messages_delivery_confirmation_tx_weight),
|
||||
"Messages delivery confirmation transaction weight {} is larger than expected weight {}",
|
||||
actual_messages_delivery_confirmation_tx_weight,
|
||||
expected_messages_delivery_confirmation_tx_weight,
|
||||
);
|
||||
|
||||
// verify pay-dispatch-fee overhead for inbound messages
|
||||
let actual_pay_inbound_dispatch_fee_weight = W::pay_inbound_dispatch_fee_overhead();
|
||||
assert!(
|
||||
actual_pay_inbound_dispatch_fee_weight.all_lte(expected_pay_inbound_dispatch_fee_weight),
|
||||
"Weight {} of pay-dispatch-fee overhead for inbound messages is larger than expected weight {}",
|
||||
actual_pay_inbound_dispatch_fee_weight,
|
||||
expected_pay_inbound_dispatch_fee_weight,
|
||||
);
|
||||
}
|
||||
|
||||
/// Ensure that we're able to receive maximal (by-size and by-weight) message from other chain.
|
||||
@@ -198,17 +132,6 @@ pub trait WeightInfoExt: WeightInfo {
|
||||
|
||||
// Functions that are directly mapped to extrinsics weights.
|
||||
|
||||
/// Weight of message send extrinsic.
|
||||
fn send_message_weight(message: &impl Size, db_weight: RuntimeDbWeight) -> Weight {
|
||||
let transaction_overhead = Self::send_message_overhead();
|
||||
let message_size_overhead = Self::send_message_size_overhead(message.size());
|
||||
let call_back_overhead = Self::single_message_callback_overhead(db_weight);
|
||||
|
||||
transaction_overhead
|
||||
.saturating_add(message_size_overhead)
|
||||
.saturating_add(call_back_overhead)
|
||||
}
|
||||
|
||||
/// Weight of message delivery extrinsic.
|
||||
fn receive_messages_proof_weight(
|
||||
proof: &impl Size,
|
||||
@@ -274,20 +197,6 @@ pub trait WeightInfoExt: WeightInfo {
|
||||
|
||||
// Functions that are used by extrinsics weights formulas.
|
||||
|
||||
/// 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 =
|
||||
|
||||
Reference in New Issue
Block a user