referrerpolicy=no-referrer-when-downgrade

pallet_bridge_messages/
outbound_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 outgoing messages sending.
18
19use crate::{Config, LOG_TARGET};
20
21use bp_messages::{
22	ChainWithMessages, DeliveredMessages, LaneState, MessageNonce, OutboundLaneData,
23	UnrewardedRelayer,
24};
25use codec::{Decode, DecodeWithMemTracking, Encode};
26use frame_support::{traits::Get, BoundedVec, PalletError};
27use scale_info::TypeInfo;
28use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive};
29use Debug;
30
31/// Outbound lane storage.
32pub trait OutboundLaneStorage {
33	/// Stored message payload type.
34	type StoredMessagePayload;
35	/// Lane identifier type.
36	type LaneId: Encode;
37
38	/// Lane id.
39	fn id(&self) -> Self::LaneId;
40	/// Get lane data from the storage.
41	fn data(&self) -> OutboundLaneData;
42	/// Update lane data in the storage.
43	fn set_data(&mut self, data: OutboundLaneData);
44	/// Returns saved outbound message payload.
45	#[cfg(test)]
46	fn message(&self, nonce: &MessageNonce) -> Option<Self::StoredMessagePayload>;
47	/// Save outbound message in the storage.
48	fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload);
49	/// Remove outbound message from the storage.
50	fn remove_message(&mut self, nonce: &MessageNonce);
51	/// Purge lane data from the storage.
52	fn purge(self);
53}
54
55/// Limit for the `StoredMessagePayload` vector.
56pub struct StoredMessagePayloadLimit<T, I>(PhantomData<(T, I)>);
57
58impl<T: Config<I>, I: 'static> Get<u32> for StoredMessagePayloadLimit<T, I> {
59	fn get() -> u32 {
60		T::BridgedChain::maximal_incoming_message_size()
61	}
62}
63
64/// Outbound message data wrapper that implements `MaxEncodedLen`.
65pub type StoredMessagePayload<T, I> = BoundedVec<u8, StoredMessagePayloadLimit<T, I>>;
66
67/// Result of messages receival confirmation.
68#[derive(Encode, Decode, DecodeWithMemTracking, Debug, PartialEq, Eq, PalletError, TypeInfo)]
69pub enum ReceptionConfirmationError {
70	/// Bridged chain is trying to confirm more messages than we have generated. May be a result
71	/// of invalid bridged chain storage.
72	FailedToConfirmFutureMessages,
73	/// The unrewarded relayers vec contains an empty entry. May be a result of invalid bridged
74	/// chain storage.
75	EmptyUnrewardedRelayerEntry,
76	/// The unrewarded relayers vec contains non-consecutive entries. May be a result of invalid
77	/// bridged chain storage.
78	NonConsecutiveUnrewardedRelayerEntries,
79	/// The chain has more messages that need to be confirmed than there is in the proof.
80	TryingToConfirmMoreMessagesThanExpected,
81}
82
83/// Outbound messages lane.
84#[derive(Debug, PartialEq, Eq)]
85pub struct OutboundLane<S> {
86	storage: S,
87}
88
89impl<S: OutboundLaneStorage> OutboundLane<S> {
90	/// Create new outbound lane backed by given storage.
91	pub fn new(storage: S) -> Self {
92		OutboundLane { storage }
93	}
94
95	/// Get this lane data.
96	pub fn data(&self) -> OutboundLaneData {
97		self.storage.data()
98	}
99
100	/// Get lane state.
101	pub fn state(&self) -> LaneState {
102		self.storage.data().state
103	}
104
105	/// Set lane state.
106	pub fn set_state(&mut self, state: LaneState) {
107		let mut data = self.storage.data();
108		data.state = state;
109		self.storage.set_data(data);
110	}
111
112	/// Return nonces of all currently queued messages.
113	pub fn queued_messages(&self) -> RangeInclusive<MessageNonce> {
114		let data = self.storage.data();
115		data.oldest_unpruned_nonce..=data.latest_generated_nonce
116	}
117
118	/// Send message over lane.
119	///
120	/// Returns new message nonce.
121	pub fn send_message(&mut self, message_payload: S::StoredMessagePayload) -> MessageNonce {
122		let mut data = self.storage.data();
123		let nonce = data.latest_generated_nonce + 1;
124		data.latest_generated_nonce = nonce;
125
126		self.storage.save_message(nonce, message_payload);
127		self.storage.set_data(data);
128
129		nonce
130	}
131
132	/// Confirm messages delivery.
133	pub fn confirm_delivery<RelayerId>(
134		&mut self,
135		max_allowed_messages: MessageNonce,
136		latest_delivered_nonce: MessageNonce,
137		relayers: &VecDeque<UnrewardedRelayer<RelayerId>>,
138	) -> Result<Option<DeliveredMessages>, ReceptionConfirmationError> {
139		let mut data = self.storage.data();
140		let confirmed_messages = DeliveredMessages {
141			begin: data.latest_received_nonce.saturating_add(1),
142			end: latest_delivered_nonce,
143		};
144		if confirmed_messages.total_messages() == 0 {
145			return Ok(None)
146		}
147		if confirmed_messages.end > data.latest_generated_nonce {
148			return Err(ReceptionConfirmationError::FailedToConfirmFutureMessages)
149		}
150		if confirmed_messages.total_messages() > max_allowed_messages {
151			// that the relayer has declared correct number of messages that the proof contains (it
152			// is checked outside of the function). But it may happen (but only if this/bridged
153			// chain storage is corrupted, though) that the actual number of confirmed messages if
154			// larger than declared. This would mean that 'reward loop' will take more time than the
155			// weight formula accounts, so we can't allow that.
156			tracing::trace!(
157				target: LOG_TARGET,
158				confirmed=%confirmed_messages.total_messages(),
159				max_allowed=%max_allowed_messages,
160				"Messages delivery proof contains too many messages to confirm"
161			);
162			return Err(ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected)
163		}
164
165		ensure_unrewarded_relayers_are_correct(confirmed_messages.end, relayers)?;
166
167		// prune all confirmed messages
168		for nonce in confirmed_messages.begin..=confirmed_messages.end {
169			self.storage.remove_message(&nonce);
170		}
171
172		data.latest_received_nonce = confirmed_messages.end;
173		data.oldest_unpruned_nonce = data.latest_received_nonce.saturating_add(1);
174		self.storage.set_data(data);
175
176		Ok(Some(confirmed_messages))
177	}
178
179	/// Remove message from the storage. Doesn't perform any checks.
180	pub fn remove_oldest_unpruned_message(&mut self) {
181		let mut data = self.storage.data();
182		self.storage.remove_message(&data.oldest_unpruned_nonce);
183		data.oldest_unpruned_nonce += 1;
184		self.storage.set_data(data);
185	}
186
187	/// Purge lane state from the storage.
188	pub fn purge(self) {
189		self.storage.purge()
190	}
191}
192
193/// Verifies unrewarded relayers vec.
194///
195/// Returns `Err(_)` if unrewarded relayers vec contains invalid data, meaning that the bridged
196/// chain has invalid runtime storage.
197fn ensure_unrewarded_relayers_are_correct<RelayerId>(
198	latest_received_nonce: MessageNonce,
199	relayers: &VecDeque<UnrewardedRelayer<RelayerId>>,
200) -> Result<(), ReceptionConfirmationError> {
201	let mut expected_entry_begin = relayers.front().map(|entry| entry.messages.begin);
202	for entry in relayers {
203		// unrewarded relayer entry must have at least 1 unconfirmed message
204		// (guaranteed by the `InboundLane::receive_message()`)
205		if entry.messages.end < entry.messages.begin {
206			return Err(ReceptionConfirmationError::EmptyUnrewardedRelayerEntry)
207		}
208		// every entry must confirm range of messages that follows previous entry range
209		// (guaranteed by the `InboundLane::receive_message()`)
210		if expected_entry_begin != Some(entry.messages.begin) {
211			return Err(ReceptionConfirmationError::NonConsecutiveUnrewardedRelayerEntries)
212		}
213		expected_entry_begin = entry.messages.end.checked_add(1);
214		// entry can't confirm messages larger than `inbound_lane_data.latest_received_nonce()`
215		// (guaranteed by the `InboundLane::receive_message()`)
216		if entry.messages.end > latest_received_nonce {
217			return Err(ReceptionConfirmationError::FailedToConfirmFutureMessages)
218		}
219	}
220
221	Ok(())
222}
223
224#[cfg(test)]
225mod tests {
226	use super::*;
227	use crate::{
228		active_outbound_lane,
229		tests::mock::{
230			outbound_message_data, run_test, test_lane_id, unrewarded_relayer, TestRelayer,
231			TestRuntime, REGULAR_PAYLOAD,
232		},
233	};
234	use sp_std::ops::RangeInclusive;
235
236	fn unrewarded_relayers(
237		nonces: RangeInclusive<MessageNonce>,
238	) -> VecDeque<UnrewardedRelayer<TestRelayer>> {
239		vec![unrewarded_relayer(*nonces.start(), *nonces.end(), 0)]
240			.into_iter()
241			.collect()
242	}
243
244	fn delivered_messages(nonces: RangeInclusive<MessageNonce>) -> DeliveredMessages {
245		DeliveredMessages { begin: *nonces.start(), end: *nonces.end() }
246	}
247
248	fn assert_3_messages_confirmation_fails(
249		latest_received_nonce: MessageNonce,
250		relayers: &VecDeque<UnrewardedRelayer<TestRelayer>>,
251	) -> Result<Option<DeliveredMessages>, ReceptionConfirmationError> {
252		run_test(|| {
253			let mut lane = active_outbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
254			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
255			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
256			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
257			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
258			assert_eq!(lane.storage.data().latest_received_nonce, 0);
259			let result = lane.confirm_delivery(3, latest_received_nonce, relayers);
260			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
261			assert_eq!(lane.storage.data().latest_received_nonce, 0);
262			result
263		})
264	}
265
266	#[test]
267	fn send_message_works() {
268		run_test(|| {
269			let mut lane = active_outbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
270			assert_eq!(lane.storage.data().latest_generated_nonce, 0);
271			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
272			assert!(lane.storage.message(&1).is_some());
273			assert_eq!(lane.storage.data().latest_generated_nonce, 1);
274		});
275	}
276
277	#[test]
278	fn confirm_delivery_works() {
279		run_test(|| {
280			let mut lane = active_outbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
281			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
282			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2);
283			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3);
284			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
285			assert_eq!(lane.storage.data().latest_received_nonce, 0);
286			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1);
287			assert_eq!(
288				lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
289				Ok(Some(delivered_messages(1..=3))),
290			);
291			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
292			assert_eq!(lane.storage.data().latest_received_nonce, 3);
293			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4);
294		});
295	}
296
297	#[test]
298	fn confirm_partial_delivery_works() {
299		run_test(|| {
300			let mut lane = active_outbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
301			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
302			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2);
303			assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3);
304			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
305			assert_eq!(lane.storage.data().latest_received_nonce, 0);
306			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1);
307
308			assert_eq!(
309				lane.confirm_delivery(3, 2, &unrewarded_relayers(1..=2)),
310				Ok(Some(delivered_messages(1..=2))),
311			);
312			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
313			assert_eq!(lane.storage.data().latest_received_nonce, 2);
314			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 3);
315
316			assert_eq!(
317				lane.confirm_delivery(3, 3, &unrewarded_relayers(3..=3)),
318				Ok(Some(delivered_messages(3..=3))),
319			);
320			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
321			assert_eq!(lane.storage.data().latest_received_nonce, 3);
322			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4);
323		});
324	}
325
326	#[test]
327	fn confirm_delivery_rejects_nonce_lesser_than_latest_received() {
328		run_test(|| {
329			let mut lane = active_outbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
330			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
331			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
332			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
333			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
334			assert_eq!(lane.storage.data().latest_received_nonce, 0);
335			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1);
336			assert_eq!(
337				lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
338				Ok(Some(delivered_messages(1..=3))),
339			);
340			assert_eq!(lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)), Ok(None),);
341			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
342			assert_eq!(lane.storage.data().latest_received_nonce, 3);
343			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4);
344
345			assert_eq!(lane.confirm_delivery(1, 2, &unrewarded_relayers(1..=1)), Ok(None),);
346			assert_eq!(lane.storage.data().latest_generated_nonce, 3);
347			assert_eq!(lane.storage.data().latest_received_nonce, 3);
348			assert_eq!(lane.storage.data().oldest_unpruned_nonce, 4);
349		});
350	}
351
352	#[test]
353	fn confirm_delivery_rejects_nonce_larger_than_last_generated() {
354		assert_eq!(
355			assert_3_messages_confirmation_fails(10, &unrewarded_relayers(1..=10),),
356			Err(ReceptionConfirmationError::FailedToConfirmFutureMessages),
357		);
358	}
359
360	#[test]
361	fn confirm_delivery_fails_if_entry_confirms_future_messages() {
362		assert_eq!(
363			assert_3_messages_confirmation_fails(
364				3,
365				&unrewarded_relayers(1..=1)
366					.into_iter()
367					.chain(unrewarded_relayers(2..=30))
368					.chain(unrewarded_relayers(3..=3))
369					.collect(),
370			),
371			Err(ReceptionConfirmationError::FailedToConfirmFutureMessages),
372		);
373	}
374
375	#[test]
376	#[allow(clippy::reversed_empty_ranges)]
377	fn confirm_delivery_fails_if_entry_is_empty() {
378		assert_eq!(
379			assert_3_messages_confirmation_fails(
380				3,
381				&unrewarded_relayers(1..=1)
382					.into_iter()
383					.chain(unrewarded_relayers(2..=1))
384					.chain(unrewarded_relayers(2..=3))
385					.collect(),
386			),
387			Err(ReceptionConfirmationError::EmptyUnrewardedRelayerEntry),
388		);
389	}
390
391	#[test]
392	fn confirm_delivery_fails_if_entries_are_non_consecutive() {
393		assert_eq!(
394			assert_3_messages_confirmation_fails(
395				3,
396				&unrewarded_relayers(1..=1)
397					.into_iter()
398					.chain(unrewarded_relayers(3..=3))
399					.chain(unrewarded_relayers(2..=2))
400					.collect(),
401			),
402			Err(ReceptionConfirmationError::NonConsecutiveUnrewardedRelayerEntries),
403		);
404	}
405
406	#[test]
407	fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() {
408		run_test(|| {
409			let mut lane = active_outbound_lane::<TestRuntime, _>(test_lane_id()).unwrap();
410			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
411			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
412			lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
413			assert_eq!(
414				lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)),
415				Err(ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected),
416			);
417			assert_eq!(
418				lane.confirm_delivery(2, 3, &unrewarded_relayers(1..=3)),
419				Err(ReceptionConfirmationError::TryingToConfirmMoreMessagesThanExpected),
420			);
421			assert_eq!(
422				lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
423				Ok(Some(delivered_messages(1..=3))),
424			);
425		});
426	}
427}