@@ -7,7 +7,7 @@ use crate::{v2::LOG_TARGET, CallIndex};
77use codec:: { Decode , DecodeLimit , Encode } ;
88use core:: marker:: PhantomData ;
99use frame_support:: ensure;
10- use snowbridge_core:: TokenId ;
10+ use snowbridge_core:: { ParaId , TokenId } ;
1111use sp_core:: { Get , RuntimeDebug , H160 } ;
1212use sp_io:: hashing:: blake2_256;
1313use sp_runtime:: { traits:: MaybeConvert , MultiAddress } ;
@@ -19,8 +19,6 @@ use xcm::{
1919use xcm_builder:: ExternalConsensusLocationsConverterFor ;
2020use xcm_executor:: traits:: ConvertLocation ;
2121
22- const MINIMUM_DEPOSIT : u128 = 1 ;
23-
2422/// Topic prefix used for generating unique identifiers for messages
2523const INBOUND_QUEUE_TOPIC_PREFIX : & str = "SnowbridgeInboundQueueV2" ;
2624
@@ -47,67 +45,78 @@ pub enum AssetTransfer {
4745 ReserveWithdraw ( Asset ) ,
4846}
4947
48+ #[ derive( Clone , RuntimeDebug , Encode ) ]
49+ pub struct CreateAssetCallInfo {
50+ pub call : CallIndex ,
51+ pub deposit : u128 ,
52+ pub min_balance : u128 ,
53+ }
54+
55+ pub struct AssetHubUniversal < LocalNetwork , AssetHubParaId > (
56+ PhantomData < ( LocalNetwork , AssetHubParaId ) > ,
57+ ) ;
58+ impl < LocalNetwork , AssetHubParaId > Get < InteriorLocation >
59+ for AssetHubUniversal < LocalNetwork , AssetHubParaId >
60+ where
61+ LocalNetwork : Get < NetworkId > ,
62+ AssetHubParaId : Get < ParaId > ,
63+ {
64+ fn get ( ) -> InteriorLocation {
65+ [ GlobalConsensus ( LocalNetwork :: get ( ) ) , Parachain ( AssetHubParaId :: get ( ) . into ( ) ) ] . into ( )
66+ }
67+ }
68+
5069/// Concrete implementation of `ConvertMessage`
5170pub struct MessageToXcm <
5271 CreateAssetCall ,
53- CreateAssetDeposit ,
5472 EthereumNetwork ,
73+ LocalNetwork ,
74+ GatewayProxyAddress ,
5575 InboundQueueLocation ,
76+ AssetHubParaId ,
5677 ConvertAssetId ,
57- GatewayProxyAddress ,
58- EthereumUniversalLocation ,
59- AssetHubFromEthereum ,
60- AssetHubUniversalLocation ,
6178 AccountId ,
6279> {
6380 _phantom : PhantomData < (
6481 CreateAssetCall ,
65- CreateAssetDeposit ,
6682 EthereumNetwork ,
83+ LocalNetwork ,
84+ GatewayProxyAddress ,
6785 InboundQueueLocation ,
86+ AssetHubParaId ,
6887 ConvertAssetId ,
69- GatewayProxyAddress ,
70- EthereumUniversalLocation ,
71- AssetHubFromEthereum ,
72- AssetHubUniversalLocation ,
7388 AccountId ,
7489 ) > ,
7590}
7691
7792impl <
7893 CreateAssetCall ,
79- CreateAssetDeposit ,
8094 EthereumNetwork ,
95+ LocalNetwork ,
96+ GatewayProxyAddress ,
8197 InboundQueueLocation ,
98+ AssetHubParaId ,
8299 ConvertAssetId ,
83- GatewayProxyAddress ,
84- EthereumUniversalLocation ,
85- AssetHubFromEthereum ,
86- AssetHubUniversalLocation ,
87100 AccountId ,
88101 >
89102 MessageToXcm <
90103 CreateAssetCall ,
91- CreateAssetDeposit ,
92104 EthereumNetwork ,
105+ LocalNetwork ,
106+ GatewayProxyAddress ,
93107 InboundQueueLocation ,
108+ AssetHubParaId ,
94109 ConvertAssetId ,
95- GatewayProxyAddress ,
96- EthereumUniversalLocation ,
97- AssetHubFromEthereum ,
98- AssetHubUniversalLocation ,
99110 AccountId ,
100111 >
101112where
102- CreateAssetCall : Get < CallIndex > ,
103- CreateAssetDeposit : Get < u128 > ,
113+ CreateAssetCall : Get < CreateAssetCallInfo > ,
104114 EthereumNetwork : Get < NetworkId > ,
115+ LocalNetwork : Get < NetworkId > ,
116+ GatewayProxyAddress : Get < H160 > ,
105117 InboundQueueLocation : Get < InteriorLocation > ,
118+ AssetHubParaId : Get < ParaId > ,
106119 ConvertAssetId : MaybeConvert < TokenId , Location > ,
107- GatewayProxyAddress : Get < H160 > ,
108- EthereumUniversalLocation : Get < InteriorLocation > ,
109- AssetHubFromEthereum : Get < Location > ,
110- AssetHubUniversalLocation : Get < InteriorLocation > ,
111120 AccountId : Into < [ u8 ; 32 ] > + From < [ u8 ; 32 ] > + Clone ,
112121{
113122 /// Parse the message into an intermediate form, with all fields decoded
@@ -163,12 +172,21 @@ where
163172 assets. push ( AssetTransfer :: ReserveDeposit ( asset) ) ;
164173 } ,
165174 EthereumAsset :: ForeignTokenERC20 { token_id, value } => {
166- let asset_loc = ConvertAssetId :: maybe_convert ( * token_id)
175+ let asset_location = ConvertAssetId :: maybe_convert ( * token_id)
167176 . ok_or ( ConvertMessageError :: InvalidAsset ) ?;
168- let reanchored_asset_loc = asset_loc
169- . reanchored ( & AssetHubFromEthereum :: get ( ) , & EthereumUniversalLocation :: get ( ) )
177+ let asset_hub_from_ethereum: Location = Location :: new (
178+ 1 ,
179+ [
180+ GlobalConsensus ( LocalNetwork :: get ( ) ) ,
181+ Parachain ( AssetHubParaId :: get ( ) . into ( ) ) ,
182+ ] ,
183+ ) ;
184+ let ethereum_universal: InteriorLocation =
185+ [ GlobalConsensus ( EthereumNetwork :: get ( ) ) ] . into ( ) ;
186+ let reanchored_asset_location = asset_location
187+ . reanchored ( & asset_hub_from_ethereum, & ethereum_universal)
170188 . map_err ( |_| ConvertMessageError :: CannotReanchor ) ?;
171- let asset: Asset = ( reanchored_asset_loc , * value) . into ( ) ;
189+ let asset: Asset = ( reanchored_asset_location , * value) . into ( ) ;
172190 assets. push ( AssetTransfer :: ReserveWithdraw ( asset) ) ;
173191 } ,
174192 }
@@ -194,9 +212,10 @@ where
194212 /// Get sovereign account of Ethereum on Asset Hub.
195213 fn bridge_owner ( ) -> Result < AccountId , ConvertMessageError > {
196214 let account =
197- ExternalConsensusLocationsConverterFor :: < AssetHubUniversalLocation , AccountId > :: convert_location (
198- & Location :: new ( 2 , [ GlobalConsensus ( EthereumNetwork :: get ( ) ) ] ) ,
199- )
215+ ExternalConsensusLocationsConverterFor :: <
216+ AssetHubUniversal < LocalNetwork , AssetHubParaId > ,
217+ AccountId ,
218+ > :: convert_location ( & Location :: new ( 2 , [ GlobalConsensus ( EthereumNetwork :: get ( ) ) ] ) )
200219 . ok_or ( ConvertMessageError :: CannotReanchor ) ?;
201220
202221 Ok ( account)
@@ -212,12 +231,13 @@ where
212231 claimer : Location ,
213232 ) -> Result < Xcm < ( ) > , ConvertMessageError > {
214233 let dot_asset = Location :: new ( 1 , Here ) ;
215- let dot_fee: xcm:: prelude:: Asset = ( dot_asset, CreateAssetDeposit :: get ( ) ) . into ( ) ;
234+ let dot_fee: xcm:: prelude:: Asset = ( dot_asset, CreateAssetCall :: get ( ) . deposit ) . into ( ) ;
216235
217236 let eth_asset: xcm:: prelude:: Asset =
218237 ( Location :: new ( 2 , [ GlobalConsensus ( EthereumNetwork :: get ( ) ) ] ) , eth_value) . into ( ) ;
219238
220- let create_call_index: [ u8 ; 2 ] = CreateAssetCall :: get ( ) ;
239+ let create_call_index: [ u8 ; 2 ] = CreateAssetCall :: get ( ) . call ;
240+ let create_min_blance: u128 = CreateAssetCall :: get ( ) . min_balance ;
221241
222242 let asset_id = Location :: new (
223243 2 ,
@@ -230,6 +250,7 @@ where
230250 match network {
231251 super :: message:: Network :: Polkadot => Ok ( Self :: make_create_asset_xcm_for_polkadot (
232252 create_call_index,
253+ create_min_blance,
233254 asset_id,
234255 bridge_owner,
235256 dot_fee,
@@ -242,6 +263,7 @@ where
242263 /// Construct the asset creation XCM for the Polkdot network.
243264 fn make_create_asset_xcm_for_polkadot (
244265 create_call_index : [ u8 ; 2 ] ,
266+ create_min_blance : u128 ,
245267 asset_id : Location ,
246268 bridge_owner : AccountId ,
247269 dot_fee_asset : xcm:: prelude:: Asset ,
@@ -270,7 +292,7 @@ where
270292 create_call_index,
271293 asset_id. clone( ) ,
272294 MultiAddress :: <[ u8 ; 32 ] , ( ) >:: Id ( bridge_owner_bytes. into( ) ) ,
273- MINIMUM_DEPOSIT ,
295+ create_min_blance ,
274296 )
275297 . encode( )
276298 . into( ) ,
@@ -301,39 +323,33 @@ where
301323}
302324
303325impl <
304- CreateAssetCall ,
305- CreateAssetDeposit ,
326+ CreateAsset ,
306327 EthereumNetwork ,
328+ LocalNetwork ,
329+ GatewayProxyAddress ,
307330 InboundQueueLocation ,
331+ AssetHubParaId ,
308332 ConvertAssetId ,
309- GatewayProxyAddress ,
310- EthereumUniversalLocation ,
311- AssetHubFromEthereum ,
312- AssetHubUniversalLocation ,
313333 AccountId ,
314334 > ConvertMessage
315335 for MessageToXcm <
316- CreateAssetCall ,
317- CreateAssetDeposit ,
336+ CreateAsset ,
318337 EthereumNetwork ,
338+ LocalNetwork ,
339+ GatewayProxyAddress ,
319340 InboundQueueLocation ,
341+ AssetHubParaId ,
320342 ConvertAssetId ,
321- GatewayProxyAddress ,
322- EthereumUniversalLocation ,
323- AssetHubFromEthereum ,
324- AssetHubUniversalLocation ,
325343 AccountId ,
326344 >
327345where
328- CreateAssetCall : Get < CallIndex > ,
329- CreateAssetDeposit : Get < u128 > ,
346+ CreateAsset : Get < CreateAssetCallInfo > ,
330347 EthereumNetwork : Get < NetworkId > ,
348+ LocalNetwork : Get < NetworkId > ,
349+ GatewayProxyAddress : Get < H160 > ,
331350 InboundQueueLocation : Get < InteriorLocation > ,
351+ AssetHubParaId : Get < ParaId > ,
332352 ConvertAssetId : MaybeConvert < TokenId , Location > ,
333- GatewayProxyAddress : Get < H160 > ,
334- EthereumUniversalLocation : Get < InteriorLocation > ,
335- AssetHubFromEthereum : Get < Location > ,
336- AssetHubUniversalLocation : Get < InteriorLocation > ,
337353 AccountId : Into < [ u8 ; 32 ] > + From < [ u8 ; 32 ] > + Clone ,
338354{
339355 fn convert ( message : Message ) -> Result < Xcm < ( ) > , ConvertMessageError > {
@@ -405,17 +421,19 @@ mod tests {
405421 const GATEWAY_ADDRESS : [ u8 ; 20 ] = hex ! [ "eda338e4dc46038493b885327842fd3e301cab39" ] ;
406422
407423 parameter_types ! {
408- pub const EthereumNetwork : xcm:: v5:: NetworkId = xcm:: v5:: NetworkId :: Ethereum { chain_id: 1 } ;
424+ pub const EthereumNetwork : NetworkId = NetworkId :: Ethereum { chain_id: 1 } ;
425+ pub const LocalNetwork : NetworkId = NetworkId :: Polkadot ;
409426 pub const GatewayAddress : H160 = H160 ( GATEWAY_ADDRESS ) ;
410427 pub InboundQueueLocation : InteriorLocation = [ PalletInstance ( 84 ) ] . into( ) ;
411428 pub EthereumUniversalLocation : InteriorLocation =
412429 [ GlobalConsensus ( EthereumNetwork :: get( ) ) ] . into( ) ;
413- pub AssetHubFromEthereum : Location = Location :: new( 1 , [ GlobalConsensus ( Polkadot ) , Parachain ( 1000 ) ] ) ;
414- pub AssetHubUniversalLocation : InteriorLocation = [ GlobalConsensus ( Polkadot ) , Parachain ( 1000 ) ] . into( ) ;
415- pub const CreateAssetCall : [ u8 ; 2 ] = [ 53 , 0 ] ;
430+ pub AssetHubParaId : ParaId = 1000 . into( ) ;
431+ pub const CreateAssetCallIndex : [ u8 ; 2 ] = [ 53 , 0 ] ;
416432 pub const CreateAssetDeposit : u128 = 10_000_000_000u128 ;
433+ pub const CreateAssetMinBalance : u128 = 1 ;
417434 pub EthereumLocation : Location = Location :: new( 2 , EthereumUniversalLocation :: get( ) ) ;
418435 pub BridgeHubContext : InteriorLocation = [ GlobalConsensus ( Polkadot ) , Parachain ( 1002 ) ] . into( ) ;
436+ pub CreateAssetCall : CreateAssetCallInfo = CreateAssetCallInfo { call: CreateAssetCallIndex :: get( ) , deposit: CreateAssetDeposit :: get( ) , min_balance: CreateAssetMinBalance :: get( ) } ;
419437 }
420438
421439 pub struct MockFailedTokenConvert ;
@@ -427,27 +445,23 @@ mod tests {
427445
428446 type Converter = MessageToXcm <
429447 CreateAssetCall ,
430- CreateAssetDeposit ,
431448 EthereumNetwork ,
449+ LocalNetwork ,
450+ GatewayAddress ,
432451 InboundQueueLocation ,
452+ AssetHubParaId ,
433453 LocationIdConvert ,
434- GatewayAddress ,
435- EthereumUniversalLocation ,
436- AssetHubFromEthereum ,
437- AssetHubUniversalLocation ,
438454 [ u8 ; 32 ] ,
439455 > ;
440456
441457 type ConverterFailing = MessageToXcm <
442458 CreateAssetCall ,
443- CreateAssetDeposit ,
444459 EthereumNetwork ,
460+ LocalNetwork ,
461+ GatewayAddress ,
445462 InboundQueueLocation ,
463+ AssetHubParaId ,
446464 MockFailedTokenConvert ,
447- GatewayAddress ,
448- EthereumUniversalLocation ,
449- AssetHubFromEthereum ,
450- AssetHubUniversalLocation ,
451465 [ u8 ; 32 ] ,
452466 > ;
453467
@@ -746,7 +760,7 @@ mod tests {
746760
747761 // actual claimer should default to Snowbridge sovereign account
748762 let bridge_owner = ExternalConsensusLocationsConverterFor :: <
749- AssetHubUniversalLocation ,
763+ AssetHubUniversal < LocalNetwork , AssetHubParaId > ,
750764 [ u8 ; 32 ] ,
751765 > :: convert_location ( & Location :: new (
752766 2 ,
0 commit comments