snowbridge_pallet_outbound_queue_v2/
benchmarking.rs1use super::*;
4
5use crate::fixture::make_submit_delivery_receipt_message;
6use bridge_hub_common::AggregateMessageOrigin;
7use codec::Encode;
8use frame_benchmarking::v2::*;
9use frame_support::{traits::Hooks, BoundedVec};
10use frame_system::RawOrigin;
11use snowbridge_outbound_queue_primitives::v2::{Command, Initializer, Message};
12use sp_core::{H160, H256};
13
14#[allow(unused_imports)]
15use crate::Pallet as OutboundQueue;
16
17#[benchmarks(
18 where
19 <T as Config>::MaxMessagePayloadSize: Get<u32>,
20 <T as frame_system::Config>::AccountId: From<[u8; 32]>,
21)]
22mod benchmarks {
23 use super::*;
24 use frame_support::assert_ok;
25
26 fn build_message<T: Config>() -> (Message, OutboundMessage) {
28 let commands = vec![Command::Upgrade {
29 impl_address: H160::zero(),
30 impl_code_hash: H256::zero(),
31 initializer: Initializer {
32 params: core::iter::repeat_with(|| 1_u8)
33 .take(<T as Config>::MaxMessagePayloadSize::get() as usize)
34 .collect(),
35 maximum_required_gas: 200_000,
36 },
37 }];
38 let message = Message {
39 origin: Default::default(),
40 id: H256::default(),
41 fee: 0,
42 commands: BoundedVec::try_from(commands.clone()).unwrap(),
43 };
44 let wrapped_commands: Vec<OutboundCommandWrapper> = commands
45 .into_iter()
46 .map(|command| OutboundCommandWrapper {
47 kind: command.index(),
48 gas: T::GasMeter::maximum_dispatch_gas_used_at_most(&command),
49 payload: command.abi_encode(),
50 })
51 .collect();
52 let outbound_message = OutboundMessage {
53 origin: Default::default(),
54 nonce: 1,
55 topic: H256::default(),
56 commands: wrapped_commands.clone().try_into().unwrap(),
57 };
58 (message, outbound_message)
59 }
60
61 fn initialize_worst_case<T: Config>() {
63 for _ in 0..T::MaxMessagesPerBlock::get() {
64 initialize_with_one_message::<T>();
65 }
66 }
67
68 fn initialize_with_one_message<T: Config>() {
70 let (message, outbound_message) = build_message::<T>();
71 let leaf = <T as Config>::Hashing::hash(&message.encode());
72 MessageLeaves::<T>::append(leaf);
73 Messages::<T>::append(outbound_message);
74 }
75
76 #[benchmark]
78 fn do_process_message() -> Result<(), BenchmarkError> {
79 let (enqueued_message, _) = build_message::<T>();
80 let origin = AggregateMessageOrigin::SnowbridgeV2([1; 32].into());
81 let message = enqueued_message.encode();
82
83 #[block]
84 {
85 let _ = OutboundQueue::<T>::do_process_message(origin, &message).unwrap();
86 }
87
88 assert_eq!(MessageLeaves::<T>::decode_len().unwrap(), 1);
89
90 Ok(())
91 }
92
93 #[benchmark]
95 fn commit() -> Result<(), BenchmarkError> {
96 initialize_worst_case::<T>();
97
98 #[block]
99 {
100 OutboundQueue::<T>::commit();
101 }
102
103 Ok(())
104 }
105
106 #[benchmark]
110 fn commit_single() -> Result<(), BenchmarkError> {
111 initialize_with_one_message::<T>();
112
113 #[block]
114 {
115 OutboundQueue::<T>::commit();
116 }
117
118 Ok(())
119 }
120
121 #[benchmark]
123 fn on_initialize() -> Result<(), BenchmarkError> {
124 initialize_worst_case::<T>();
125 #[block]
126 {
127 OutboundQueue::<T>::on_initialize(1_u32.into());
128 }
129 Ok(())
130 }
131
132 #[benchmark]
136 fn process() -> Result<(), BenchmarkError> {
137 initialize_worst_case::<T>();
138 let origin = AggregateMessageOrigin::SnowbridgeV2([1; 32].into());
139 let (enqueued_message, _) = build_message::<T>();
140 let message = enqueued_message.encode();
141
142 #[block]
143 {
144 OutboundQueue::<T>::on_initialize(1_u32.into());
145 for _ in 0..T::MaxMessagesPerBlock::get() {
146 OutboundQueue::<T>::do_process_message(origin, &message).unwrap();
147 }
148 OutboundQueue::<T>::commit();
149 }
150
151 Ok(())
152 }
153
154 #[benchmark]
155 fn submit_delivery_receipt() -> Result<(), BenchmarkError> {
156 let caller: T::AccountId = whitelisted_caller();
157
158 let message = make_submit_delivery_receipt_message();
159
160 T::Helper::initialize_storage(message.finalized_header, message.block_roots_root);
161
162 let receipt = DeliveryReceipt::try_from(&message.event.event_log).unwrap();
163
164 let order = PendingOrder {
165 nonce: receipt.nonce,
166 fee: 0,
167 block_number: frame_system::Pallet::<T>::current_block_number(),
168 };
169 <PendingOrders<T>>::insert(receipt.nonce, order);
170
171 #[block]
172 {
173 assert_ok!(OutboundQueue::<T>::submit_delivery_receipt(
174 RawOrigin::Signed(caller.clone()).into(),
175 Box::new(message.event),
176 ));
177 }
178
179 Ok(())
180 }
181
182 impl_benchmark_test_suite!(OutboundQueue, crate::mock::new_tester(), crate::mock::Test,);
183}