Skip to content

Commit 4bb1a64

Browse files
authored
only refund if all bundled messages have been delivered (#2019)
1 parent b9acf52 commit 4bb1a64

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

bin/runtime-common/src/messages_call_ext.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ use sp_runtime::transaction_validity::TransactionValidity;
2525
/// Generic info about a messages delivery/confirmation proof.
2626
#[derive(PartialEq, RuntimeDebug)]
2727
pub struct BaseMessagesProofInfo {
28+
/// Message lane, used by the call.
2829
pub lane_id: LaneId,
30+
/// Nonce of the best message, included in the call.
2931
pub best_bundled_nonce: MessageNonce,
32+
/// Nonce of the best message, stored by this chain before the call is dispatched.
3033
pub best_stored_nonce: MessageNonce,
3134
}
3235

@@ -58,19 +61,23 @@ pub struct CallHelper<T: Config<I>, I: 'static> {
5861
}
5962

6063
impl<T: Config<I>, I: 'static> CallHelper<T, I> {
61-
/// Check if a call delivered proof/confirmation for at least some of the messages that it
62-
/// contained.
63-
pub fn was_partially_successful(info: &CallInfo) -> bool {
64+
/// Returns true if:
65+
///
66+
/// - call is `receive_messages_proof` and all messages have been delivered;
67+
///
68+
/// - call is `receive_messages_delivery_proof` and all messages confirmations have been
69+
/// received.
70+
pub fn was_successful(info: &CallInfo) -> bool {
6471
match info {
6572
CallInfo::ReceiveMessagesProof(info) => {
6673
let inbound_lane_data =
6774
pallet_bridge_messages::InboundLanes::<T, I>::get(info.0.lane_id);
68-
inbound_lane_data.last_delivered_nonce() > info.0.best_stored_nonce
75+
inbound_lane_data.last_delivered_nonce() == info.0.best_bundled_nonce
6976
},
7077
CallInfo::ReceiveMessagesDeliveryProof(info) => {
7178
let outbound_lane_data =
7279
pallet_bridge_messages::OutboundLanes::<T, I>::get(info.0.lane_id);
73-
outbound_lane_data.latest_received_nonce > info.0.best_stored_nonce
80+
outbound_lane_data.latest_received_nonce == info.0.best_bundled_nonce
7481
},
7582
}
7683
}

bin/runtime-common/src/refund_relayer_extension.rs

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,16 @@ where
344344
finality_proof_info.block_number,
345345
) {
346346
// we only refund relayer if all calls have updated chain state
347+
log::trace!(
348+
target: "runtime::bridge",
349+
"{} from parachain {} via {:?}: failed to refund relayer {:?}, because \
350+
relay chain finality proof has not been accepted",
351+
Self::IDENTIFIER,
352+
Para::Id::get(),
353+
Msgs::Id::get(),
354+
relayer,
355+
);
356+
347357
return Ok(())
348358
}
349359

@@ -366,15 +376,34 @@ where
366376
para_proof_info,
367377
) {
368378
// we only refund relayer if all calls have updated chain state
379+
log::trace!(
380+
target: "runtime::bridge",
381+
"{} from parachain {} via {:?}: failed to refund relayer {:?}, because \
382+
parachain finality proof has not been accepted",
383+
Self::IDENTIFIER,
384+
Para::Id::get(),
385+
Msgs::Id::get(),
386+
relayer,
387+
);
388+
369389
return Ok(())
370390
}
371391
}
372392

373-
// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
393+
// Check if the `ReceiveMessagesProof` call delivered all the messages that
374394
// it contained. If this happens, we consider the transaction "helpful" and refund it.
375395
let msgs_call_info = call_info.messages_call_info();
376-
if !MessagesCallHelper::<Runtime, Msgs::Instance>::was_partially_successful(msgs_call_info)
377-
{
396+
if !MessagesCallHelper::<Runtime, Msgs::Instance>::was_successful(msgs_call_info) {
397+
log::trace!(
398+
target: "runtime::bridge",
399+
"{} from parachain {} via {:?}: failed to refund relayer {:?}, because \
400+
some of messages have not been accepted",
401+
Self::IDENTIFIER,
402+
Para::Id::get(),
403+
Msgs::Id::get(),
404+
relayer,
405+
);
406+
378407
return Ok(())
379408
}
380409

@@ -1032,6 +1061,30 @@ mod tests {
10321061
});
10331062
}
10341063

1064+
#[test]
1065+
fn post_dispatch_ignores_transaction_that_has_not_delivered_all_messages() {
1066+
run_test(|| {
1067+
initialize_environment(200, 200, Default::default(), 150);
1068+
1069+
assert_storage_noop!(run_post_dispatch(Some(all_finality_pre_dispatch_data()), Ok(())));
1070+
assert_storage_noop!(run_post_dispatch(
1071+
Some(parachain_finality_pre_dispatch_data()),
1072+
Ok(())
1073+
));
1074+
assert_storage_noop!(run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(())));
1075+
1076+
assert_storage_noop!(run_post_dispatch(
1077+
Some(all_finality_confirmation_pre_dispatch_data()),
1078+
Ok(())
1079+
));
1080+
assert_storage_noop!(run_post_dispatch(
1081+
Some(parachain_finality_confirmation_pre_dispatch_data()),
1082+
Ok(())
1083+
));
1084+
assert_storage_noop!(run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(())));
1085+
});
1086+
}
1087+
10351088
#[test]
10361089
fn post_dispatch_refunds_relayer_in_all_finality_batch_with_extra_weight() {
10371090
run_test(|| {

0 commit comments

Comments
 (0)