Skip to content

Commit 183778f

Browse files
authored
Propagate message receival confirmation errors (paritytech#2116)
* Propagate message receival confirmation errors * spellcheck
1 parent 57c5f95 commit 183778f

File tree

2 files changed

+71
-102
lines changed

2 files changed

+71
-102
lines changed

bridges/modules/messages/src/lib.rs

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub use weights_ext::{
4848

4949
use crate::{
5050
inbound_lane::{InboundLane, InboundLaneStorage},
51-
outbound_lane::{OutboundLane, OutboundLaneStorage, ReceivalConfirmationResult},
51+
outbound_lane::{OutboundLane, OutboundLaneStorage, ReceivalConfirmationError},
5252
};
5353

5454
use bp_messages::{
@@ -458,36 +458,13 @@ pub mod pallet {
458458
// mark messages as delivered
459459
let mut lane = outbound_lane::<T, I>(lane_id);
460460
let last_delivered_nonce = lane_data.last_delivered_nonce();
461-
let confirmed_messages = match lane.confirm_delivery(
462-
relayers_state.total_messages,
463-
last_delivered_nonce,
464-
&lane_data.relayers,
465-
) {
466-
ReceivalConfirmationResult::ConfirmedMessages(confirmed_messages) =>
467-
Some(confirmed_messages),
468-
ReceivalConfirmationResult::NoNewConfirmations => None,
469-
ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(
470-
to_confirm_messages_count,
471-
) => {
472-
log::trace!(
473-
target: LOG_TARGET,
474-
"Messages delivery proof contains too many messages to confirm: {} vs declared {}",
475-
to_confirm_messages_count,
476-
relayers_state.total_messages,
477-
);
478-
479-
fail!(Error::<T, I>::TryingToConfirmMoreMessagesThanExpected);
480-
},
481-
error => {
482-
log::trace!(
483-
target: LOG_TARGET,
484-
"Messages delivery proof contains invalid unrewarded relayers vec: {:?}",
485-
error,
486-
);
487-
488-
fail!(Error::<T, I>::InvalidUnrewardedRelayers);
489-
},
490-
};
461+
let confirmed_messages = lane
462+
.confirm_delivery(
463+
relayers_state.total_messages,
464+
last_delivered_nonce,
465+
&lane_data.relayers,
466+
)
467+
.map_err(Error::<T, I>::ReceivalConfirmation)?;
491468

492469
if let Some(confirmed_messages) = confirmed_messages {
493470
// emit 'delivered' event
@@ -568,8 +545,6 @@ pub mod pallet {
568545
InvalidMessagesProof,
569546
/// Invalid messages delivery proof has been submitted.
570547
InvalidMessagesDeliveryProof,
571-
/// The bridged chain has invalid `UnrewardedRelayers` in its storage (fatal for the lane).
572-
InvalidUnrewardedRelayers,
573548
/// The relayer has declared invalid unrewarded relayers state in the
574549
/// `receive_messages_delivery_proof` call.
575550
InvalidUnrewardedRelayersState,
@@ -578,9 +553,8 @@ pub mod pallet {
578553
InsufficientDispatchWeight,
579554
/// The message someone is trying to work with (i.e. increase fee) is not yet sent.
580555
MessageIsNotYetSent,
581-
/// The number of actually confirmed messages is going to be larger than the number of
582-
/// messages in the proof. This may mean that this or bridged chain storage is corrupted.
583-
TryingToConfirmMoreMessagesThanExpected,
556+
/// Error confirming messages receival.
557+
ReceivalConfirmation(ReceivalConfirmationError),
584558
/// Error generated by the `OwnedBridgeModule` trait.
585559
BridgeModule(bp_runtime::OwnedBridgeModuleError),
586560
}
@@ -941,13 +915,16 @@ fn verify_and_decode_messages_proof<Chain: SourceHeaderChain, DispatchPayload: D
941915
#[cfg(test)]
942916
mod tests {
943917
use super::*;
944-
use crate::mock::{
945-
inbound_unrewarded_relayers_state, message, message_payload, run_test, unrewarded_relayer,
946-
AccountId, DbWeight, RuntimeEvent as TestEvent, RuntimeOrigin,
947-
TestDeliveryConfirmationPayments, TestDeliveryPayments, TestMessagesDeliveryProof,
948-
TestMessagesProof, TestRelayer, TestRuntime, TestWeightInfo, MAX_OUTBOUND_PAYLOAD_SIZE,
949-
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2,
950-
TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B,
918+
use crate::{
919+
mock::{
920+
inbound_unrewarded_relayers_state, message, message_payload, run_test,
921+
unrewarded_relayer, AccountId, DbWeight, RuntimeEvent as TestEvent, RuntimeOrigin,
922+
TestDeliveryConfirmationPayments, TestDeliveryPayments, TestMessagesDeliveryProof,
923+
TestMessagesProof, TestRelayer, TestRuntime, TestWeightInfo, MAX_OUTBOUND_PAYLOAD_SIZE,
924+
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2,
925+
TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B,
926+
},
927+
outbound_lane::ReceivalConfirmationError,
951928
};
952929
use bp_messages::{BridgeMessagesCall, UnrewardedRelayer, UnrewardedRelayersState};
953930
use bp_test_utils::generate_owned_bridge_module_tests;
@@ -1818,7 +1795,9 @@ mod tests {
18181795
))),
18191796
UnrewardedRelayersState { last_delivered_nonce: 1, ..Default::default() },
18201797
),
1821-
Error::<TestRuntime, ()>::TryingToConfirmMoreMessagesThanExpected,
1798+
Error::<TestRuntime, ()>::ReceivalConfirmation(
1799+
ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected
1800+
),
18221801
);
18231802
});
18241803
}

bridges/modules/messages/src/outbound_lane.rs

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@
1616

1717
//! Everything about outgoing messages sending.
1818
19-
use crate::Config;
19+
use crate::{Config, LOG_TARGET};
2020

2121
use bp_messages::{
2222
DeliveredMessages, LaneId, MessageNonce, MessagePayload, OutboundLaneData, UnrewardedRelayer,
2323
};
24+
use codec::{Decode, Encode};
2425
use frame_support::{
2526
weights::{RuntimeDbWeight, Weight},
26-
BoundedVec, RuntimeDebug,
27+
BoundedVec, PalletError, RuntimeDebug,
2728
};
2829
use num_traits::Zero;
30+
use scale_info::TypeInfo;
2931
use sp_std::collections::vec_deque::VecDeque;
3032

3133
/// Outbound lane storage.
@@ -49,13 +51,8 @@ pub trait OutboundLaneStorage {
4951
pub type StoredMessagePayload<T, I> = BoundedVec<u8, <T as Config<I>>::MaximalOutboundPayloadSize>;
5052

5153
/// Result of messages receival confirmation.
52-
#[derive(RuntimeDebug, PartialEq, Eq)]
53-
pub enum ReceivalConfirmationResult {
54-
/// New messages have been confirmed by the confirmation transaction.
55-
ConfirmedMessages(DeliveredMessages),
56-
/// Confirmation transaction brings no new confirmation. This may be a result of relayer
57-
/// error or several relayers running.
58-
NoNewConfirmations,
54+
#[derive(Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)]
55+
pub enum ReceivalConfirmationError {
5956
/// Bridged chain is trying to confirm more messages than we have generated. May be a result
6057
/// of invalid bridged chain storage.
6158
FailedToConfirmFutureMessages,
@@ -66,7 +63,7 @@ pub enum ReceivalConfirmationResult {
6663
/// bridged chain storage.
6764
NonConsecutiveUnrewardedRelayerEntries,
6865
/// The chain has more messages that need to be confirmed than there is in the proof.
69-
TryingToConfirmMoreMessagesThanExpected(MessageNonce),
66+
TryingToConfirmMoreMessagesThanExpected,
7067
}
7168

7269
/// Outbound messages lane.
@@ -105,37 +102,39 @@ impl<S: OutboundLaneStorage> OutboundLane<S> {
105102
max_allowed_messages: MessageNonce,
106103
latest_delivered_nonce: MessageNonce,
107104
relayers: &VecDeque<UnrewardedRelayer<RelayerId>>,
108-
) -> ReceivalConfirmationResult {
105+
) -> Result<Option<DeliveredMessages>, ReceivalConfirmationError> {
109106
let mut data = self.storage.data();
110-
if latest_delivered_nonce <= data.latest_received_nonce {
111-
return ReceivalConfirmationResult::NoNewConfirmations
107+
let confirmed_messages = DeliveredMessages {
108+
begin: data.latest_received_nonce.saturating_add(1),
109+
end: latest_delivered_nonce,
110+
};
111+
if confirmed_messages.total_messages() == 0 {
112+
return Ok(None)
112113
}
113-
if latest_delivered_nonce > data.latest_generated_nonce {
114-
return ReceivalConfirmationResult::FailedToConfirmFutureMessages
114+
if confirmed_messages.end > data.latest_generated_nonce {
115+
return Err(ReceivalConfirmationError::FailedToConfirmFutureMessages)
115116
}
116-
if latest_delivered_nonce - data.latest_received_nonce > max_allowed_messages {
117+
if confirmed_messages.total_messages() > max_allowed_messages {
117118
// that the relayer has declared correct number of messages that the proof contains (it
118119
// is checked outside of the function). But it may happen (but only if this/bridged
119120
// chain storage is corrupted, though) that the actual number of confirmed messages if
120121
// larger than declared. This would mean that 'reward loop' will take more time than the
121122
// weight formula accounts, so we can't allow that.
122-
return ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(
123-
latest_delivered_nonce - data.latest_received_nonce,
124-
)
123+
log::trace!(
124+
target: LOG_TARGET,
125+
"Messages delivery proof contains too many messages to confirm: {} vs declared {}",
126+
confirmed_messages.total_messages(),
127+
max_allowed_messages,
128+
);
129+
return Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected)
125130
}
126131

127-
if let Err(e) = ensure_unrewarded_relayers_are_correct(latest_delivered_nonce, relayers) {
128-
return e
129-
}
132+
ensure_unrewarded_relayers_are_correct(confirmed_messages.end, relayers)?;
130133

131-
let prev_latest_received_nonce = data.latest_received_nonce;
132-
data.latest_received_nonce = latest_delivered_nonce;
134+
data.latest_received_nonce = confirmed_messages.end;
133135
self.storage.set_data(data);
134136

135-
ReceivalConfirmationResult::ConfirmedMessages(DeliveredMessages {
136-
begin: prev_latest_received_nonce + 1,
137-
end: latest_delivered_nonce,
138-
})
137+
Ok(Some(confirmed_messages))
139138
}
140139

141140
/// Prune at most `max_messages_to_prune` already received messages.
@@ -176,27 +175,24 @@ impl<S: OutboundLaneStorage> OutboundLane<S> {
176175
fn ensure_unrewarded_relayers_are_correct<RelayerId>(
177176
latest_received_nonce: MessageNonce,
178177
relayers: &VecDeque<UnrewardedRelayer<RelayerId>>,
179-
) -> Result<(), ReceivalConfirmationResult> {
180-
let mut last_entry_end: Option<MessageNonce> = None;
178+
) -> Result<(), ReceivalConfirmationError> {
179+
let mut expected_entry_begin = relayers.front().map(|entry| entry.messages.begin);
181180
for entry in relayers {
182181
// unrewarded relayer entry must have at least 1 unconfirmed message
183182
// (guaranteed by the `InboundLane::receive_message()`)
184183
if entry.messages.end < entry.messages.begin {
185-
return Err(ReceivalConfirmationResult::EmptyUnrewardedRelayerEntry)
184+
return Err(ReceivalConfirmationError::EmptyUnrewardedRelayerEntry)
186185
}
187186
// every entry must confirm range of messages that follows previous entry range
188187
// (guaranteed by the `InboundLane::receive_message()`)
189-
if let Some(last_entry_end) = last_entry_end {
190-
let expected_entry_begin = last_entry_end.checked_add(1);
191-
if expected_entry_begin != Some(entry.messages.begin) {
192-
return Err(ReceivalConfirmationResult::NonConsecutiveUnrewardedRelayerEntries)
193-
}
188+
if expected_entry_begin != Some(entry.messages.begin) {
189+
return Err(ReceivalConfirmationError::NonConsecutiveUnrewardedRelayerEntries)
194190
}
195-
last_entry_end = Some(entry.messages.end);
191+
expected_entry_begin = entry.messages.end.checked_add(1);
196192
// entry can't confirm messages larger than `inbound_lane_data.latest_received_nonce()`
197193
// (guaranteed by the `InboundLane::receive_message()`)
198194
if entry.messages.end > latest_received_nonce {
199-
return Err(ReceivalConfirmationResult::FailedToConfirmFutureMessages)
195+
return Err(ReceivalConfirmationError::FailedToConfirmFutureMessages)
200196
}
201197
}
202198

@@ -231,7 +227,7 @@ mod tests {
231227
fn assert_3_messages_confirmation_fails(
232228
latest_received_nonce: MessageNonce,
233229
relayers: &VecDeque<UnrewardedRelayer<TestRelayer>>,
234-
) -> ReceivalConfirmationResult {
230+
) -> Result<Option<DeliveredMessages>, ReceivalConfirmationError> {
235231
run_test(|| {
236232
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
237233
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
@@ -268,7 +264,7 @@ mod tests {
268264
assert_eq!(lane.storage.data().latest_received_nonce, 0);
269265
assert_eq!(
270266
lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
271-
ReceivalConfirmationResult::ConfirmedMessages(delivered_messages(1..=3)),
267+
Ok(Some(delivered_messages(1..=3))),
272268
);
273269
assert_eq!(lane.storage.data().latest_generated_nonce, 3);
274270
assert_eq!(lane.storage.data().latest_received_nonce, 3);
@@ -286,19 +282,13 @@ mod tests {
286282
assert_eq!(lane.storage.data().latest_received_nonce, 0);
287283
assert_eq!(
288284
lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
289-
ReceivalConfirmationResult::ConfirmedMessages(delivered_messages(1..=3)),
290-
);
291-
assert_eq!(
292-
lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
293-
ReceivalConfirmationResult::NoNewConfirmations,
285+
Ok(Some(delivered_messages(1..=3))),
294286
);
287+
assert_eq!(lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)), Ok(None),);
295288
assert_eq!(lane.storage.data().latest_generated_nonce, 3);
296289
assert_eq!(lane.storage.data().latest_received_nonce, 3);
297290

298-
assert_eq!(
299-
lane.confirm_delivery(1, 2, &unrewarded_relayers(1..=1)),
300-
ReceivalConfirmationResult::NoNewConfirmations,
301-
);
291+
assert_eq!(lane.confirm_delivery(1, 2, &unrewarded_relayers(1..=1)), Ok(None),);
302292
assert_eq!(lane.storage.data().latest_generated_nonce, 3);
303293
assert_eq!(lane.storage.data().latest_received_nonce, 3);
304294
});
@@ -308,7 +298,7 @@ mod tests {
308298
fn confirm_delivery_rejects_nonce_larger_than_last_generated() {
309299
assert_eq!(
310300
assert_3_messages_confirmation_fails(10, &unrewarded_relayers(1..=10),),
311-
ReceivalConfirmationResult::FailedToConfirmFutureMessages,
301+
Err(ReceivalConfirmationError::FailedToConfirmFutureMessages),
312302
);
313303
}
314304

@@ -323,7 +313,7 @@ mod tests {
323313
.chain(unrewarded_relayers(3..=3).into_iter())
324314
.collect(),
325315
),
326-
ReceivalConfirmationResult::FailedToConfirmFutureMessages,
316+
Err(ReceivalConfirmationError::FailedToConfirmFutureMessages),
327317
);
328318
}
329319

@@ -339,7 +329,7 @@ mod tests {
339329
.chain(unrewarded_relayers(2..=3).into_iter())
340330
.collect(),
341331
),
342-
ReceivalConfirmationResult::EmptyUnrewardedRelayerEntry,
332+
Err(ReceivalConfirmationError::EmptyUnrewardedRelayerEntry),
343333
);
344334
}
345335

@@ -354,7 +344,7 @@ mod tests {
354344
.chain(unrewarded_relayers(2..=2).into_iter())
355345
.collect(),
356346
),
357-
ReceivalConfirmationResult::NonConsecutiveUnrewardedRelayerEntries,
347+
Err(ReceivalConfirmationError::NonConsecutiveUnrewardedRelayerEntries),
358348
);
359349
}
360350

@@ -383,7 +373,7 @@ mod tests {
383373
// after confirmation, some messages are received
384374
assert_eq!(
385375
lane.confirm_delivery(2, 2, &unrewarded_relayers(1..=2)),
386-
ReceivalConfirmationResult::ConfirmedMessages(delivered_messages(1..=2)),
376+
Ok(Some(delivered_messages(1..=2))),
387377
);
388378
assert_eq!(
389379
lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)),
@@ -396,7 +386,7 @@ mod tests {
396386
// after last message is confirmed, everything is pruned
397387
assert_eq!(
398388
lane.confirm_delivery(1, 3, &unrewarded_relayers(3..=3)),
399-
ReceivalConfirmationResult::ConfirmedMessages(delivered_messages(3..=3)),
389+
Ok(Some(delivered_messages(3..=3))),
400390
);
401391
assert_eq!(
402392
lane.prune_messages(RocksDbWeight::get(), RocksDbWeight::get().writes(101)),
@@ -418,15 +408,15 @@ mod tests {
418408
lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
419409
assert_eq!(
420410
lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)),
421-
ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(3),
411+
Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected),
422412
);
423413
assert_eq!(
424414
lane.confirm_delivery(2, 3, &unrewarded_relayers(1..=3)),
425-
ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(3),
415+
Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected),
426416
);
427417
assert_eq!(
428418
lane.confirm_delivery(3, 3, &unrewarded_relayers(1..=3)),
429-
ReceivalConfirmationResult::ConfirmedMessages(delivered_messages(1..=3)),
419+
Ok(Some(delivered_messages(1..=3))),
430420
);
431421
});
432422
}

0 commit comments

Comments
 (0)