1#![cfg(feature = "runtime-benchmarks")]
21
22use bp_messages::{
23 source_chain::FromBridgedChainMessagesDeliveryProof,
24 target_chain::FromBridgedChainMessagesProof, MessagePayload,
25};
26use bp_polkadot_core::parachains::ParaHash;
27use bp_runtime::{AccountIdOf, Chain, HashOf, Parachain};
28use codec::Encode;
29use frame_support::weights::Weight;
30use pallet_bridge_messages::{
31 benchmarking::{MessageDeliveryProofParams, MessageProofParams},
32 messages_generation::{
33 encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof,
34 prepare_messages_storage_proof,
35 },
36 BridgedChainOf, LaneIdOf, ThisChainOf,
37};
38use sp_runtime::traits::{Header, Zero};
39use sp_std::prelude::*;
40use xcm::latest::prelude::*;
41
42fn prepare_inbound_message<LaneId>(
44 params: &MessageProofParams<LaneId>,
45 successful_dispatch_message_generator: impl Fn(usize) -> MessagePayload,
46) -> MessagePayload {
47 let expected_size = params.proof_params.db_size.unwrap_or(0) as usize;
48
49 if !params.is_successful_dispatch_expected {
51 return vec![0u8; expected_size]
52 }
53
54 let msg = successful_dispatch_message_generator(expected_size);
56 assert!(
57 msg.len() >= expected_size,
58 "msg.len(): {} does not match expected_size: {}",
59 expected_size,
60 msg.len()
61 );
62 msg
63}
64
65pub fn prepare_message_proof_from_grandpa_chain<R, FI, MI>(
74 params: MessageProofParams<LaneIdOf<R, MI>>,
75 message_generator: impl Fn(usize) -> MessagePayload,
76) -> (FromBridgedChainMessagesProof<HashOf<BridgedChainOf<R, MI>>, LaneIdOf<R, MI>>, Weight)
77where
78 R: pallet_bridge_grandpa::Config<FI, BridgedChain = BridgedChainOf<R, MI>>
79 + pallet_bridge_messages::Config<
80 MI,
81 BridgedHeaderChain = pallet_bridge_grandpa::Pallet<R, FI>,
82 >,
83 FI: 'static,
84 MI: 'static,
85{
86 let (state_root, storage_proof) = prepare_messages_storage_proof::<
88 BridgedChainOf<R, MI>,
89 ThisChainOf<R, MI>,
90 LaneIdOf<R, MI>,
91 >(
92 params.lane,
93 params.message_nonces.clone(),
94 params.outbound_lane_data.clone(),
95 params.proof_params,
96 |_| prepare_inbound_message(¶ms, &message_generator),
97 encode_all_messages,
98 encode_lane_data,
99 false,
100 false,
101 );
102
103 let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::<R, FI>(state_root);
105
106 (
107 FromBridgedChainMessagesProof {
108 bridged_header_hash,
109 storage_proof,
110 lane: params.lane,
111 nonces_start: *params.message_nonces.start(),
112 nonces_end: *params.message_nonces.end(),
113 },
114 Weight::MAX / 1000,
115 )
116}
117
118pub fn prepare_message_proof_from_parachain<R, PI, MI>(
127 params: MessageProofParams<LaneIdOf<R, MI>>,
128 message_generator: impl Fn(usize) -> MessagePayload,
129) -> (FromBridgedChainMessagesProof<HashOf<BridgedChainOf<R, MI>>, LaneIdOf<R, MI>>, Weight)
130where
131 R: pallet_bridge_parachains::Config<PI> + pallet_bridge_messages::Config<MI>,
132 PI: 'static,
133 MI: 'static,
134 BridgedChainOf<R, MI>: Chain<Hash = ParaHash> + Parachain,
135{
136 let (state_root, storage_proof) = prepare_messages_storage_proof::<
138 BridgedChainOf<R, MI>,
139 ThisChainOf<R, MI>,
140 LaneIdOf<R, MI>,
141 >(
142 params.lane,
143 params.message_nonces.clone(),
144 params.outbound_lane_data.clone(),
145 params.proof_params,
146 |_| prepare_inbound_message(¶ms, &message_generator),
147 encode_all_messages,
148 encode_lane_data,
149 false,
150 false,
151 );
152
153 let (_, bridged_header_hash) =
155 insert_header_to_parachains_pallet::<R, PI, BridgedChainOf<R, MI>>(state_root);
156
157 (
158 FromBridgedChainMessagesProof {
159 bridged_header_hash,
160 storage_proof,
161 lane: params.lane,
162 nonces_start: *params.message_nonces.start(),
163 nonces_end: *params.message_nonces.end(),
164 },
165 Weight::MAX / 1000,
166 )
167}
168
169pub fn prepare_message_delivery_proof_from_grandpa_chain<R, FI, MI>(
175 params: MessageDeliveryProofParams<AccountIdOf<ThisChainOf<R, MI>>, LaneIdOf<R, MI>>,
176) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<R, MI>>, LaneIdOf<R, MI>>
177where
178 R: pallet_bridge_grandpa::Config<FI, BridgedChain = BridgedChainOf<R, MI>>
179 + pallet_bridge_messages::Config<
180 MI,
181 BridgedHeaderChain = pallet_bridge_grandpa::Pallet<R, FI>,
182 >,
183 FI: 'static,
184 MI: 'static,
185{
186 let lane = params.lane;
188 let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<
189 BridgedChainOf<R, MI>,
190 ThisChainOf<R, MI>,
191 LaneIdOf<R, MI>,
192 >(params.lane, params.inbound_lane_data, params.proof_params);
193
194 let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::<R, FI>(state_root);
196
197 FromBridgedChainMessagesDeliveryProof {
198 bridged_header_hash: bridged_header_hash.into(),
199 storage_proof,
200 lane,
201 }
202}
203
204pub fn prepare_message_delivery_proof_from_parachain<R, PI, MI>(
210 params: MessageDeliveryProofParams<AccountIdOf<ThisChainOf<R, MI>>, LaneIdOf<R, MI>>,
211) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChainOf<R, MI>>, LaneIdOf<R, MI>>
212where
213 R: pallet_bridge_parachains::Config<PI> + pallet_bridge_messages::Config<MI>,
214 PI: 'static,
215 MI: 'static,
216 BridgedChainOf<R, MI>: Chain<Hash = ParaHash> + Parachain,
217{
218 let lane = params.lane;
220 let (state_root, storage_proof) = prepare_message_delivery_storage_proof::<
221 BridgedChainOf<R, MI>,
222 ThisChainOf<R, MI>,
223 LaneIdOf<R, MI>,
224 >(params.lane, params.inbound_lane_data, params.proof_params);
225
226 let (_, bridged_header_hash) =
228 insert_header_to_parachains_pallet::<R, PI, BridgedChainOf<R, MI>>(state_root);
229
230 FromBridgedChainMessagesDeliveryProof {
231 bridged_header_hash: bridged_header_hash.into(),
232 storage_proof,
233 lane,
234 }
235}
236
237pub(crate) fn insert_header_to_grandpa_pallet<R, GI>(
239 state_root: bp_runtime::HashOf<R::BridgedChain>,
240) -> (bp_runtime::BlockNumberOf<R::BridgedChain>, bp_runtime::HashOf<R::BridgedChain>)
241where
242 R: pallet_bridge_grandpa::Config<GI>,
243 GI: 'static,
244 R::BridgedChain: bp_runtime::Chain,
245{
246 let bridged_block_number = Zero::zero();
247 let bridged_header = bp_runtime::HeaderOf::<R::BridgedChain>::new(
248 bridged_block_number,
249 Default::default(),
250 state_root,
251 Default::default(),
252 Default::default(),
253 );
254 let bridged_header_hash = bridged_header.hash();
255 pallet_bridge_grandpa::initialize_for_benchmarks::<R, GI>(bridged_header);
256 (bridged_block_number, bridged_header_hash)
257}
258
259pub(crate) fn insert_header_to_parachains_pallet<R, PI, PC>(
261 state_root: bp_runtime::HashOf<PC>,
262) -> (bp_runtime::BlockNumberOf<PC>, bp_runtime::HashOf<PC>)
263where
264 R: pallet_bridge_parachains::Config<PI>,
265 PI: 'static,
266 PC: Chain<Hash = ParaHash> + Parachain,
267{
268 let bridged_block_number = Zero::zero();
269 let bridged_header = bp_runtime::HeaderOf::<PC>::new(
270 bridged_block_number,
271 Default::default(),
272 state_root,
273 Default::default(),
274 Default::default(),
275 );
276 let bridged_header_hash = bridged_header.hash();
277 pallet_bridge_parachains::initialize_for_benchmarks::<R, PI, PC>(bridged_header);
278 (bridged_block_number, bridged_header_hash)
279}
280
281pub fn generate_xcm_builder_bridge_message_sample(
284 destination: InteriorLocation,
285) -> impl Fn(usize) -> MessagePayload {
286 move |expected_message_size| -> MessagePayload {
287 let location = xcm::VersionedInteriorLocation::from(destination.clone());
290 let location_encoded_size = location.encoded_size();
291
292 let xcm_size = expected_message_size.saturating_sub(location_encoded_size);
294 let xcm_data_size = xcm_size.saturating_sub(
295 Instruction::<()>::ExpectPallet {
297 index: 0,
298 name: vec![],
299 module_name: vec![],
300 crate_major: 0,
301 min_crate_minor: 0,
302 }
303 .encoded_size(),
304 );
305
306 tracing::trace!(
307 target: "runtime::bridge-benchmarks",
308 %expected_message_size, %location_encoded_size, %xcm_size, %xcm_data_size,
309 "generate_xcm_builder_bridge_message_sample"
310 );
311
312 let xcm = xcm::VersionedXcm::<()>::from(Xcm(vec![Instruction::<()>::ExpectPallet {
313 index: 0,
314 name: vec![42; xcm_data_size],
315 module_name: vec![],
316 crate_major: 0,
317 min_crate_minor: 0,
318 }]));
319
320 (location, xcm).encode().encode()
325 }
326}