Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

relay account and tests #651

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
88 changes: 87 additions & 1 deletion xcm-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@
#![allow(clippy::unused_unit)]

use frame_support::dispatch::{DispatchError, DispatchResult};
use frame_support::{ensure, traits::Contains, weights::Weight};

use sp_runtime::traits::{CheckedConversion, Convert};
use sp_std::{convert::TryFrom, marker::PhantomData, prelude::*};

use xcm::latest::prelude::*;
use xcm_executor::traits::{FilterAssetLocation, MatchesFungible};
use xcm_executor::traits::{FilterAssetLocation, MatchesFungible, ShouldExecute};

use orml_traits::location::Reserve;

pub use currency_adapter::MultiCurrencyAdapter;
use frame_support::pallet_prelude::Get;

mod currency_adapter;

Expand Down Expand Up @@ -75,3 +78,86 @@ impl UnknownAsset for () {
Err(DispatchError::Other(NO_UNKNOWN_ASSET_IMPL))
}
}

/// Extracts the `AccountId32` from the passed `location` if the network
/// matches.
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
pub struct RelaychainAccountId32Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
xcm_executor::traits::Convert<MultiLocation, AccountId> for RelaychainAccountId32Aliases<Network, AccountId>
{
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
let id = match location {
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
MultiLocation {
parents: 1,
interior: X1(AccountId32 {
id,
network: NetworkId::Any,
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
}),
} => id,
MultiLocation {
parents: 1,
interior: X1(AccountId32 { id, network }),
} if network == Network::get() => id,
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
_ => return Err(location),
};
Ok(id.into())
}

fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
Ok((
1,
AccountId32 {
id: who.into(),
network: Network::get(),
},
)
.into())
}
}

/// when Relay an XCM message from a given `interior` location, if the given
/// `interior` is not `Here`, the destination will receive a xcm message
/// beginning with `DescendOrigin` as the first instruction. so the xcm message
/// format must match this order:
/// `DescendOrigin`,`WithdrawAsset`,`BuyExecution`,`Transact`.
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
pub struct AllowEquivalentAccountsFrom<T>(PhantomData<T>);
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
impl<T: Contains<MultiLocation>> ShouldExecute for AllowEquivalentAccountsFrom<T> {
fn should_execute<Call>(
origin: &MultiLocation,
message: &mut Xcm<Call>,
max_weight: Weight,
_weight_credit: &mut Weight,
) -> Result<(), ()> {
ensure!(T::contains(origin), ());
let mut iter = message.0.iter_mut();
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
let i = iter.next().ok_or(())?;
match i {
DescendOrigin(..) => (),
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
_ => return Err(()),
}
let i = iter.next().ok_or(())?;
match i {
WithdrawAsset(..) => (),
_ => return Err(()),
}
let i = iter.next().ok_or(())?;
match i {
BuyExecution {
weight_limit: Limited(ref mut weight),
..
} if *weight >= max_weight => {
*weight = max_weight;
()
}
_ => return Err(()),
}
let i = iter.next().ok_or(())?;
match i {
Transact {
origin_type: OriginKind::SovereignAccount,
..
} => Ok(()),
_ => Err(()),
}
}
}
2 changes: 2 additions & 0 deletions xtokens/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ xcm-simulator = { git = "https://github.com/paritytech/polkadot", branch = "rele
orml-tokens = { path = "../tokens" }
orml-xcm = { path = "../xcm" }

env_logger = "0.8.3"
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved

[features]
default = ["std"]
std = [
Expand Down
41 changes: 37 additions & 4 deletions xtokens/src/mock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,41 @@ use serde::{Deserialize, Serialize};
use sp_io::TestExternalities;
use sp_runtime::AccountId32;

use cumulus_primitives_core::ParaId;
use polkadot_parachain::primitives::{AccountIdConversion, Sibling};
use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain};

pub mod para;
pub mod relay;
pub mod tests;

pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]);
pub const BOB: AccountId32 = AccountId32::new([1u8; 32]);
pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
pub const BOB: AccountId32 = AccountId32::new([2u8; 32]);
pub const DEFAULT: AccountId32 = AccountId32::new([0u8; 32]);
pub const INITIAL_BALANCE: u128 = 1_000;

pub fn para_a_account() -> AccountId32 {
ParaId::from(1).into_account()
}

pub fn para_b_account() -> AccountId32 {
ParaId::from(2).into_account()
}

pub fn sibling_a_account() -> AccountId32 {
use sp_runtime::traits::AccountIdConversion;
Sibling::from(1).into_account()
}

pub fn sibling_b_account() -> AccountId32 {
use sp_runtime::traits::AccountIdConversion;
Sibling::from(2).into_account()
}

pub fn sibling_c_account() -> AccountId32 {
use sp_runtime::traits::AccountIdConversion;
Sibling::from(3).into_account()
}

#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
Expand Down Expand Up @@ -118,9 +146,14 @@ decl_test_network! {
}

pub type RelayBalances = pallet_balances::Pallet<relay::Runtime>;
pub type ParaBalances = pallet_balances::Pallet<para::Runtime>;

pub type ParaTokens = orml_tokens::Pallet<para::Runtime>;
pub type ParaXTokens = orml_xtokens::Pallet<para::Runtime>;

pub type RelayChainPalletXcm = pallet_xcm::Pallet<relay::Runtime>;
pub type ParachainPalletXcm = pallet_xcm::Pallet<para::Runtime>;

pub fn para_ext(para_id: u32) -> TestExternalities {
use para::{Runtime, System};

Expand All @@ -135,7 +168,7 @@ pub fn para_ext(para_id: u32) -> TestExternalities {
.unwrap();

orml_tokens::GenesisConfig::<Runtime> {
balances: vec![(ALICE, CurrencyId::R, 1_000)],
balances: vec![(ALICE, CurrencyId::R, INITIAL_BALANCE)],
}
.assimilate_storage(&mut t)
.unwrap();
Expand All @@ -153,7 +186,7 @@ pub fn relay_ext() -> sp_io::TestExternalities {
.unwrap();

pallet_balances::GenesisConfig::<Runtime> {
balances: vec![(ALICE, 1_000)],
balances: vec![(ALICE, INITIAL_BALANCE)],
}
.assimilate_storage(&mut t)
.unwrap();
Expand Down
11 changes: 9 additions & 2 deletions xtokens/src/mock/para.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ use xcm_builder::{
use xcm_executor::{traits::WeightTrader, Assets, Config, XcmExecutor};

use orml_traits::parameter_type_with_key;
use orml_xcm_support::{IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset};
use orml_xcm_support::{
AllowEquivalentAccountsFrom, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset, RelaychainAccountId32Aliases,
};

pub type AccountId = AccountId32;

Expand Down Expand Up @@ -114,6 +116,7 @@ pub type LocationToAccountId = (
ParentIsDefault<AccountId>,
SiblingParachainConvertsVia<Sibling, AccountId>,
AccountId32Aliases<RelayNetwork, AccountId>,
RelaychainAccountId32Aliases<RelayNetwork, AccountId>,
);

pub type XcmOriginToCallOrigin = (
Expand All @@ -140,7 +143,11 @@ pub type LocalAssetTransactor = MultiCurrencyAdapter<
>;

pub type XcmRouter = ParachainXcmRouter<ParachainInfo>;
pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecutionFrom<Everything>);
pub type Barrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
AllowEquivalentAccountsFrom<Everything>,
);

/// A trader who believes all tokens are created equal to "weight" of any chain,
/// which is not true, but good enough to mock the fee payment of XCM execution.
Expand Down
Loading