Skip to content

Commit ed2a308

Browse files
svyatonikbkchr
authored andcommitted
Support dedicated lanes for pallets (#962)
* pass call origin to the message verifier * is_outbound_lane_enabled -> is_message_accepted * trait SenderOrigin * only accept messages from token swap pallet to token swap lane * tests for edge cases of pay_delivery_and_dispatch_fee * fixed origin verification * fmt * fix benchmarks compilation * fix TODO with None account and non-zero message fee (already covered by tests) * revert cargo fmt changes temporarily
1 parent 7b7b8ba commit ed2a308

File tree

15 files changed

+361
-129
lines changed

15 files changed

+361
-129
lines changed

bridges/bin/millau/runtime/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,9 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
456456
type MessageDeliveryAndDispatchPayment =
457457
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
458458
Runtime,
459-
(),
459+
WithRialtoMessagesInstance,
460460
pallet_balances::Pallet<Runtime>,
461461
GetDeliveryConfirmationTransactionFee,
462-
RootAccountForPayments,
463462
>;
464463
type OnMessageAccepted = ();
465464
type OnDeliveryConfirmed =
@@ -525,7 +524,7 @@ construct_runtime!(
525524
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
526525
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event<T>},
527526
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
528-
BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event<T>},
527+
BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event<T>, Origin<T>},
529528

530529
// Westend bridge modules.
531530
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage},

bridges/bin/millau/runtime/src/rialto_messages.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use crate::Runtime;
2020

2121
use bp_messages::{
22-
source_chain::TargetHeaderChain,
22+
source_chain::{SenderOrigin, TargetHeaderChain},
2323
target_chain::{ProvedMessages, SourceHeaderChain},
2424
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
2525
};
@@ -116,12 +116,23 @@ impl messages::ChainWithMessages for Millau {
116116
}
117117

118118
impl messages::ThisChainWithMessages for Millau {
119+
type Origin = crate::Origin;
119120
type Call = crate::Call;
120121

121-
fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
122-
*lane == [0, 0, 0, 0] ||
123-
*lane == [0, 0, 0, 1] ||
124-
*lane == crate::TokenSwapMessagesLane::get()
122+
fn is_message_accepted(send_origin: &Self::Origin, lane: &LaneId) -> bool {
123+
// lanes 0x00000000 && 0x00000001 are accepting any paid messages, while
124+
// `TokenSwapMessageLane` only accepts messages from token swap pallet
125+
let token_swap_dedicated_lane = crate::TokenSwapMessagesLane::get();
126+
match *lane {
127+
[0, 0, 0, 0] | [0, 0, 0, 1] => send_origin.linked_account().is_some(),
128+
_ if *lane == token_swap_dedicated_lane => matches!(
129+
send_origin.caller,
130+
crate::OriginCaller::BridgeRialtoTokenSwap(
131+
pallet_bridge_token_swap::RawOrigin::TokenSwap { .. }
132+
)
133+
),
134+
_ => false,
135+
}
125136
}
126137

127138
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
@@ -277,6 +288,25 @@ impl SourceHeaderChain<bp_rialto::Balance> for Rialto {
277288
}
278289
}
279290

