Skip to content

Commit 604eb1c

Browse files
svyatoniktomusdrw
andauthored
Relay basic single-bit message dispatch results back to the source chain (#935)
* relay dispatch result flags back to the source chain * OnMessagesDelivered callback * add lane id to OnDeliveredMessages callback * fix benchmarks && upate weights * clippy * clippy * clipy another try * OnMessagesDelivered -> OnDeliveryConfirmed * Update primitives/messages/src/source_chain.rs Co-authored-by: Tomasz Drwięga <[email protected]> Co-authored-by: Tomasz Drwięga <[email protected]>
1 parent bf52fff commit 604eb1c

20 files changed

Lines changed: 866 additions & 197 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/millau/runtime/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
384384
GetDeliveryConfirmationTransactionFee,
385385
RootAccountForPayments,
386386
>;
387+
type OnDeliveryConfirmed = ();
387388

388389
type SourceHeaderChain = crate::rialto_messages::Rialto;
389390
type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch;
@@ -702,6 +703,7 @@ mod tests {
702703
let max_incoming_inbound_lane_data_proof_size = bp_messages::InboundLaneData::<()>::encoded_size_hint(
703704
bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
704705
bp_rialto::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _,
706+
bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _,
705707
)
706708
.unwrap_or(u32::MAX);
707709
pallet_bridge_messages::ensure_able_to_receive_confirmation::<Weights>(

bin/millau/runtime/src/rialto_messages.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,12 @@ impl messages::ThisChainWithMessages for Millau {
113113
}
114114

115115
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight> {
116-
let inbound_data_size =
117-
InboundLaneData::<bp_millau::AccountId>::encoded_size_hint(bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, 1)
118-
.unwrap_or(u32::MAX);
116+
let inbound_data_size = InboundLaneData::<bp_millau::AccountId>::encoded_size_hint(
117+
bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
118+
1,
119+
1,
120+
)
121+
.unwrap_or(u32::MAX);
119122

120123
MessageTransaction {
121124
dispatch_weight: bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,

bin/rialto/runtime/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
491491
GetDeliveryConfirmationTransactionFee,
492492
RootAccountForPayments,
493493
>;
494+
type OnDeliveryConfirmed = ();
494495

495496
type SourceHeaderChain = crate::millau_messages::Millau;
496497
type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch;
@@ -1028,7 +1029,7 @@ impl_runtime_apis! {
10281029
.map(|event_record| event_record.event)
10291030
.any(|event| matches!(
10301031
event,
1031-
Event::pallet_bridge_dispatch(pallet_bridge_dispatch::Event::<Runtime, _>::MessageDispatched(
1032+
Event::BridgeDispatch(pallet_bridge_dispatch::Event::<Runtime, _>::MessageDispatched(
10321033
_, ([0, 0, 0, 0], nonce_from_event), _,
10331034
)) if nonce_from_event == nonce
10341035
))
@@ -1144,6 +1145,7 @@ mod tests {
11441145
let max_incoming_inbound_lane_data_proof_size = bp_messages::InboundLaneData::<()>::encoded_size_hint(
11451146
bp_rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
11461147
bp_millau::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _,
1148+
bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _,
11471149
)
11481150
.unwrap_or(u32::MAX);
11491151
pallet_bridge_messages::ensure_able_to_receive_confirmation::<Weights>(

bin/rialto/runtime/src/millau_messages.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,12 @@ impl messages::ThisChainWithMessages for Rialto {
113113
}
114114

115115
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight> {
116-
let inbound_data_size =
117-
InboundLaneData::<bp_rialto::AccountId>::encoded_size_hint(bp_rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, 1)
118-
.unwrap_or(u32::MAX);
116+
let inbound_data_size = InboundLaneData::<bp_rialto::AccountId>::encoded_size_hint(
117+
bp_rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
118+
1,
119+
1,
120+
)
121+
.unwrap_or(u32::MAX);
119122

120123
MessageTransaction {
121124
dispatch_weight: bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,

modules/dispatch/src/lib.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
154154
);
155155
Self::deposit_event(RawEvent::MessageRejected(source_chain, id));
156156
return MessageDispatchResult {
157+
dispatch_result: false,
157158
unspent_weight: 0,
158159
dispatch_fee_paid_during_dispatch: false,
159160
};
@@ -163,6 +164,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
163164
// verify spec version
164165
// (we want it to be the same, because otherwise we may decode Call improperly)
165166
let mut dispatch_result = MessageDispatchResult {
167+
dispatch_result: false,
166168
unspent_weight: message.weight,
167169
dispatch_fee_paid_during_dispatch: false,
168170
};
@@ -303,6 +305,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
303305
log::trace!(target: "runtime::bridge-dispatch", "Message being dispatched is: {:.4096?}", &call);
304306
let result = call.dispatch(origin);
305307
let actual_call_weight = extract_actual_weight(&result, &dispatch_info);
308+
dispatch_result.dispatch_result = result.is_ok();
306309
dispatch_result.unspent_weight = message.weight.saturating_sub(actual_call_weight);
307310

308311
log::trace!(
@@ -573,6 +576,7 @@ mod tests {
573576
System::set_block_number(1);
574577
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
575578
assert_eq!(result.unspent_weight, weight);
579+
assert!(!result.dispatch_result);
576580

577581
assert_eq!(
578582
System::events(),
@@ -601,6 +605,7 @@ mod tests {
601605
System::set_block_number(1);
602606
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
603607
assert_eq!(result.unspent_weight, 7);
608+
assert!(!result.dispatch_result);
604609

605610
assert_eq!(
606611
System::events(),
@@ -633,6 +638,7 @@ mod tests {
633638
System::set_block_number(1);
634639
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
635640
assert_eq!(result.unspent_weight, weight);
641+
assert!(!result.dispatch_result);
636642

637643
assert_eq!(
638644
System::events(),
@@ -683,6 +689,7 @@ mod tests {
683689
System::set_block_number(1);
684690
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
685691
assert_eq!(result.unspent_weight, weight);
692+
assert!(!result.dispatch_result);
686693

687694
assert_eq!(
688695
System::events(),
@@ -711,6 +718,7 @@ mod tests {
711718
System::set_block_number(1);
712719
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
713720
assert_eq!(result.unspent_weight, weight);
721+
assert!(!result.dispatch_result);
714722

715723
assert_eq!(
716724
System::events(),
@@ -739,12 +747,13 @@ mod tests {
739747
System::set_block_number(1);
740748
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| Err(()));
741749
assert_eq!(result.unspent_weight, weight);
750+
assert!(!result.dispatch_result);
742751

743752
assert_eq!(
744753
System::events(),
745754
vec![EventRecord {
746755
phase: Phase::Initialization,
747-
event: Event::call_dispatch(call_dispatch::Event::<TestRuntime>::MessageDispatchPaymentFailed(
756+
event: Event::Dispatch(call_dispatch::Event::<TestRuntime>::MessageDispatchPaymentFailed(
748757
SOURCE_CHAIN_ID,
749758
id,
750759
AccountIdConverter::convert(derive_account_id::<AccountId>(
@@ -771,12 +780,13 @@ mod tests {
771780
System::set_block_number(1);
772781
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| Ok(()));
773782
assert!(result.dispatch_fee_paid_during_dispatch);
783+
assert!(result.dispatch_result);
774784

775785
assert_eq!(
776786
System::events(),
777787
vec![EventRecord {
778788
phase: Phase::Initialization,
779-
event: Event::call_dispatch(call_dispatch::Event::<TestRuntime>::MessageDispatched(
789+
event: Event::Dispatch(call_dispatch::Event::<TestRuntime>::MessageDispatched(
780790
SOURCE_CHAIN_ID,
781791
id,
782792
Ok(())
@@ -787,6 +797,34 @@ mod tests {
787797
});
788798
}
789799

800+
#[test]
801+
fn should_return_dispatch_failed_flag_if_dispatch_happened_but_failed() {
802+
new_test_ext().execute_with(|| {
803+
let id = [0; 4];
804+
805+
let call = Call::System(<frame_system::Call<TestRuntime>>::set_heap_pages(1));
806+
let message = prepare_target_message(call);
807+
808+
System::set_block_number(1);
809+
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
810+
assert!(!result.dispatch_fee_paid_during_dispatch);
811+
assert!(!result.dispatch_result);
812+
813+
assert_eq!(
814+
System::events(),
815+
vec![EventRecord {
816+
phase: Phase::Initialization,
817+
event: Event::Dispatch(call_dispatch::Event::<TestRuntime>::MessageDispatched(
818+
SOURCE_CHAIN_ID,
819+
id,
820+
Err(sp_runtime::DispatchError::BadOrigin)
821+
)),
822+
topics: vec![],
823+
}],
824+
);
825+
})
826+
}
827+
790828
#[test]
791829
fn should_dispatch_bridge_message_from_root_origin() {
792830
new_test_ext().execute_with(|| {
@@ -796,6 +834,7 @@ mod tests {
796834
System::set_block_number(1);
797835
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
798836
assert!(!result.dispatch_fee_paid_during_dispatch);
837+
assert!(result.dispatch_result);
799838

800839
assert_eq!(
801840
System::events(),
@@ -823,6 +862,7 @@ mod tests {
823862
System::set_block_number(1);
824863
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
825864
assert!(!result.dispatch_fee_paid_during_dispatch);
865+
assert!(result.dispatch_result);
826866

827867
assert_eq!(
828868
System::events(),
@@ -850,6 +890,7 @@ mod tests {
850890
System::set_block_number(1);
851891
let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!());
852892
assert!(!result.dispatch_fee_paid_during_dispatch);
893+
assert!(result.dispatch_result);
853894

854895
assert_eq!(
855896
System::events(),

modules/messages/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2018"
77
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
88

99
[dependencies]
10+
bitvec = { version = "0.20", default-features = false, features = ["alloc"] }
1011
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }
1112
log = { version = "0.4.14", default-features = false }
1213
num-traits = { version = "0.2", default-features = false }

modules/messages/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,14 @@ the `MessageAccepted` event is emitted in the `send_message()` transaction. The
101101
message lane identifier and nonce that has been assigned to the message. When a message is delivered
102102
to the target chain, the `MessagesDelivered` event is emitted from the
103103
`receive_messages_delivery_proof()` transaction. The `MessagesDelivered` contains the message lane
104-
identifier and inclusive range of delivered message nonces.
104+
identifier, inclusive range of delivered message nonces and their single-bit dispatch results.
105+
106+
Please note that the meaning of the 'dispatch result' is determined by the message dispatcher at
107+
the target chain. For example, in case of immediate call dispatcher it will be the `true` if call
108+
has been successfully dispatched and `false` if it has only been delivered. This simple mechanism
109+
built into the messages module allows building basic bridge applications, which only care whether
110+
their messages have been successfully dispatched or not. More sophisticated applications may use
111+
their own dispatch result delivery mechanism to deliver something larger than single bit.
105112

106113
### How to plug-in Messages Module to Send Messages to the Bridged Chain?
107114

0 commit comments

Comments
 (0)