@@ -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+
87101pub type DescribeAccountIdTerminal = ( DescribeAccountId32Terminal , DescribeAccountKey20Terminal ) ;
88102
89103pub 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) ]
443477mod 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