291+
impl SenderOrigin<crate::AccountId> for crate::Origin {
292+
fn linked_account(&self) -> Option<crate::AccountId> {
293+
match self.caller {
294+
crate::OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) =>
295+
Some(submitter.clone()),
296+
crate::OriginCaller::system(frame_system::RawOrigin::Root) |
297+
crate::OriginCaller::system(frame_system::RawOrigin::None) =>
298+
crate::RootAccountForPayments::get(),
299+
crate::OriginCaller::BridgeRialtoTokenSwap(
300+
pallet_bridge_token_swap::RawOrigin::TokenSwap {
301+
ref swap_account_at_this_chain,
302+
..
303+
},
304+
) => Some(swap_account_at_this_chain.clone()),
305+
_ => None,
306+
}
307+
}
308+
}
309+
280310
/// Millau -> Rialto message lane pallet parameters.
281311
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)]
282312
pub enum MillauToRialtoMessagesParameter {

bridges/bin/rialto/runtime/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,9 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
457457
type MessageDeliveryAndDispatchPayment =
458458
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
459459
Runtime,
460-
(),
460+
WithMillauMessagesInstance,
461461
pallet_balances::Pallet<Runtime>,
462462
GetDeliveryConfirmationTransactionFee,
463-
RootAccountForPayments,
464463
>;
465464
type OnMessageAccepted = ();
466465
type OnDeliveryConfirmed = ();

bridges/bin/rialto/runtime/src/millau_messages.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use crate::Runtime;
2020

2121
use bp_messages::{
22-
source_chain::TargetHeaderChain,
22+
source_chain::{SenderOrigin, TargetHeaderChain},
2323
target_chain::{ProvedMessages, SourceHeaderChain},
2424
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
2525
};
@@ -116,10 +116,11 @@ impl messages::ChainWithMessages for Rialto {
116116
}
117117

118118
impl messages::ThisChainWithMessages for Rialto {
119+
type Origin = crate::Origin;
119120
type Call = crate::Call;
120121

121-
fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
122-
*lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1]
122+
fn is_message_accepted(send_origin: &Self::Origin, lane: &LaneId) -> bool {
123+
send_origin.linked_account().is_some() && (*lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1])
123124
}
124125

125126
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
@@ -275,6 +276,19 @@ impl SourceHeaderChain<bp_millau::Balance> for Millau {
275276
}
276277
}
277278

279+
impl SenderOrigin<crate::AccountId> for crate::Origin {
280+
fn linked_account(&self) -> Option<crate::AccountId> {
281+
match self.caller {
282+
crate::OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) =>
283+
Some(submitter.clone()),
284+
crate::OriginCaller::system(frame_system::RawOrigin::Root) |
285+
crate::OriginCaller::system(frame_system::RawOrigin::None) =>
286+
crate::RootAccountForPayments::get(),
287+
_ => None,
288+
}
289+
}
290+
}
291+
278292
/// Rialto -> Millau message lane pallet parameters.
279293
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)]
280294
pub enum RialtoToMillauMessagesParameter {

bridges/bin/runtime-common/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pallet-bridge-messages = { path = "../../modules/messages", default-features = f
2626
# Substrate dependencies
2727

2828
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
29-
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
29+
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3030
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
3131
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3232
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -45,6 +45,7 @@ std = [
4545
"bp-runtime/std",
4646
"codec/std",
4747
"frame-support/std",
48+
"frame-system/std",
4849
"hash-db/std",
4950
"pallet-bridge-dispatch/std",
5051
"pallet-bridge-grandpa/std",
@@ -60,14 +61,12 @@ std = [
6061
]
6162
runtime-benchmarks = [
6263
"ed25519-dalek/u64_backend",
63-
"frame-system",
6464
"pallet-balances",
6565
"pallet-bridge-grandpa/runtime-benchmarks",
6666
"pallet-bridge-messages/runtime-benchmarks",
6767
"sp-state-machine",
6868
"sp-version",
6969
]
7070
integrity-test = [
71-
"frame-system",
7271
"static_assertions",
7372
]

bridges/bin/runtime-common/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ corresponding chain. There is single exception, though (it may be changed in the
6262

6363
This trait represents this chain from bridge point of view. Let's review every method of this trait:
6464

65-
- `ThisChainWithMessages::is_outbound_lane_enabled`: is used to check whether given lane accepts
66-
outbound messages.
65+
- `ThisChainWithMessages::is_message_accepted`: is used to check whether given lane accepts
66+
messages. The send-message origin is passed to the function, so you may e.g. verify that only
67+
given pallet is able to send messages over selected lane. **IMPORTANT**: if you assume that the
68+
message must be paid by the sender, you must ensure that the sender origin has linked the account
69+
for paying message delivery and dispatch fee.
6770

6871
- `ThisChainWithMessages::maximal_pending_messages_at_outbound_lane`: you should return maximal
6972
number of pending (undelivered) messages from this function. Returning small values would require

0 commit comments

Comments
 (0)