Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub use pallet_bridge_messages::Call as MessagesCall;
pub use pallet_bridge_parachains::Call as BridgeParachainsCall;
pub use pallet_sudo::Call as SudoCall;
pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_xcm::Call as XcmCall;

#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
Expand Down
4 changes: 3 additions & 1 deletion bin/millau/runtime/src/rialto_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ use scale_info::TypeInfo;
use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128};
use sp_std::convert::TryFrom;

/// Default lane that is used to send messages to Rialto.
pub const DEFAULT_XCM_LANE_TO_RIALTO: LaneId = [0, 0, 0, 0];
/// Initial value of `RialtoToMillauConversionRate` parameter.
pub const INITIAL_RIALTO_TO_MILLAU_CONVERSION_RATE: FixedU128 =
FixedU128::from_inner(FixedU128::DIV);
Expand Down Expand Up @@ -149,7 +151,7 @@ impl messages::ThisChainWithMessages for Millau {
},
}

*lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1]
*lane == DEFAULT_XCM_LANE_TO_RIALTO || *lane == [0, 0, 0, 1]
}

fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
Expand Down
4 changes: 3 additions & 1 deletion bin/millau/runtime/src/rialto_parachain_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ use scale_info::TypeInfo;
use sp_runtime::{traits::Saturating, FixedPointNumber, FixedU128};
use sp_std::convert::TryFrom;

/// Default lane that is used to send messages to Rialto parachain.
pub const DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN: LaneId = [0, 0, 0, 0];
/// Weight of 2 XCM instructions is for simple `Trap(42)` program, coming through bridge
/// (it is prepended with `UniversalOrigin` instruction). It is used just for simplest manual
/// tests, confirming that we don't break encoding somewhere between.
Expand Down Expand Up @@ -138,7 +140,7 @@ impl messages::ThisChainWithMessages for Millau {
>;

fn is_message_accepted(_send_origin: &Self::Origin, lane: &LaneId) -> bool {
*lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1]
*lane == DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN || *lane == [0, 0, 0, 1]
}

fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
Expand Down
135 changes: 71 additions & 64 deletions bin/millau/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@
//! XCM configurations for the Millau runtime.

