Skip to content

Commit

Permalink
Generates private AccountIds from MultiLocations, in a stable & s…
Browse files Browse the repository at this point in the history
…afe way (#484)

Co-authored-by: Chris Li <[email protected]>
  • Loading branch information
imstar15 and chrisli30 authored Dec 11, 2023
1 parent b1f2c29 commit 6f5442a
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 6 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.

3 changes: 3 additions & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ repository = 'https://github.com/OAK-Foundation/OAK-blockchain'
edition = "2021"

[dependencies]
impl-trait-for-tuples = "0.2.2"
codec = { package = "parity-scale-codec", version = "3.0.0", features = [
"derive",
], default-features = false }
Expand All @@ -22,12 +23,14 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v
sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.43" }
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.43" }
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.43" }
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.43" }

## Substrate FRAME Dependencies
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.43" }

## Polkdadot deps
xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.43", default-features = false }
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.43" }

## ORML deps
orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", default-features = false, branch = "polkadot-v0.9.43" }
Expand Down
115 changes: 115 additions & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,118 @@ impl<AbsoluteLocation: Get<MultiLocation>> Reserve
})
}
}

// https://github.com/AstarNetwork/Astar/blob/2a8df8d098f6abc3fdf5aaf6514e94f615f9bdab/primitives/src/xcm/mod.rs#L276-L418
// TODO: remove this after uplift to `polkadot-v0.9.44` or beyond, and replace it with code in XCM builder.

use codec::{Compact, Encode};
use sp_io::hashing::blake2_256;
use sp_std::prelude::*;
use xcm_executor::traits::Convert as XcmConvert;

/// Means of converting a location into a stable and unique descriptive identifier.
pub trait DescribeLocation {
/// Create a description of the given `location` if possible. No two locations should have the
/// same descriptor.
fn describe_location(location: &MultiLocation) -> Option<Vec<u8>>;
}

#[impl_trait_for_tuples::impl_for_tuples(30)]
impl DescribeLocation for Tuple {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
for_tuples!( #(
match Tuple::describe_location(l) {
Some(result) => return Some(result),
None => {},
}
)* );
None
}
}

pub struct DescribeTerminus;
impl DescribeLocation for DescribeTerminus {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, Here) => Some(Vec::new()),
_ => return None,
}
}
}

pub struct DescribePalletTerminal;
impl DescribeLocation for DescribePalletTerminal {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, X1(PalletInstance(i))) =>
Some((b"Pallet", Compact::<u32>::from(*i as u32)).encode()),
_ => return None,
}
}
}

pub struct DescribeAccountId32Terminal;
impl DescribeLocation for DescribeAccountId32Terminal {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, X1(AccountId32 { id, .. })) => Some((b"AccountId32", id).encode()),
_ => return None,
}
}
}

pub struct DescribeAccountKey20Terminal;
impl DescribeLocation for DescribeAccountKey20Terminal {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, X1(AccountKey20 { key, .. })) => Some((b"AccountKey20", key).encode()),
_ => return None,
}
}
}

pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccountKey20Terminal);

pub type DescribeAllTerminal = (
DescribeTerminus,
DescribePalletTerminal,
DescribeAccountId32Terminal,
DescribeAccountKey20Terminal,
);

pub struct DescribeFamily<DescribeInterior>(PhantomData<DescribeInterior>);
impl<Suffix: DescribeLocation> DescribeLocation for DescribeFamily<Suffix> {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, l.interior.first()) {
(0, Some(Parachain(index))) => {
let tail = l.interior.split_first().0;
let interior = Suffix::describe_location(&tail.into())?;
Some((b"ChildChain", Compact::<u32>::from(*index), interior).encode())
},
(1, Some(Parachain(index))) => {
let tail = l.interior.split_first().0;
let interior = Suffix::describe_location(&tail.into())?;
Some((b"SiblingChain", Compact::<u32>::from(*index), interior).encode())
},
(1, _) => {
let tail = l.interior.into();
let interior = Suffix::describe_location(&tail)?;
Some((b"ParentChain", interior).encode())
},
_ => return None,
}
}
}

pub struct HashedDescription<AccountId, Describe>(PhantomData<(AccountId, Describe)>);
impl<AccountId: From<[u8; 32]> + Clone, Describe: DescribeLocation>
XcmConvert<MultiLocation, AccountId> for HashedDescription<AccountId, Describe>
{
fn convert(value: MultiLocation) -> Result<AccountId, MultiLocation> {
if let Some(description) = Describe::describe_location(&value) {
Ok(blake2_256(&description).into())
} else {
Err(value)
}
}
}
8 changes: 6 additions & 2 deletions runtime/neumann/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ use orml_xcm_support::{
DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset,
};

use primitives::AbsoluteAndRelativeReserveProvider;
use primitives::{
AbsoluteAndRelativeReserveProvider, DescribeAllTerminal, DescribeFamily, HashedDescription,
};

parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
Expand All @@ -55,7 +57,9 @@ pub type LocationToAccountId = (
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
Account32Hash<RelayNetwork, AccountId>,
// Generates private `AccountId`s from `MultiLocation`s, in a stable & safe way.
// Replaces the old `Account32Hash` approach.
HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
);

pub type LocalAssetTransactor = MultiCurrencyAdapter<
Expand Down
8 changes: 6 additions & 2 deletions runtime/oak/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ use orml_xcm_support::{
DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset,
};

use primitives::AbsoluteAndRelativeReserveProvider;
use primitives::{
AbsoluteAndRelativeReserveProvider, DescribeAllTerminal, DescribeFamily, HashedDescription,
};

parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
Expand All @@ -57,7 +59,9 @@ pub type LocationToAccountId = (
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
Account32Hash<RelayNetwork, AccountId>,
// Generates private `AccountId`s from `MultiLocation`s, in a stable & safe way.
// Replaces the old `Account32Hash` approach.
HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
);

pub type LocalAssetTransactor = MultiCurrencyAdapter<
Expand Down
8 changes: 6 additions & 2 deletions runtime/turing/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ use orml_xcm_support::{
DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset,
};

use primitives::AbsoluteAndRelativeReserveProvider;
use primitives::{
AbsoluteAndRelativeReserveProvider, DescribeAllTerminal, DescribeFamily, HashedDescription,
};

parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
Expand All @@ -57,7 +59,9 @@ pub type LocationToAccountId = (
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
Account32Hash<RelayNetwork, AccountId>,
// Generates private `AccountId`s from `MultiLocation`s, in a stable & safe way.
// Replaces the old `Account32Hash` approach.
HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
);

pub type LocalAssetTransactor = MultiCurrencyAdapter<
Expand Down

0 comments on commit 6f5442a

Please sign in to comment.