Skip to content

Commit

Permalink
Support dedicated lanes for pallets (#962)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
svyatonik authored and bkchr committed Apr 10, 2024
1 parent 7b7b8ba commit ed2a308
Show file tree
Hide file tree
Showing 15 changed files with 361 additions and 129 deletions.
5 changes: 2 additions & 3 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,9 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
type MessageDeliveryAndDispatchPayment =
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
Runtime,
(),
WithRialtoMessagesInstance,
pallet_balances::Pallet<Runtime>,
GetDeliveryConfirmationTransactionFee,
RootAccountForPayments,
>;
type OnMessageAccepted = ();
type OnDeliveryConfirmed =
Expand Down Expand Up @@ -525,7 +524,7 @@ construct_runtime!(
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event<T>},
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event<T>},
BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event<T>, Origin<T>},

// Westend bridge modules.
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage},
Expand Down
40 changes: 35 additions & 5 deletions bridges/bin/millau/runtime/src/rialto_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use crate::Runtime;

use bp_messages::{
source_chain::TargetHeaderChain,
source_chain::{SenderOrigin, TargetHeaderChain},
target_chain::{ProvedMessages, SourceHeaderChain},
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
};
Expand Down Expand Up @@ -116,12 +116,23 @@ impl messages::ChainWithMessages for Millau {
}

impl messages::ThisChainWithMessages for Millau {
type Origin = crate::Origin;
type Call = crate::Call;

fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
*lane == [0, 0, 0, 0] ||
*lane == [0, 0, 0, 1] ||
*lane == crate::TokenSwapMessagesLane::get()
fn is_message_accepted(send_origin: &Self::Origin, lane: &LaneId) -> bool {
// lanes 0x00000000 && 0x00000001 are accepting any paid messages, while
// `TokenSwapMessageLane` only accepts messages from token swap pallet
let token_swap_dedicated_lane = crate::TokenSwapMessagesLane::get();
match *lane {
[0, 0, 0, 0] | [0, 0, 0, 1] => send_origin.linked_account().is_some(),
_ if *lane == token_swap_dedicated_lane => matches!(
send_origin.caller,
crate::OriginCaller::BridgeRialtoTokenSwap(
pallet_bridge_token_swap::RawOrigin::TokenSwap { .. }
)
),
_ => false,
}
}

fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
Expand Down Expand Up @@ -277,6 +288,25 @@ impl SourceHeaderChain<bp_rialto::Balance> for Rialto {
}
}

impl SenderOrigin<crate::AccountId> for crate::Origin {
fn linked_account(&self) -> Option<crate::AccountId> {
match self.caller {
crate::OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) =>
Some(submitter.clone()),
crate::OriginCaller::system(frame_system::RawOrigin::Root) |
crate::OriginCaller::system(frame_system::RawOrigin::None) =>
crate::RootAccountForPayments::get(),
crate::OriginCaller::BridgeRialtoTokenSwap(
pallet_bridge_token_swap::RawOrigin::TokenSwap {
ref swap_account_at_this_chain,
..
},
) => Some(swap_account_at_this_chain.clone()),
_ => None,
}
}
}

/// Millau -> Rialto message lane pallet parameters.
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)]
pub enum MillauToRialtoMessagesParameter {
Expand Down
3 changes: 1 addition & 2 deletions bridges/bin/rialto/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,10 +457,9 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
type MessageDeliveryAndDispatchPayment =
pallet_bridge_messages::instant_payments::InstantCurrencyPayments<
Runtime,
(),
WithMillauMessagesInstance,
pallet_balances::Pallet<Runtime>,
GetDeliveryConfirmationTransactionFee,
RootAccountForPayments,
>;
type OnMessageAccepted = ();
type OnDeliveryConfirmed = ();
Expand Down
20 changes: 17 additions & 3 deletions bridges/bin/rialto/runtime/src/millau_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use crate::Runtime;

use bp_messages::{
source_chain::TargetHeaderChain,
source_chain::{SenderOrigin, TargetHeaderChain},
target_chain::{ProvedMessages, SourceHeaderChain},
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
};
Expand Down Expand Up @@ -116,10 +116,11 @@ impl messages::ChainWithMessages for Rialto {
}

impl messages::ThisChainWithMessages for Rialto {
type Origin = crate::Origin;
type Call = crate::Call;

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

fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
Expand Down Expand Up @@ -275,6 +276,19 @@ impl SourceHeaderChain<bp_millau::Balance> for Millau {
}
}

impl SenderOrigin<crate::AccountId> for crate::Origin {
fn linked_account(&self) -> Option<crate::AccountId> {
match self.caller {
crate::OriginCaller::system(frame_system::RawOrigin::Signed(ref submitter)) =>
Some(submitter.clone()),
crate::OriginCaller::system(frame_system::RawOrigin::Root) |
crate::OriginCaller::system(frame_system::RawOrigin::None) =>
crate::RootAccountForPayments::get(),
_ => None,
}
}
}

/// Rialto -> Millau message lane pallet parameters.
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq, TypeInfo)]
pub enum RialtoToMillauMessagesParameter {
Expand Down
5 changes: 2 additions & 3 deletions bridges/bin/runtime-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pallet-bridge-messages = { path = "../../modules/messages", default-features = f
# Substrate dependencies

frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
Expand All @@ -45,6 +45,7 @@ std = [
"bp-runtime/std",
"codec/std",
"frame-support/std",
"frame-system/std",
"hash-db/std",
"pallet-bridge-dispatch/std",
"pallet-bridge-grandpa/std",
Expand All @@ -60,14 +61,12 @@ std = [
]
runtime-benchmarks = [
"ed25519-dalek/u64_backend",
"frame-system",
"pallet-balances",
"pallet-bridge-grandpa/runtime-benchmarks",
"pallet-bridge-messages/runtime-benchmarks",
"sp-state-machine",
"sp-version",
]
integrity-test = [
"frame-system",
"static_assertions",
]
7 changes: 5 additions & 2 deletions bridges/bin/runtime-common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ corresponding chain. There is single exception, though (it may be changed in the

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

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

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

0 comments on commit ed2a308

Please sign in to comment.