use super::{
rialto_messages::WithRialtoMessageBridge, AccountId, AllPalletsWithSystem, Balances,
BridgeRialtoMessages, Call, Event, Origin, Runtime, XcmPallet,
rialto_messages::{WithRialtoMessageBridge, DEFAULT_XCM_LANE_TO_RIALTO},
rialto_parachain_messages::{
WithRialtoParachainMessageBridge, DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN,
},
AccountId, AllPalletsWithSystem, Balances, Call, Event, Origin, Runtime,
WithRialtoMessagesInstance, WithRialtoParachainMessagesInstance, XcmPallet,
};
use bp_messages::source_chain::MessagesBridge;
use bp_millau::{Balance, WeightToFee};
use bridge_runtime_common::messages::{
source::{estimate_message_dispatch_and_delivery_fee, FromThisChainMessagePayload},
MessageBridge,
};
use codec::Encode;
use bp_messages::LaneId;
use bp_millau::WeightToFee;
use bp_rialto_parachain::RIALTO_PARACHAIN_ID;
use bridge_runtime_common::messages::source::{XcmBridge, XcmBridgeAdapter};
use frame_support::{
parameter_types,
traits::{Everything, Nothing},
weights::Weight,
};
use sp_std::marker::PhantomData;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom,
Expand All @@ -49,6 +49,8 @@ parameter_types! {
pub const ThisNetwork: NetworkId = Kusama;
/// The Rialto network ID, associated with Polkadot.
pub const RialtoNetwork: NetworkId = Polkadot;
/// The RialtoParachain network ID, associated with Westend.
pub const RialtoParachainNetwork: NetworkId = Westend;
Comment thread
serban300 marked this conversation as resolved.

/// Our XCM location ancestry - i.e. our location within the Consensus Universe.
///
Expand Down Expand Up @@ -105,7 +107,9 @@ parameter_types! {
/// individual routers.
pub type XcmRouter = (
// Router to send messages to Rialto.
ToRialtoBridge<BridgeRialtoMessages>,
XcmBridgeAdapter<ToRialtoBridge>,
// Router to send messages to RialtoParachains.
XcmBridgeAdapter<ToRialtoParachainBridge>,
);

parameter_types! {
Expand Down Expand Up @@ -189,60 +193,56 @@ impl pallet_xcm::Config for Runtime {
type MaxLockers = frame_support::traits::ConstU32<8>;
}

/// With-rialto bridge.
pub struct ToRialtoBridge<MB>(PhantomData<MB>);

impl<MB: MessagesBridge<Origin, AccountId, Balance, FromThisChainMessagePayload>> SendXcm
for ToRialtoBridge<MB>
{
type Ticket = (Balance, FromThisChainMessagePayload);

fn validate(
dest: &mut Option<MultiLocation>,
msg: &mut Option<Xcm<()>>,
) -> SendResult<Self::Ticket> {
let d = dest.take().ok_or(SendError::MissingArgument)?;
if !matches!(d, MultiLocation { parents: 1, interior: X1(GlobalConsensus(r)) } if r == RialtoNetwork::get())
{
*dest = Some(d);
return Err(SendError::NotApplicable)
};
/// With-Rialto bridge.
pub struct ToRialtoBridge;

impl XcmBridge for ToRialtoBridge {
type MessageBridge = WithRialtoMessageBridge;
type MessageSender = pallet_bridge_messages::Pallet<Runtime, WithRialtoMessagesInstance>;

fn universal_location() -> InteriorMultiLocation {
UniversalLocation::get()
}

fn verify_destination(dest: &MultiLocation) -> bool {
matches!(*dest, MultiLocation { parents: 1, interior: X1(GlobalConsensus(r)) } if r == RialtoNetwork::get())
}

fn build_destination() -> MultiLocation {
let dest: InteriorMultiLocation = RialtoNetwork::get().into();
let here = UniversalLocation::get();
let route = dest.relative_to(&here);
let msg = (route, msg.take().unwrap()).encode();
dest.relative_to(&here)
}

let fee = estimate_message_dispatch_and_delivery_fee::<WithRialtoMessageBridge>(
&msg,
WithRialtoMessageBridge::RELAYER_FEE_PERCENT,
None,
)
.map_err(SendError::Transport)?;
let fee_assets = MultiAssets::from((Here, fee));
fn xcm_lane() -> LaneId {
DEFAULT_XCM_LANE_TO_RIALTO
}
}

/// With-RialtoParachain bridge.
pub struct ToRialtoParachainBridge;

impl XcmBridge for ToRialtoParachainBridge {
type MessageBridge = WithRialtoParachainMessageBridge;
type MessageSender =
pallet_bridge_messages::Pallet<Runtime, WithRialtoParachainMessagesInstance>;

Ok(((fee, msg), fee_assets))
fn universal_location() -> InteriorMultiLocation {
UniversalLocation::get()
}

fn deliver(ticket: Self::Ticket) -> Result<XcmHash, SendError> {
let lane = [0, 0, 0, 0];
let (fee, msg) = ticket;
let result = MB::send_message(
pallet_xcm::Origin::from(MultiLocation::from(UniversalLocation::get())).into(),
lane,
msg,
fee,
);
result
.map(|artifacts| {
let hash = (lane, artifacts.nonce).using_encoded(sp_io::hashing::blake2_256);
log::debug!(target: "runtime::bridge", "Sent XCM message {:?}/{} to Millau: {:?}", lane, artifacts.nonce, hash);
hash
})
.map_err(|e| {
log::debug!(target: "runtime::bridge", "Failed to send XCM message over lane {:?} to Millau: {:?}", lane, e);
SendError::Transport("Bridge has rejected the message")
})
fn verify_destination(dest: &MultiLocation) -> bool {
matches!(*dest, MultiLocation { parents: 1, interior: X2(GlobalConsensus(r), Parachain(RIALTO_PARACHAIN_ID)) } if r == RialtoNetwork::get())
}

fn build_destination() -> MultiLocation {
let dest: InteriorMultiLocation = RialtoParachainNetwork::get().into();
let here = UniversalLocation::get();
dest.relative_to(&here)
}

fn xcm_lane() -> LaneId {
DEFAULT_XCM_LANE_TO_RIALTO_PARACHAIN
}
}

Expand All @@ -255,6 +255,7 @@ mod tests {
};
use bp_runtime::messages::MessageDispatchResult;
use bridge_runtime_common::messages::target::FromBridgedChainMessageDispatch;
use codec::Encode;

fn new_test_ext() -> sp_io::TestExternalities {
sp_io::TestExternalities::new(
Expand All @@ -263,17 +264,23 @@ mod tests {
}

#[test]
fn xcm_messages_to_rialto_are_sent() {
fn xcm_messages_are_sent_using_bridge_router() {
new_test_ext().execute_with(|| {
// the encoded message (origin ++ xcm) is 0x010109020419A8
let dest = (Parent, X1(GlobalConsensus(RialtoNetwork::get())));
let xcm: Xcm<()> = vec![Instruction::Trap(42)].into();

let send_result = send_xcm::<XcmRouter>(dest.into(), xcm);
let expected_fee = MultiAssets::from((Here, 4_345_002_552_u64));
let expected_hash =
([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256);
assert_eq!(send_result, Ok((expected_hash, expected_fee)),);

// message 1 to Rialto
let dest = (Parent, X1(GlobalConsensus(RialtoNetwork::get())));
let send_result = send_xcm::<XcmRouter>(dest.into(), xcm.clone());
assert_eq!(send_result, Ok((expected_hash, expected_fee.clone())));

// message 2 to RialtoParachain (expected hash is the same, since other lane is used)
let dest =
(Parent, X2(GlobalConsensus(RialtoNetwork::get()), Parachain(RIALTO_PARACHAIN_ID)));
let send_result = send_xcm::<XcmRouter>(dest.into(), xcm);
assert_eq!(send_result, Ok((expected_hash, expected_fee)));
})
}

Expand Down
Loading