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