1use crate::test_data::{prepare_inbound_xcm, XcmAsPlainPayload};
20
21use bp_messages::{
22 source_chain::FromBridgedChainMessagesDeliveryProof,
23 target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneState, MessageNonce,
24 UnrewardedRelayersState,
25};
26use bp_runtime::{AccountIdOf, BlockNumberOf, Chain, HeaderOf, UnverifiedStorageProofParams};
27use bp_test_utils::make_default_justification;
28use codec::Encode;
29use pallet_bridge_grandpa::{BridgedChain, BridgedHeader};
30use sp_runtime::traits::Header as HeaderT;
31use xcm::latest::prelude::*;
32
33use crate::test_cases::helpers::InboundRelayerId;
34use bp_header_chain::{justification::GrandpaJustification, ChainWithGrandpa};
35use bp_messages::{DeliveredMessages, InboundLaneData, UnrewardedRelayer};
36use bp_runtime::HashOf;
37use pallet_bridge_messages::{
38 messages_generation::{
39 encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof,
40 prepare_messages_storage_proof,
41 },
42 BridgedChainOf, LaneIdOf,
43};
44use sp_runtime::DigestItem;
45
46pub fn make_complex_relayer_delivery_batch<Runtime, GPI, MPI>(
48 bridged_header: BridgedHeader<Runtime, GPI>,
49 bridged_justification: GrandpaJustification<BridgedHeader<Runtime, GPI>>,
50 message_proof: FromBridgedChainMessagesProof<
51 HashOf<BridgedChain<Runtime, GPI>>,
52 LaneIdOf<Runtime, MPI>,
53 >,
54 relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>,
55) -> pallet_utility::Call<Runtime>
56where
57 Runtime: pallet_bridge_grandpa::Config<GPI>
58 + pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload>
59 + pallet_utility::Config,
60 GPI: 'static,
61 MPI: 'static,
62 <Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>>
63 + From<pallet_bridge_messages::Call<Runtime, MPI>>,
64 BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>,
65{
66 let submit_grandpa = pallet_bridge_grandpa::Call::<Runtime, GPI>::submit_finality_proof {
67 finality_target: Box::new(bridged_header),
68 justification: bridged_justification,
69 };
70 let submit_message = pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof {
71 relayer_id_at_bridged_chain,
72 proof: Box::new(message_proof),
73 messages_count: 1,
74 dispatch_weight: Weight::from_parts(1000000000, 0),
75 };
76 pallet_utility::Call::<Runtime>::batch_all {
77 calls: vec![submit_grandpa.into(), submit_message.into()],
78 }
79}
80
81pub fn make_complex_relayer_confirmation_batch<Runtime, GPI, MPI>(
83 bridged_header: BridgedHeader<Runtime, GPI>,
84 bridged_justification: GrandpaJustification<BridgedHeader<Runtime, GPI>>,
85 message_delivery_proof: FromBridgedChainMessagesDeliveryProof<
86 HashOf<BridgedChain<Runtime, GPI>>,
87 LaneIdOf<Runtime, MPI>,
88 >,
89 relayers_state: UnrewardedRelayersState,
90) -> pallet_utility::Call<Runtime>
91where
92 Runtime: pallet_bridge_grandpa::Config<GPI>
93 + pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>
94 + pallet_utility::Config,
95 GPI: 'static,
96 MPI: 'static,
97 <Runtime as pallet_utility::Config>::RuntimeCall: From<pallet_bridge_grandpa::Call<Runtime, GPI>>
98 + From<pallet_bridge_messages::Call<Runtime, MPI>>,
99 BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>,
100{
101 let submit_grandpa = pallet_bridge_grandpa::Call::<Runtime, GPI>::submit_finality_proof {
102 finality_target: Box::new(bridged_header),
103 justification: bridged_justification,
104 };
105 let submit_message_delivery_proof =
106 pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof {
107 proof: message_delivery_proof,
108 relayers_state,
109 };
110 pallet_utility::Call::<Runtime>::batch_all {
111 calls: vec![submit_grandpa.into(), submit_message_delivery_proof.into()],
112 }
113}
114
115pub fn make_standalone_relayer_delivery_call<Runtime, GPI, MPI>(
117 message_proof: FromBridgedChainMessagesProof<
118 HashOf<BridgedChain<Runtime, GPI>>,
119 LaneIdOf<Runtime, MPI>,
120 >,
121 relayer_id_at_bridged_chain: InboundRelayerId<Runtime, MPI>,
122) -> Runtime::RuntimeCall
123where
124 Runtime: pallet_bridge_grandpa::Config<GPI>
125 + pallet_bridge_messages::Config<MPI, InboundPayload = XcmAsPlainPayload>,
126 MPI: 'static,
127 Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
128 BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>,
129{
130 pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof {
131 relayer_id_at_bridged_chain,
132 proof: Box::new(message_proof),
133 messages_count: 1,
134 dispatch_weight: Weight::from_parts(1000000000, 0),
135 }
136 .into()
137}
138
139pub fn make_standalone_relayer_confirmation_call<Runtime, GPI, MPI>(
141 message_delivery_proof: FromBridgedChainMessagesDeliveryProof<
142 HashOf<BridgedChain<Runtime, GPI>>,
143 LaneIdOf<Runtime, MPI>,
144 >,
145 relayers_state: UnrewardedRelayersState,
146) -> Runtime::RuntimeCall
147where
148 Runtime: pallet_bridge_grandpa::Config<GPI>
149 + pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>,
150 MPI: 'static,
151 Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
152 BridgedChainOf<Runtime, MPI>: Chain<Hash = HashOf<BridgedChain<Runtime, GPI>>>,
153{
154 pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof {
155 proof: message_delivery_proof,
156 relayers_state,
157 }
158 .into()
159}
160
161pub fn make_complex_relayer_delivery_proofs<BridgedChain, ThisChainWithMessages, LaneId>(
163 lane_id: LaneId,
164 xcm_message: Xcm<()>,
165 message_nonce: MessageNonce,
166 message_destination: Junctions,
167 header_number: BlockNumberOf<BridgedChain>,
168 is_minimal_call: bool,
169) -> (
170 HeaderOf<BridgedChain>,
171 GrandpaJustification<HeaderOf<BridgedChain>>,
172 FromBridgedChainMessagesProof<HashOf<BridgedChain>, LaneId>,
173)
174where
175 BridgedChain: ChainWithGrandpa,
176 ThisChainWithMessages: ChainWithMessages,
177 LaneId: Copy + Encode,
178{
179 let message_payload = prepare_inbound_xcm(xcm_message, message_destination);
181 let (state_root, storage_proof) =
183 prepare_messages_storage_proof::<BridgedChain, ThisChainWithMessages, LaneId>(
184 lane_id,
185 message_nonce..=message_nonce,
186 None,
187 UnverifiedStorageProofParams::from_db_size(message_payload.len() as u32),
188 |_| message_payload.clone(),
189 encode_all_messages,
190 encode_lane_data,
191 false,
192 false,
193 );
194
195 let (header, justification) = make_complex_bridged_grandpa_header_proof::<BridgedChain>(
196 state_root,
197 header_number,
198 is_minimal_call,
199 );
200
201 let message_proof = FromBridgedChainMessagesProof {
202 bridged_header_hash: header.hash(),
203 storage_proof,
204 lane: lane_id,
205 nonces_start: message_nonce,
206 nonces_end: message_nonce,
207 };
208
209 (header, justification, message_proof)
210}
211
212pub fn make_complex_relayer_confirmation_proofs<
214 BridgedChain,
215 ThisChainWithMessages,
216 InnerXcmRuntimeCall,
217 LaneId,
218>(
219 lane_id: LaneId,
220 header_number: BlockNumberOf<BridgedChain>,
221 relayer_id_at_this_chain: AccountIdOf<ThisChainWithMessages>,
222 relayers_state: UnrewardedRelayersState,
223) -> (
224 HeaderOf<BridgedChain>,
225 GrandpaJustification<HeaderOf<BridgedChain>>,
226 FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain>, LaneId>,
227)
228where
229 BridgedChain: ChainWithGrandpa,
230 ThisChainWithMessages: ChainWithMessages,
231 LaneId: Copy + Encode,
232{
233 let (state_root, storage_proof) =
235 prepare_message_delivery_storage_proof::<BridgedChain, ThisChainWithMessages, LaneId>(
236 lane_id,
237 InboundLaneData {
238 state: LaneState::Opened,
239 relayers: vec![
240 UnrewardedRelayer {
241 relayer: relayer_id_at_this_chain,
242 messages: DeliveredMessages::new(1)
243 };
244 relayers_state.unrewarded_relayer_entries as usize
245 ]
246 .into(),
247 last_confirmed_nonce: 1,
248 },
249 UnverifiedStorageProofParams::default(),
250 );
251
252 let (header, justification) =
253 make_complex_bridged_grandpa_header_proof::<BridgedChain>(state_root, header_number, false);
254
255 let message_delivery_proof = FromBridgedChainMessagesDeliveryProof {
256 bridged_header_hash: header.hash(),
257 storage_proof,
258 lane: lane_id,
259 };
260
261 (header, justification, message_delivery_proof)
262}
263
264pub fn make_complex_bridged_grandpa_header_proof<BridgedChain>(
266 state_root: HashOf<BridgedChain>,
267 header_number: BlockNumberOf<BridgedChain>,
268 is_minimal_call: bool,
269) -> (HeaderOf<BridgedChain>, GrandpaJustification<HeaderOf<BridgedChain>>)
270where
271 BridgedChain: ChainWithGrandpa,
272{
273 let mut header = bp_test_utils::test_header_with_root::<HeaderOf<BridgedChain>>(
274 header_number.into(),
275 state_root.into(),
276 );
277
278 let extra_bytes_required = maximal_expected_submit_finality_proof_call_size::<BridgedChain>()
281 .saturating_sub(header.encoded_size());
282 if !is_minimal_call {
283 header.digest_mut().push(DigestItem::Other(vec![42; extra_bytes_required]));
284 }
285
286 let justification = make_default_justification(&header);
287 (header, justification)
288}
289
290pub fn maximal_expected_submit_finality_proof_call_size<BridgedChain: ChainWithGrandpa>() -> usize {
292 bp_header_chain::max_expected_submit_finality_proof_arguments_size::<BridgedChain>(
293 false,
294 BridgedChain::MAX_AUTHORITIES_COUNT * 2 / 3 + 1,
295 ) as usize
296}