Skip to content

Commit 70d4907

Browse files
samelamingavofyorkfranciscoaguirrebkonturbkchr
authored
allow treasury to do reserve asset transfers (#1447)
This pr resolves #1428. *Added only to Kusama for now* I did raise it [here](polkadot-fellows/runtimes#19) and we discussed creating a chopsticks test to run an end-to-end test however, to do that I will need a build agent/custom runner that is powerful enough to run the build I will be doing that separately as I still think having chopsticks test your runtime with each commit will be very powerful and extremely useful for the ecosystem For now I have used XCM simulator and replicated what the other reserve tests do --------- Co-authored-by: Gavin Wood <[email protected]> Co-authored-by: Francisco Aguirre <[email protected]> Co-authored-by: Branislav Kontur <[email protected]> Co-authored-by: Bastian Köcher <[email protected]>
1 parent b5aee6e commit 70d4907

File tree

2 files changed

+107
-4
lines changed

2 files changed

+107
-4
lines changed

polkadot/xcm/xcm-builder/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ pub use location_conversion::{
3333
Account32Hash, AccountId32Aliases, AccountKey20Aliases, AliasesIntoAccountId32,
3434
ChildParachainConvertsVia, DescribeAccountId32Terminal, DescribeAccountIdTerminal,
3535
DescribeAccountKey20Terminal, DescribeAllTerminal, DescribeBodyTerminal, DescribeFamily,
36-
DescribeLocation, DescribePalletTerminal, DescribeTerminus, GlobalConsensusConvertsFor,
37-
GlobalConsensusParachainConvertsFor, HashedDescription, ParentIsPreset,
38-
SiblingParachainConvertsVia,
36+
DescribeLocation, DescribePalletTerminal, DescribeTerminus, DescribeTreasuryVoiceTerminal,
37+
GlobalConsensusConvertsFor, GlobalConsensusParachainConvertsFor, HashedDescription,
38+
LocalTreasuryVoiceConvertsVia, ParentIsPreset, SiblingParachainConvertsVia,
3939
};
4040

4141
mod origin_conversion;

polkadot/xcm/xcm-builder/src/location_conversion.rs

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ impl DescribeLocation for DescribeAccountKey20Terminal {
8484
}
8585
}
8686

87+
/// Create a description of the remote treasury `location` if possible. No two locations should have
88+
/// the same descriptor.
89+
pub struct DescribeTreasuryVoiceTerminal;
90+
91+
impl DescribeLocation for DescribeTreasuryVoiceTerminal {
92+
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
93+
match (l.parents, &l.interior) {
94+
(0, X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice })) =>
95+
Some((b"Treasury", b"Voice").encode()),
96+
_ => None,
97+
}
98+
}
99+
}
100+
87101
pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccountKey20Terminal);
88102

89103
pub struct DescribeBodyTerminal;
@@ -101,6 +115,7 @@ pub type DescribeAllTerminal = (
101115
DescribePalletTerminal,
102116
DescribeAccountId32Terminal,
103117
DescribeAccountKey20Terminal,
118+
DescribeTreasuryVoiceTerminal,
104119
DescribeBodyTerminal,
105120
);
106121

@@ -328,6 +343,25 @@ impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 32]> + Into<[u8; 32]>
328343
}
329344
}
330345

346+
/// Returns specified `TreasuryAccount` as `AccountId32` if passed `location` matches Treasury
347+
/// plurality.
348+
pub struct LocalTreasuryVoiceConvertsVia<TreasuryAccount, AccountId>(
349+
PhantomData<(TreasuryAccount, AccountId)>,
350+
);
351+
impl<TreasuryAccount: Get<AccountId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
352+
ConvertLocation<AccountId> for LocalTreasuryVoiceConvertsVia<TreasuryAccount, AccountId>
353+
{
354+
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
355+
match *location {
356+
MultiLocation {
357+
parents: 0,
358+
interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }),
359+
} => Some((TreasuryAccount::get().into() as [u8; 32]).into()),
360+
_ => None,
361+
}
362+
}
363+
}
364+
331365
/// Conversion implementation which converts from a `[u8; 32]`-based `AccountId` into a
332366
/// `MultiLocation` consisting solely of a `AccountId32` junction with a fixed value for its
333367
/// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`.
@@ -442,10 +476,13 @@ impl<UniversalLocation, AccountId>
442476
#[cfg(test)]
443477
mod tests {
444478
use super::*;
445-
479+
use primitives::AccountId;
446480
pub type ForeignChainAliasAccount<AccountId> =
447481
HashedDescription<AccountId, LegacyDescribeForeignChainAccount>;
448482

483+
pub type ForeignChainAliasTreasuryAccount<AccountId> =
484+
HashedDescription<AccountId, DescribeFamily<DescribeTreasuryVoiceTerminal>>;
485+
449486
use frame_support::parameter_types;
450487
use xcm::latest::Junction;
451488

@@ -936,4 +973,70 @@ mod tests {
936973
};
937974
assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none());
938975
}
976+
977+
#[test]
978+
fn remote_account_convert_on_para_sending_from_remote_para_treasury() {
979+
let relay_treasury_to_para_location = MultiLocation {
980+
parents: 1,
981+
interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }),
982+
};
983+
let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location(
984+
&relay_treasury_to_para_location,
985+
)
986+
.unwrap();
987+
988+
assert_eq!(
989+
[
990+
18, 84, 93, 74, 187, 212, 254, 71, 192, 127, 112, 51, 3, 42, 54, 24, 220, 185, 161,
991+
67, 205, 154, 108, 116, 108, 166, 226, 211, 29, 11, 244, 115
992+
],
993+
actual_description
994+
);
995+
996+
let para_to_para_treasury_location = MultiLocation {
997+
parents: 1,
998+
interior: X2(
999+
Parachain(1001),
1000+
Plurality { id: BodyId::Treasury, part: BodyPart::Voice },
1001+
),
1002+
};
1003+
let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location(
1004+
&para_to_para_treasury_location,
1005+
)
1006+
.unwrap();
1007+
1008+
assert_eq!(
1009+
[
1010+
202, 52, 249, 30, 7, 99, 135, 128, 153, 139, 176, 141, 138, 234, 163, 150, 7, 36,
1011+
204, 92, 220, 137, 87, 57, 73, 91, 243, 189, 245, 200, 217, 204
1012+
],
1013+
actual_description
1014+
);
1015+
}
1016+
1017+
#[test]
1018+
fn local_account_convert_on_para_from_relay_treasury() {
1019+
let location = MultiLocation {
1020+
parents: 0,
1021+
interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }),
1022+
};
1023+
1024+
parameter_types! {
1025+
pub TreasuryAccountId: AccountId = AccountId::new([42u8; 32]);
1026+
}
1027+
1028+
let actual_description =
1029+
LocalTreasuryVoiceConvertsVia::<TreasuryAccountId, [u8; 32]>::convert_location(
1030+
&location,
1031+
)
1032+
.unwrap();
1033+
1034+
assert_eq!(
1035+
[
1036+
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
1037+
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42
1038+
],
1039+
actual_description
1040+
);
1041+
}
9391042
}

0 commit comments

Comments
 (0)