referrerpolicy=no-referrer-when-downgrade

pallet_bridge_messages/
inbound_lane.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Bridges Common is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Everything about incoming messages receival.
18
19use crate::{BridgedChainOf, Config};
20
21use bp_messages::{
22	target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
23	ChainWithMessages, DeliveredMessages, InboundLaneData, LaneState, MessageKey, MessageNonce,
24	OutboundLaneData, ReceptionResult, UnrewardedRelayer,
25};
26use bp_runtime::AccountIdOf;
27use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};
28use scale_info::{Type, TypeInfo};
29use sp_runtime::RuntimeDebug;
30use sp_std::prelude::PartialEq;
31
32/// Inbound lane storage.
33pub trait InboundLaneStorage {
34	/// Id of relayer on source chain.
35	type Relayer: Clone + PartialEq;
36	/// Lane identifier type.
37	type LaneId: Encode;
38
39	/// Lane id.
40	fn id(&self) -> Self::LaneId;
41	/// Return maximal number of unrewarded relayer entries in inbound lane.
42	fn max_unrewarded_relayer_entries(&self) -> MessageNonce;
43	/// Return maximal number of unconfirmed messages in inbound lane.
44	fn max_unconfirmed_messages(&self) -> MessageNonce;
45	/// Get lane data from the storage.
46	fn data(&self) -> InboundLaneData<Self::Relayer>;
47	/// Update lane data in the storage.
48	fn set_data(&mut self, data: InboundLaneData<Self::Relayer>);
49	/// Purge lane data from the storage.
50	fn purge(self);
51}
52
53/// Inbound lane data wrapper that implements `MaxEncodedLen`.
54///
55/// We have already had `MaxEncodedLen`-like functionality before, but its usage has
56/// been localized and we haven't been passing bounds (maximal count of unrewarded relayer entries,
57/// maximal count of unconfirmed messages) everywhere. This wrapper allows us to avoid passing
58/// these generic bounds all over the code.
59///
60/// The encoding of this type matches encoding of the corresponding `MessageData`.
61#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)]
62pub struct StoredInboundLaneData<T: Config<I>, I: 'static>(
63	pub InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>,
64);
65
66impl<T: Config<I>, I: 'static> sp_std::ops::Deref for StoredInboundLaneData<T, I> {
67	type Target = InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>;
68
69	fn deref(&self) -> &Self::Target {
70		&self.0
71	}
72}
73
74impl<T: Config<I>, I: 'static> sp_std::ops::DerefMut for StoredInboundLaneData<T, I> {
75	fn deref_mut(&mut self) -> &mut Self::Target {
76		&mut self.0
77	}
78}
79
80impl<T: Config<I>, I: 'static> Default for StoredInboundLaneData<T, I> {
81	fn default() -> Self {
82		StoredInboundLaneData(Default::default())
83	}
84}
85
86impl<T: Config<I>, I: 'static> From<StoredInboundLaneData<T, I>>
87	for InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>
88{
89	fn from(data: StoredInboundLaneData<T, I>) -> Self {
90		data.0
91	}
92}
93
94impl<T: Config<I>, I: 'static> EncodeLike<StoredInboundLaneData<T, I>>
95	for InboundLaneData<AccountIdOf<BridgedChainOf<T, I>>>
96{
97}
98
99impl<T: Config<I>, I: 'static> TypeInfo for StoredInboundLaneData<T, I> {
100	type Identity = Self;
101
102	fn type_info() -> Type {
103		InboundLaneData::<AccountIdOf<BridgedChainOf<T, I>>>::type_info()
104	}
105}
106
107impl<T: Config<I>, I: 'static> MaxEncodedLen for StoredInboundLaneData<T, I> {
108	fn max_encoded_len() -> usize {
109		InboundLaneData::<AccountIdOf<BridgedChainOf<T, I>>>::encoded_size_hint(
110			BridgedChainOf::<T, I>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX as usize,
111		)
112		.unwrap_or(usize::MAX)
113	}
114}
115
116/// Inbound messages lane.
117pub struct InboundLane<S> {
118	storage: S,
119}
120
121impl<S: InboundLaneStorage> InboundLane<S> {
122	/// Create new inbound lane backed by given storage.
123	pub fn new(storage: S) -> Self {
124		InboundLane { storage }
125	}
126
127	/// Get lane state.
128	pub fn state(&self) -> LaneState {
129		self.storage.data().state
130	}
131
132	/// Returns storage reference.
133	pub fn storage(&self) -> &S {
134		&self.storage
135	}
136
137	/// Set lane state.
138	pub fn set_state(&mut self, state: LaneState) {
139		let mut data = self.storage.data();
140		data.state = state;
141		self.storage.set_data(data);
142	}
143
144	/// Receive state of the corresponding outbound lane.
145	pub fn receive_state_update(
146		&mut self,
147		outbound_lane_data: OutboundLaneData,
148	) -> Option<MessageNonce> {
149		let mut data = self.storage.data();
150		let last_delivered_nonce = data.last_delivered_nonce();
151
152		if outbound_lane_data.latest_received_nonce > last_delivered_nonce {
153			// this is something that should never happen if proofs are correct
154			return None
155		}
156		if outbound_lane_data.latest_received_nonce <= data.last_confirmed_nonce {
157			return None
158		}
159
160		let new_confirmed_nonce = outbound_lane_data.latest_received_nonce;
161		data.last_confirmed_nonce = new_confirmed_nonce;
162		// Firstly, remove all of the records where higher nonce <= new confirmed nonce
163		while data
164			.relayers
165			.front()
166			.map(|entry| entry.messages.end <= new_confirmed_nonce)
167			.unwrap_or(false)
168		{
169			data.relayers.pop_front();
170		}
171		// Secondly, update the next record with lower nonce equal to new confirmed nonce if needed.
172		// Note: There will be max. 1 record to update as we don't allow messages from relayers to
173		// overlap.
174		match data.relayers.front_mut() {
175			Some(entry) if entry.messages.begin <= new_confirmed_nonce => {
176				entry.messages.begin = new_confirmed_nonce + 1;
177			},
178			_ => {},
179		}
180
181		self.storage.set_data(data);
182		Some(outbound_lane_data.latest_received_nonce)
183	}
184
185	/// Receive new message.
186	pub fn receive_message<Dispatch: MessageDispatch<LaneId = S::LaneId>>(
187		&mut self,
188		relayer_at_bridged_chain: &S::Relayer,
189		nonce: MessageNonce,
190		message_data: DispatchMessageData<Dispatch::DispatchPayload>,
191	) -> ReceptionResult<Dispatch::DispatchLevelResult> {
192		let mut data = self.storage.data();
193		if Some(nonce) != data.last_delivered_nonce().checked_add(1) {
194			return ReceptionResult::InvalidNonce
195		}
196
197		// if there are more unrewarded relayer entries than we may accept, reject this message
198		if data.relayers.len() as MessageNonce >= self.storage.max_unrewarded_relayer_entries() {
199			return ReceptionResult::TooManyUnrewardedRelayers
200		}
201
202		// if there are more unconfirmed messages than we may accept, reject this message
203		let unconfirmed_messages_count = nonce.saturating_sub(data.last_confirmed_nonce);
204		if unconfirmed_messages_count > self.storage.max_unconfirmed_messages() {
205			return ReceptionResult::TooManyUnconfirmedMessages
206		}
207
208		// then, dispatch message
209		let dispatch_result = Dispatch::dispatch(DispatchMessage {
210			key: MessageKey { lane_id: self.storage.id(), nonce },
211			data: message_data,
212		});
213
214		// now let's update inbound lane storage
215		match data.relayers.back_mut() {
216			Some(entry) if entry.relayer == *relayer_at_bridged_chain => {
217				entry.messages.note_dispatched_message();
218			},
219			_ => {
220				data.relayers.push_back(UnrewardedRelayer {
221					relayer: relayer_at_bridged_chain.clone(),
222					messages: DeliveredMessages::new(nonce),
223				});
224			},
225		};
226		self.storage.set_data(data);
227
228		ReceptionResult::Dispatched(dispatch_result)
229	}
230
231	/// Purge lane state from the storage.
232	pub fn purge(self) {
233		self.storage.purge()
234	}
235}
236
237#[cfg(test)]
238mod tests {
239	use super::*;
240	use crate::{active_inbound_lane, lanes_manager::RuntimeInboundLaneStorage, tests::mock::*};
241	use bp_messages::UnrewardedRelayersState;
242
243	fn receive_regular_message(
244		lane: &mut InboundLane<RuntimeInboundLaneStorage<TestRuntime, ()>>,
245		nonce: MessageNonce,
246	) {
247		assert_eq!(
248			lane.receive_message::<TestMessageDispatch>(
249				&TEST_RELAYER_A,
250				nonce,
251				inbound_message_data(REGULAR_PAYLOAD)
252			),
253			ReceptionResult::Dispatched(dispatch_result(0))
254		);
255	}
256
257	#[test]
258	fn receive_status_update_ignores_status_from_the_future() {
259		run_test(|| {
260			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
261			receive_regular_message(&mut lane, 1);
262			assert_eq!(
263				lane.receive_state_update(OutboundLaneData {
264					latest_received_nonce: 10,
265					..Default::default()
266				}),
267				None,
268			);
269
270			assert_eq!(lane.storage.data().last_confirmed_nonce, 0);
271		});
272	}
273
274	#[test]
275	fn receive_status_update_ignores_obsolete_status() {
276		run_test(|| {
277			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
278			receive_regular_message(&mut lane, 1);
279			receive_regular_message(&mut lane, 2);
280			receive_regular_message(&mut lane, 3);
281			assert_eq!(
282				lane.receive_state_update(OutboundLaneData {
283					latest_received_nonce: 3,
284					..Default::default()
285				}),
286				Some(3),
287			);
288			assert_eq!(lane.storage.data().last_confirmed_nonce, 3);
289
290			assert_eq!(
291				lane.receive_state_update(OutboundLaneData {
292					latest_received_nonce: 3,
293					..Default::default()
294				}),
295				None,
296			);
297			assert_eq!(lane.storage.data().last_confirmed_nonce, 3);
298		});
299	}
300
301	#[test]
302	fn receive_status_update_works() {
303		run_test(|| {
304			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
305			receive_regular_message(&mut lane, 1);
306			receive_regular_message(&mut lane, 2);
307			receive_regular_message(&mut lane, 3);
308			assert_eq!(lane.storage.data().last_confirmed_nonce, 0);
309			assert_eq!(
310				lane.storage.data().relayers,
311				vec![unrewarded_relayer(1, 3, TEST_RELAYER_A)]
312			);
313
314			assert_eq!(
315				lane.receive_state_update(OutboundLaneData {
316					latest_received_nonce: 2,
317					..Default::default()
318				}),
319				Some(2),
320			);
321			assert_eq!(lane.storage.data().last_confirmed_nonce, 2);
322			assert_eq!(
323				lane.storage.data().relayers,
324				vec![unrewarded_relayer(3, 3, TEST_RELAYER_A)]
325			);
326
327			assert_eq!(
328				lane.receive_state_update(OutboundLaneData {
329					latest_received_nonce: 3,
330					..Default::default()
331				}),
332				Some(3),
333			);
334			assert_eq!(lane.storage.data().last_confirmed_nonce, 3);
335			assert_eq!(lane.storage.data().relayers, vec![]);
336		});
337	}
338
339	#[test]
340	fn receive_status_update_works_with_batches_from_relayers() {
341		run_test(|| {
342			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
343			let mut seed_storage_data = lane.storage.data();
344			// Prepare data
345			seed_storage_data.last_confirmed_nonce = 0;
346			seed_storage_data.relayers.push_back(unrewarded_relayer(1, 1, TEST_RELAYER_A));
347			// Simulate messages batch (2, 3, 4) from relayer #2
348			seed_storage_data.relayers.push_back(unrewarded_relayer(2, 4, TEST_RELAYER_B));
349			seed_storage_data.relayers.push_back(unrewarded_relayer(5, 5, TEST_RELAYER_C));
350			lane.storage.set_data(seed_storage_data);
351			// Check
352			assert_eq!(
353				lane.receive_state_update(OutboundLaneData {
354					latest_received_nonce: 3,
355					..Default::default()
356				}),
357				Some(3),
358			);
359			assert_eq!(lane.storage.data().last_confirmed_nonce, 3);
360			assert_eq!(
361				lane.storage.data().relayers,
362				vec![
363					unrewarded_relayer(4, 4, TEST_RELAYER_B),
364					unrewarded_relayer(5, 5, TEST_RELAYER_C)
365				]
366			);
367		});
368	}
369
370	#[test]
371	fn fails_to_receive_message_with_incorrect_nonce() {
372		run_test(|| {
373			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
374			assert_eq!(
375				lane.receive_message::<TestMessageDispatch>(
376					&TEST_RELAYER_A,
377					10,
378					inbound_message_data(REGULAR_PAYLOAD)
379				),
380				ReceptionResult::InvalidNonce
381			);
382			assert_eq!(lane.storage.data().last_delivered_nonce(), 0);
383		});
384	}
385
386	#[test]
387	fn fails_to_receive_messages_above_unrewarded_relayer_entries_limit_per_lane() {
388		run_test(|| {
389			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
390			let max_nonce = BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
391			for current_nonce in 1..max_nonce + 1 {
392				assert_eq!(
393					lane.receive_message::<TestMessageDispatch>(
394						&(TEST_RELAYER_A + current_nonce),
395						current_nonce,
396						inbound_message_data(REGULAR_PAYLOAD)
397					),
398					ReceptionResult::Dispatched(dispatch_result(0))
399				);
400			}
401			// Fails to dispatch new message from different than latest relayer.
402			assert_eq!(
403				lane.receive_message::<TestMessageDispatch>(
404					&(TEST_RELAYER_A + max_nonce + 1),
405					max_nonce + 1,
406					inbound_message_data(REGULAR_PAYLOAD)
407				),
408				ReceptionResult::TooManyUnrewardedRelayers,
409			);
410			// Fails to dispatch new messages from latest relayer. Prevents griefing attacks.
411			assert_eq!(
412				lane.receive_message::<TestMessageDispatch>(
413					&(TEST_RELAYER_A + max_nonce),
414					max_nonce + 1,
415					inbound_message_data(REGULAR_PAYLOAD)
416				),
417				ReceptionResult::TooManyUnrewardedRelayers,
418			);
419		});
420	}
421
422	#[test]
423	fn fails_to_receive_messages_above_unconfirmed_messages_limit_per_lane() {
424		run_test(|| {
425			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
426			let max_nonce = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
427			for current_nonce in 1..=max_nonce {
428				assert_eq!(
429					lane.receive_message::<TestMessageDispatch>(
430						&TEST_RELAYER_A,
431						current_nonce,
432						inbound_message_data(REGULAR_PAYLOAD)
433					),
434					ReceptionResult::Dispatched(dispatch_result(0))
435				);
436			}
437			// Fails to dispatch new message from different than latest relayer.
438			assert_eq!(
439				lane.receive_message::<TestMessageDispatch>(
440					&TEST_RELAYER_B,
441					max_nonce + 1,
442					inbound_message_data(REGULAR_PAYLOAD)
443				),
444				ReceptionResult::TooManyUnconfirmedMessages,
445			);
446			// Fails to dispatch new messages from latest relayer.
447			assert_eq!(
448				lane.receive_message::<TestMessageDispatch>(
449					&TEST_RELAYER_A,
450					max_nonce + 1,
451					inbound_message_data(REGULAR_PAYLOAD)
452				),
453				ReceptionResult::TooManyUnconfirmedMessages,
454			);
455		});
456	}
457
458	#[test]
459	fn correctly_receives_following_messages_from_two_relayers_alternately() {
460		run_test(|| {
461			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
462			assert_eq!(
463				lane.receive_message::<TestMessageDispatch>(
464					&TEST_RELAYER_A,
465					1,
466					inbound_message_data(REGULAR_PAYLOAD)
467				),
468				ReceptionResult::Dispatched(dispatch_result(0))
469			);
470			assert_eq!(
471				lane.receive_message::<TestMessageDispatch>(
472					&TEST_RELAYER_B,
473					2,
474					inbound_message_data(REGULAR_PAYLOAD)
475				),
476				ReceptionResult::Dispatched(dispatch_result(0))
477			);
478			assert_eq!(
479				lane.receive_message::<TestMessageDispatch>(
480					&TEST_RELAYER_A,
481					3,
482					inbound_message_data(REGULAR_PAYLOAD)
483				),
484				ReceptionResult::Dispatched(dispatch_result(0))
485			);
486			assert_eq!(
487				lane.storage.data().relayers,
488				vec![
489					unrewarded_relayer(1, 1, TEST_RELAYER_A),
490					unrewarded_relayer(2, 2, TEST_RELAYER_B),
491					unrewarded_relayer(3, 3, TEST_RELAYER_A)
492				]
493			);
494		});
495	}
496
497	#[test]
498	fn rejects_same_message_from_two_different_relayers() {
499		run_test(|| {
500			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
501			assert_eq!(
502				lane.receive_message::<TestMessageDispatch>(
503					&TEST_RELAYER_A,
504					1,
505					inbound_message_data(REGULAR_PAYLOAD)
506				),
507				ReceptionResult::Dispatched(dispatch_result(0))
508			);
509			assert_eq!(
510				lane.receive_message::<TestMessageDispatch>(
511					&TEST_RELAYER_B,
512					1,
513					inbound_message_data(REGULAR_PAYLOAD)
514				),
515				ReceptionResult::InvalidNonce,
516			);
517		});
518	}
519
520	#[test]
521	fn correct_message_is_processed_instantly() {
522		run_test(|| {
523			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
524			receive_regular_message(&mut lane, 1);
525			assert_eq!(lane.storage.data().last_delivered_nonce(), 1);
526		});
527	}
528
529	#[test]
530	fn unspent_weight_is_returned_by_receive_message() {
531		run_test(|| {
532			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
533			let mut payload = REGULAR_PAYLOAD;
534			*payload.dispatch_result.unspent_weight.ref_time_mut() = 1;
535			assert_eq!(
536				lane.receive_message::<TestMessageDispatch>(
537					&TEST_RELAYER_A,
538					1,
539					inbound_message_data(payload)
540				),
541				ReceptionResult::Dispatched(dispatch_result(1))
542			);
543		});
544	}
545
546	#[test]
547	fn first_message_is_confirmed_correctly() {
548		run_test(|| {
549			let mut lane = active_inbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
550			receive_regular_message(&mut lane, 1);
551			receive_regular_message(&mut lane, 2);
552			assert_eq!(
553				lane.receive_state_update(OutboundLaneData {
554					latest_received_nonce: 1,
555					..Default::default()
556				}),
557				Some(1),
558			);
559			assert_eq!(
560				inbound_unrewarded_relayers_state(test_lane_id()),
561				UnrewardedRelayersState {
562					unrewarded_relayer_entries: 1,
563					messages_in_oldest_entry: 1,
564					total_messages: 1,
565					last_delivered_nonce: 2,
566				},
567			);
568		});
569	}
570}