Skip to content

Commit

Permalink
xcm: Align config across all runtimes (#1527)
Browse files Browse the repository at this point in the history
* e2e: test cfg xcm transfers

* dev: Align xcm CurrencyIdConvert with Centrifuge

* Improve un-anchor

* cfg-primitives: Add HashedDescriptionDescribeFamilyAllTerminal

* xcm: Use HashedDescriptionDescribeFamilyAllTerminal
   Instead of `Account32Hash`
  • Loading branch information
NunoAlexandre authored Sep 5, 2023
1 parent 8ca2218 commit 4af6cfb
Show file tree
Hide file tree
Showing 9 changed files with 459 additions and 107 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

11 changes: 10 additions & 1 deletion libs/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde = { version = "1.0.119" }
sp-arithmetic = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }

Expand All @@ -27,20 +28,26 @@ frame-support = { git = "https://github.com/paritytech/substrate", default-featu
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }
pallet-collective = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" }

# cumuluse primitives dependencies
# cumulus primitives dependencies
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.38" }

# XCM primitives dependencies
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.38" }
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.38" }

[features]
default = ["std"]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-collective/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
]
std = [
"serde/std",
"codec/std",
"sp-io/std",
"sp-std/std",
"scale-info/std",
"sp-core/std",
Expand All @@ -51,6 +58,8 @@ std = [
"pallet-collective/std",
"sp-consensus-aura/std",
"cumulus-primitives-core/std",
"xcm/std",
"xcm-executor/std",
]
try-runtime = [
"frame-support/try-runtime",
Expand Down
158 changes: 158 additions & 0 deletions libs/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,161 @@ pub mod liquidity_pools {
}
}
}

pub mod xcm {
use codec::{Compact, Encode};
use sp_io::hashing::blake2_256;
use sp_std::{borrow::Borrow, marker::PhantomData, vec::Vec};
use xcm::prelude::{
AccountId32, AccountKey20, Here, MultiLocation, PalletInstance, Parachain, X1,
};
use xcm_executor::traits::Convert;

/// NOTE: Copied from <https://github.com/moonbeam-foundation/polkadot/blob/d83bb6cc7d7c93ead2fd3cafce0e268fd3f6b9bc/xcm/xcm-builder/src/location_conversion.rs#L25C1-L68C2>
///
/// temporary struct that mimics the behavior of the upstream type that we
/// will move to once we update this repository to Polkadot 0.9.43+.
pub struct HashedDescriptionDescribeFamilyAllTerminal<AccountId>(PhantomData<AccountId>);
impl<AccountId: From<[u8; 32]> + Clone> HashedDescriptionDescribeFamilyAllTerminal<AccountId> {
fn describe_location_suffix(l: &MultiLocation) -> Result<Vec<u8>, ()> {
match (l.parents, &l.interior) {
(0, Here) => Ok(Vec::new()),
(0, X1(PalletInstance(i))) => {
Ok((b"Pallet", Compact::<u32>::from(*i as u32)).encode())
}
(0, X1(AccountId32 { id, .. })) => Ok((b"AccountId32", id).encode()),
(0, X1(AccountKey20 { key, .. })) => Ok((b"AccountKey20", key).encode()),
_ => Err(()),
}
}
}

impl<AccountId: From<[u8; 32]> + Clone> Convert<MultiLocation, AccountId>
for HashedDescriptionDescribeFamilyAllTerminal<AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
let l = location.borrow();
let to_hash = match (l.parents, l.interior.first()) {
(0, Some(Parachain(index))) => {
let tail = l.interior.split_first().0;
let interior = Self::describe_location_suffix(&tail.into())?;
(b"ChildChain", Compact::<u32>::from(*index), interior).encode()
}
(1, Some(Parachain(index))) => {
let tail = l.interior.split_first().0;
let interior = Self::describe_location_suffix(&tail.into())?;
(b"SiblingChain", Compact::<u32>::from(*index), interior).encode()
}
(1, _) => {
let tail = l.interior.into();
let interior = Self::describe_location_suffix(&tail)?;
(b"ParentChain", interior).encode()
}
_ => return Err(()),
};
Ok(blake2_256(&to_hash).into())
}

