Skip to content

Commit

Permalink
removed extra messages benchmarks (paritytech#1279)
Browse files Browse the repository at this point in the history
  • Loading branch information
svyatonik authored and serban300 committed Apr 9, 2024
1 parent dba2e45 commit e60a092
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 400 deletions.
5 changes: 2 additions & 3 deletions bridges/modules/messages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,8 @@ Where:
*\* - In all benchmarks all received messages are dispatched and their dispatch cost is near to zero*

*\*\* - Trie leafs are assumed to have minimal values. The proof is derived from the minimal proof
by including more trie nodes. That's because according to `receive_message_proofs_with_large_leaf`
and `receive_message_proofs_with_extra_nodes` benchmarks, increasing proof by including more nodes
has slightly larger impact on performance than increasing values stored in leafs*.
by including more trie nodes. That's because according to our additioal benchmarks, increasing proof
by including more nodes has slightly larger impact on performance than increasing values stored in leafs*.

#### Weight formula

Expand Down
301 changes: 1 addition & 300 deletions bridges/modules/messages/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,7 @@ use bp_runtime::messages::DispatchFeePayment;
use frame_benchmarking::{account, benchmarks_instance_pallet};
use frame_support::{traits::Get, weights::Weight};
use frame_system::RawOrigin;
use sp_std::{
collections::{btree_map::BTreeMap, vec_deque::VecDeque},
convert::TryInto,
ops::RangeInclusive,
prelude::*,
};
use sp_std::{collections::vec_deque::VecDeque, convert::TryInto, ops::RangeInclusive, prelude::*};

/// Fee paid by submitter for single message delivery.
pub const MESSAGE_FEE: u64 = 100_000_000_000;
Expand Down Expand Up @@ -602,300 +597,6 @@ benchmarks_instance_pallet! {
ensure_relayer_rewarded::<T, I>(&relayer1_id, &relayer1_balance);
ensure_relayer_rewarded::<T, I>(&relayer2_id, &relayer2_balance);
}

//
// Benchmarks for manual checks.
//

// Benchmark `send_message` extrinsic with following conditions:
// * outbound lane already has state, so it needs to be read and decoded;
// * relayers fund account does not exists (in practice it needs to exist in production environment);
// * maximal number of messages is being pruned during the call;
// * message size varies from minimal to maximal for the target chain.
//
// Results of this benchmark may be used to check how message size affects `send_message` performance.
send_messages_of_various_lengths {
let i in 0..T::maximal_message_size().try_into().unwrap_or_default();

let lane_id = 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: i as _,
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 `receive_messages_proof` extrinsic with multiple minimal-weight messages and following conditions:
// * proof does not include outbound lane state proof;
// * inbound lane already has state, so it needs to be read and decoded;
// * message is successfully dispatched;
// * message requires all heavy checks done by dispatcher.
//
// This benchmarks gives us an approximation of single message delivery weight. It is similar to the
// `weight(receive_two_messages_proof) - weight(receive_single_message_proof)`. So it may be used
// to verify that the other approximation is correct.
receive_multiple_messages_proof {
let i in 1..64;

let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
let messages_count = i as _;

// mark messages 1..=20 as delivered
receive_messages::<T, I>(20);

let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: T::bench_lane_id(),
message_nonces: 21..=(20 + i as MessageNonce),
outbound_lane_data: None,
size: ProofSize::Minimal(EXPECTED_DEFAULT_MESSAGE_LENGTH),
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
});
}: receive_messages_proof(
RawOrigin::Signed(relayer_id_on_target),
relayer_id_on_source,
proof,
messages_count,
dispatch_weight
)
verify {
assert_eq!(
crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(),
20 + i as MessageNonce,
);
}

// Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions:
// * proof does not include outbound lane state proof;
// * inbound lane already has state, so it needs to be read and decoded;
// * message is successfully dispatched;
// * message requires all heavy checks done by dispatcher.
//
// Results of this benchmark may be used to check how proof size affects `receive_message_proof` performance.
receive_message_proofs_with_extra_nodes {
let i in 0..T::maximal_message_size();

let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
let messages_count = 1u32;

// mark messages 1..=20 as delivered
receive_messages::<T, I>(20);

let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: T::bench_lane_id(),
message_nonces: 21..=21,
outbound_lane_data: None,
size: ProofSize::HasExtraNodes(i as _),
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
});
}: receive_messages_proof(
RawOrigin::Signed(relayer_id_on_target),
relayer_id_on_source,
proof,
messages_count,
dispatch_weight
)
verify {
assert_eq!(
crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(),
21,
);
}

// Benchmark `receive_messages_proof` extrinsic with single minimal-weight message and following conditions:
// * proof does not include outbound lane state proof;
// * inbound lane already has state, so it needs to be read and decoded;
// * message is successfully dispatched;
// * message requires all heavy checks done by dispatcher.
//
// Results of this benchmark may be used to check how message size affects `receive_message_proof` performance.
receive_message_proofs_with_large_leaf {
let i in 0..T::maximal_message_size();

let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
let messages_count = 1u32;

// mark messages 1..=20 as delivered
receive_messages::<T, I>(20);

let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: T::bench_lane_id(),
message_nonces: 21..=21,
outbound_lane_data: None,
size: ProofSize::HasLargeLeaf(i as _),
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
});
}: receive_messages_proof(
RawOrigin::Signed(relayer_id_on_target),
relayer_id_on_source,
proof,
messages_count,
dispatch_weight
)
verify {
assert_eq!(
crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(),
21,
);
}

