1use 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
31pub trait OutboundLaneStorage {
33 type StoredMessagePayload;
35 type LaneId: Encode;
37
38 fn id(&self) -> Self::LaneId;
40 fn data(&self) -> OutboundLaneData;
42 fn set_data(&mut self, data: OutboundLaneData);
44 #[cfg(test)]
46 fn message(&self, nonce: &MessageNonce) -> Option<Self::StoredMessagePayload>;
47 fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload);
49 fn remove_message(&mut self, nonce: &MessageNonce);
51 fn purge(self);
53}
54
55pub 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
64pub type StoredMessagePayload<T, I> = BoundedVec<u8, StoredMessagePayloadLimit<T, I>>;
66
67#[derive(Encode, Decode, DecodeWithMemTracking, Debug, PartialEq, Eq, PalletError, TypeInfo)]
69pub enum ReceptionConfirmationError {
70 FailedToConfirmFutureMessages,
73 EmptyUnrewardedRelayerEntry,
76 NonConsecutiveUnrewardedRelayerEntries,
79 TryingToConfirmMoreMessagesThanExpected,
81}
82
83#[derive(Debug, PartialEq, Eq)]
85pub struct OutboundLane<S> {
86 storage: S,
87}
88
89impl<S: OutboundLaneStorage> OutboundLane<S> {
90 pub fn new(storage: S) -> Self {
92 OutboundLane { storage }
93 }
94
95 pub fn data(&self) -> OutboundLaneData {
97 self.storage.data()
98 }
99
100 pub fn state(&self) -> LaneState {
102 self.storage.data().state
103 }
104
105 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 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 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 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 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 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 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 pub fn purge(self) {
189 self.storage.purge()
190 }
191}
192
193fn 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 if entry.messages.end < entry.messages.begin {
206 return Err(ReceptionConfirmationError::EmptyUnrewardedRelayerEntry)
207 }
208 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 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}