fn reverse_ref(_: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
Err(())
}
}

#[test]
fn test_hashed_family_all_terminal_converter() {
use xcm::prelude::X2;

type Converter<AccountId> = HashedDescriptionDescribeFamilyAllTerminal<AccountId>;

assert_eq!(
[
129, 211, 14, 6, 146, 54, 225, 200, 135, 103, 248, 244, 125, 112, 53, 133, 91, 42,
215, 236, 154, 199, 191, 208, 110, 148, 223, 55, 92, 216, 250, 34
],
Converter::<[u8; 32]>::convert(MultiLocation {
parents: 0,
interior: X2(
Parachain(1),
AccountId32 {
network: None,
id: [0u8; 32]
}
),
})
.unwrap()
);
assert_eq!(
[
17, 142, 105, 253, 199, 34, 43, 136, 155, 48, 12, 137, 155, 219, 155, 110, 93, 181,
93, 252, 124, 60, 250, 195, 229, 86, 31, 220, 121, 111, 254, 252
],
Converter::<[u8; 32]>::convert(MultiLocation {
parents: 1,
interior: X2(
Parachain(1),
AccountId32 {
network: None,
id: [0u8; 32]
}
),
})
.unwrap()
);
assert_eq!(
[
237, 65, 190, 49, 53, 182, 196, 183, 151, 24, 214, 23, 72, 244, 235, 87, 187, 67,
52, 122, 195, 192, 10, 58, 253, 49, 0, 112, 175, 224, 125, 66
],
Converter::<[u8; 32]>::convert(MultiLocation {
parents: 0,
interior: X2(
Parachain(1),
AccountKey20 {
network: None,
key: [0u8; 20]
}
),
})
.unwrap()
);
assert_eq!(
[
226, 225, 225, 162, 254, 156, 113, 95, 68, 155, 160, 118, 126, 18, 166, 132, 144,
19, 8, 204, 228, 112, 164, 189, 179, 124, 249, 1, 168, 110, 151, 50
],
Converter::<[u8; 32]>::convert(MultiLocation {
parents: 1,
interior: X2(
Parachain(1),
AccountKey20 {
network: None,
key: [0u8; 20]
}
),
})
.unwrap()
);
assert_eq!(
[
254, 186, 179, 229, 13, 24, 84, 36, 84, 35, 64, 95, 114, 136, 62, 69, 247, 74, 215,
104, 121, 114, 53, 6, 124, 46, 42, 245, 121, 197, 12, 208
],
Converter::<[u8; 32]>::convert(MultiLocation {
parents: 1,
interior: X2(Parachain(2), PalletInstance(3)),
})
.unwrap()
);
assert_eq!(
[
217, 56, 0, 36, 228, 154, 250, 26, 200, 156, 1, 39, 254, 162, 16, 187, 107, 67, 27,
16, 218, 254, 250, 184, 6, 27, 216, 138, 194, 93, 23, 165
],
Converter::<[u8; 32]>::convert(MultiLocation {
parents: 1,
interior: Here,
})
.unwrap()
);
}
}
34 changes: 7 additions & 27 deletions runtime/altair/src/xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// GNU General Public License for more details.

use cfg_primitives::{
constants::currency_decimals,
parachains,
types::{EnsureRootOr, HalfOfCouncil},
};
Expand All @@ -33,7 +32,7 @@ use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use runtime_common::{
xcm::{general_key, AccountIdToMultiLocation, FixedConversionRateProvider},
xcm_fees::{default_per_second, ksm_per_second, native_per_second},
xcm_fees::native_per_second,
};
use sp_core::ConstU32;
use sp_runtime::traits::{Convert, Zero};
Expand Down Expand Up @@ -106,28 +105,6 @@ parameter_types! {
native_per_second(),
0,
);