// Benchmark `receive_messages_proof` extrinsic with multiple minimal-weight messages and following conditions:
// * proof includes outbound lane state proof;
// * inbound lane already has state, so it needs to be read and decoded;
// * message is successfully dispatched;
// * message requires all heavy checks done by dispatcher.
//
// This benchmarks gives us an approximation of outbound lane state delivery weight. It is similar to the
// `weight(receive_single_message_proof_with_outbound_lane_state) - weight(receive_single_message_proof)`.
// So it may be used to verify that the other approximation is correct.
receive_multiple_messages_proof_with_outbound_lane_state {
let i in 1..128;

let relayer_id_on_source = T::bridged_relayer_id();
let relayer_id_on_target = account("relayer", 0, SEED);
let messages_count = i as _;

// mark messages 1..=20 as delivered
receive_messages::<T, I>(20);

let (proof, dispatch_weight) = T::prepare_message_proof(MessageProofParams {
lane: T::bench_lane_id(),
message_nonces: 21..=20 + i as MessageNonce,
outbound_lane_data: Some(OutboundLaneData {
oldest_unpruned_nonce: 21,
latest_received_nonce: 20,
latest_generated_nonce: 21,
}),
size: ProofSize::Minimal(0),
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
});
}: receive_messages_proof(
RawOrigin::Signed(relayer_id_on_target),
relayer_id_on_source,
proof,
messages_count,
dispatch_weight
)
verify {
assert_eq!(
crate::InboundLanes::<T, I>::get(&T::bench_lane_id()).last_delivered_nonce(),
20 + i as MessageNonce,
);
assert_eq!(
crate::Pallet::<T, I>::inbound_latest_confirmed_nonce(T::bench_lane_id()),
20,
);
}

// Benchmark `receive_messages_delivery_proof` extrinsic where single relayer delivers multiple messages.
receive_delivery_proof_for_multiple_messages_by_single_relayer {
// there actually should be used value of `MaxUnrewardedRelayerEntriesAtInboundLane` from the bridged
// chain, but we're more interested in additional weight/message than in max weight
let i in 1..T::MaxUnrewardedRelayerEntriesAtInboundLane::get()
.try_into()
.expect("Value of MaxUnrewardedRelayerEntriesAtInboundLane is too large");

let relayers_fund_id = crate::relayer_fund_account_id::<T::AccountId, T::AccountIdConverter>();
let relayer_id: T::AccountId = account("relayer", 0, SEED);
let relayer_balance = T::account_balance(&relayer_id);
T::endow_account(&relayers_fund_id);

// send messages that we're going to confirm
for _ in 1..=i {
send_regular_message::<T, I>();
}

let relayers_state = UnrewardedRelayersState {
unrewarded_relayer_entries: 1,
messages_in_oldest_entry: 1,
total_messages: i as MessageNonce,
};
let mut delivered_messages = DeliveredMessages::new(1, true);
for nonce in 2..=i {
delivered_messages.note_dispatched_message(true);
}
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
lane: T::bench_lane_id(),
inbound_lane_data: InboundLaneData {
relayers: vec![UnrewardedRelayer {
relayer: relayer_id.clone(),
messages: delivered_messages,
}].into_iter().collect(),
last_confirmed_nonce: 0,
},
size: ProofSize::Minimal(0),
});
}: receive_messages_delivery_proof(RawOrigin::Signed(relayer_id.clone()), proof, relayers_state)
verify {
ensure_relayer_rewarded::<T, I>(&relayer_id, &relayer_balance);
}

// Benchmark `receive_messages_delivery_proof` extrinsic where every relayer delivers single messages.
receive_delivery_proof_for_multiple_messages_by_multiple_relayers {
// there actually should be used value of `MaxUnconfirmedMessagesAtInboundLane` from the bridged
// chain, but we're more interested in additional weight/message than in max weight
let i in 1..T::MaxUnconfirmedMessagesAtInboundLane::get()
.try_into()
.expect("Value of MaxUnconfirmedMessagesAtInboundLane is too large ");

let relayers_fund_id = crate::relayer_fund_account_id::<T::AccountId, T::AccountIdConverter>();
let confirmation_relayer_id = account("relayer", 0, SEED);
let relayers: BTreeMap<T::AccountId, T::OutboundMessageFee> = (1..=i)
.map(|j| {
let relayer_id = account("relayer", j + 1, SEED);
let relayer_balance = T::account_balance(&relayer_id);
(relayer_id, relayer_balance)
})
.collect();
T::endow_account(&relayers_fund_id);

// send messages that we're going to confirm
for _ in 1..=i {
send_regular_message::<T, I>();
}

let relayers_state = UnrewardedRelayersState {
unrewarded_relayer_entries: i as MessageNonce,
messages_in_oldest_entry: 1,
total_messages: i as MessageNonce,
};
let proof = T::prepare_message_delivery_proof(MessageDeliveryProofParams {
lane: T::bench_lane_id(),
inbound_lane_data: InboundLaneData {
relayers: relayers
.keys()
.enumerate()
.map(|(j, relayer)| UnrewardedRelayer {
relayer: relayer.clone(),
messages: DeliveredMessages::new(j as MessageNonce + 1, true),
})
.collect(),
last_confirmed_nonce: 0,
},
size: ProofSize::Minimal(0),
});
}: receive_messages_delivery_proof(RawOrigin::Signed(confirmation_relayer_id), proof, relayers_state)
verify {
for (relayer_id, prev_balance) in relayers {
ensure_relayer_rewarded::<T, I>(&relayer_id, &prev_balance);
}
}
}

fn send_regular_message<T: Config<I>, I: 'static>() {
Expand Down
Loading

0 comments on commit e60a092

Please sign in to comment.