pub AirPerSecond: (AssetId, u128) = (
MultiLocation::new(
1,
X2(Parachain(ParachainInfo::parachain_id().into()), general_key(parachains::kusama::altair::AIR_KEY)),
).into(),
native_per_second(),
);

pub KsmPerSecond: (AssetId, u128) = (MultiLocation::parent().into(), ksm_per_second());

pub AUSDPerSecond: (AssetId, u128) = (
MultiLocation::new(
1,
X2(
Parachain(parachains::kusama::karura::ID),
general_key(parachains::kusama::karura::AUSD_KEY)
)
).into(),
default_per_second(currency_decimals::AUSD)
);

}

pub struct ToTreasury;
Expand Down Expand Up @@ -223,10 +200,12 @@ impl xcm_executor::traits::Convert<MultiLocation, CurrencyId> for CurrencyIdConv
let unanchored_location = match location {
MultiLocation {
parents: 0,
interior: X1(x),
interior,
} => MultiLocation {
parents: 1,
interior: X2(Parachain(u32::from(ParachainInfo::get())), x),
interior: interior
.pushed_front_with(Parachain(u32::from(ParachainInfo::get())))
.map_err(|_| location)?,
},
x => x,
};
Expand Down Expand Up @@ -283,7 +262,6 @@ impl pallet_xcm::Config for Runtime {
}

parameter_types! {
pub const KsmLocation: MultiLocation = MultiLocation::parent();
pub const RelayNetwork: NetworkId = NetworkId::Kusama;
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
Expand All @@ -301,6 +279,8 @@ pub type LocationToAccountId = (
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
// Generate remote accounts according to polkadot standards
cfg_primitives::xcm::HashedDescriptionDescribeFamilyAllTerminal<AccountId>,
);

/// No local origins on this chain are allowed to dispatch XCM sends/executions.
Expand Down
31 changes: 7 additions & 24 deletions runtime/centrifuge/src/xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// GNU General Public License for more details.

use cfg_primitives::{
constants::currency_decimals,
parachains,
types::{EnsureRootOr, HalfOfCouncil},
};
Expand All @@ -35,7 +34,7 @@ use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use runtime_common::{
xcm::{general_key, AccountIdToMultiLocation, FixedConversionRateProvider},
xcm_fees::{default_per_second, native_per_second},
xcm_fees::native_per_second,
};
use sp_core::ConstU32;
use sp_runtime::traits::{Convert, Zero};
Expand Down Expand Up @@ -108,26 +107,6 @@ parameter_types! {
native_per_second(),
0,
);

pub CfgPerSecond: (AssetId, u128) = (
MultiLocation::new(
1,
X2(Parachain(ParachainInfo::parachain_id().into()), general_key(parachains::polkadot::centrifuge::CFG_KEY)),
).into(),
native_per_second(),
);

pub AUSDPerSecond: (AssetId, u128) = (
MultiLocation::new(
1,
X2(
Parachain(parachains::polkadot::acala::ID),
general_key(parachains::polkadot::acala::AUSD_KEY)
)
).into(),
default_per_second(currency_decimals::AUSD)
);

}

pub struct ToTreasury;
Expand Down Expand Up @@ -223,10 +202,12 @@ impl xcm_executor::traits::Convert<MultiLocation, CurrencyId> for CurrencyIdConv
let unanchored_location = match location {
MultiLocation {
parents: 0,
interior: X1(x),
interior,
} => MultiLocation {
parents: 1,
interior: X2(Parachain(u32::from(ParachainInfo::get())), x),
interior: interior
.pushed_front_with(Parachain(u32::from(ParachainInfo::get())))
.map_err(|_| location)?,
},
x => x,
};
Expand Down Expand Up @@ -300,6 +281,8 @@ pub type LocationToAccountId = (
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
// Generate remote accounts according to polkadot standards
cfg_primitives::xcm::HashedDescriptionDescribeFamilyAllTerminal<AccountId>,
);

/// No local origins on this chain are allowed to dispatch XCM sends/executions.
Expand Down
Loading

0 comments on commit 4af6cfb

Please sign in to comment.