@@ -38,49 +38,35 @@ mod test;
3838
3939use codec:: { Decode , DecodeAll , Encode } ;
4040use envelope:: Envelope ;
41- use frame_support:: {
42- traits:: {
43- fungible:: { Inspect , Mutate } ,
44- tokens:: { Fortitude , Preservation } ,
45- } ,
46- weights:: WeightToFee ,
47- PalletError ,
48- } ;
41+ use frame_support:: PalletError ;
4942use frame_system:: ensure_signed;
5043use scale_info:: TypeInfo ;
5144use sp_core:: H160 ;
52- use sp_runtime:: traits:: Zero ;
5345use sp_std:: vec;
54- use xcm:: prelude:: {
55- send_xcm, Junction :: * , Location , SendError as XcmpSendError , SendXcm , Xcm , XcmContext , XcmHash ,
46+ use xcm:: {
47+ prelude:: { send_xcm, Junction :: * , Location , SendError as XcmpSendError , SendXcm , Xcm } ,
48+ VersionedXcm , MAX_XCM_DECODE_DEPTH ,
5649} ;
57- use xcm_executor:: traits:: TransactAsset ;
5850
5951use snowbridge_core:: {
6052 inbound:: { Message , VerificationError , Verifier } ,
61- sibling_sovereign_account, BasicOperatingMode , Channel , ChannelId , ParaId , PricingParameters ,
62- StaticLookup ,
63- } ;
64- use snowbridge_router_primitives:: inbound:: v2:: {
65- ConvertMessage , ConvertMessageError , VersionedMessage ,
53+ BasicOperatingMode ,
6654} ;
67- use sp_runtime :: { traits :: Saturating , SaturatedConversion , TokenError } ;
55+ use snowbridge_router_primitives :: inbound :: v2 :: Message as MessageV2 ;
6856
6957pub use weights:: WeightInfo ;
7058
7159#[ cfg( feature = "runtime-benchmarks" ) ]
7260use snowbridge_beacon_primitives:: BeaconHeader ;
7361
74- type BalanceOf < T > =
75- <<T as pallet:: Config >:: Token as Inspect < <T as frame_system:: Config >:: AccountId > >:: Balance ;
76-
7762pub use pallet:: * ;
7863
79- pub const LOG_TARGET : & str = "snowbridge-inbound-queue" ;
64+ pub const LOG_TARGET : & str = "snowbridge-inbound-queue:v2 " ;
8065
8166#[ frame_support:: pallet]
8267pub mod pallet {
8368 use super :: * ;
69+ use codec:: DecodeLimit ;
8470
8571 use frame_support:: pallet_prelude:: * ;
8672 use frame_system:: pallet_prelude:: * ;
@@ -101,44 +87,17 @@ pub mod pallet {
10187 /// The verifier for inbound messages from Ethereum
10288 type Verifier : Verifier ;
10389
104- /// Message relayers are rewarded with this asset
105- type Token : Mutate < Self :: AccountId > + Inspect < Self :: AccountId > ;
106-
10790 /// XCM message sender
10891 type XcmSender : SendXcm ;
10992
110- // Address of the Gateway contract
93+ /// Address of the Gateway contract
11194 #[ pallet:: constant]
11295 type GatewayAddress : Get < H160 > ;
11396
114- /// Convert inbound message to XCM
115- type MessageConverter : ConvertMessage <
116- AccountId = Self :: AccountId ,
117- Balance = BalanceOf < Self > ,
118- > ;
119-
120- /// Lookup a channel descriptor
121- type ChannelLookup : StaticLookup < Source = ChannelId , Target = Channel > ;
122-
123- /// Lookup pricing parameters
124- type PricingParameters : Get < PricingParameters < BalanceOf < Self > > > ;
125-
12697 type WeightInfo : WeightInfo ;
12798
12899 #[ cfg( feature = "runtime-benchmarks" ) ]
129100 type Helper : BenchmarkHelper < Self > ;
130-
131- /// Convert a weight value into deductible balance type.
132- type WeightToFee : WeightToFee < Balance = BalanceOf < Self > > ;
133-
134- /// Convert a length value into deductible balance type
135- type LengthToFee : WeightToFee < Balance = BalanceOf < Self > > ;
136-
137- /// The upper limit here only used to estimate delivery cost
138- type MaxMessageSize : Get < u32 > ;
139-
140- /// To withdraw and deposit an asset.
141- type AssetTransactor : TransactAsset ;
142101 }
143102
144103 #[ pallet:: hooks]
@@ -149,14 +108,10 @@ pub mod pallet {
149108 pub enum Event < T : Config > {
150109 /// A message was received from Ethereum
151110 MessageReceived {
152- /// The message channel
153- channel_id : ChannelId ,
154111 /// The message nonce
155112 nonce : u64 ,
156113 /// ID of the XCM message which was forwarded to the final destination parachain
157114 message_id : [ u8 ; 32 ] ,
158- /// Fee burned for the teleport
159- fee_burned : BalanceOf < T > ,
160115 } ,
161116 /// Set OperatingMode
162117 OperatingModeChanged { mode : BasicOperatingMode } ,
@@ -184,8 +139,6 @@ pub mod pallet {
184139 Verification ( VerificationError ) ,
185140 /// XCMP send failure
186141 Send ( SendError ) ,
187- /// Message conversion error
188- ConvertMessage ( ConvertMessageError ) ,
189142 }
190143
191144 #[ derive( Clone , Encode , Decode , Eq , PartialEq , Debug , TypeInfo , PalletError ) ]
@@ -215,9 +168,9 @@ pub mod pallet {
215168 }
216169 }
217170
218- /// The current nonce for each channel
171+ /// The nonce of the message been processed or not
219172 #[ pallet:: storage]
220- pub type Nonce < T : Config > = StorageMap < _ , Twox64Concat , ChannelId , u64 , ValueQuery > ;
173+ pub type Nonce < T : Config > = StorageMap < _ , Identity , u64 , bool , ValueQuery > ;
221174
222175 /// The current operating mode of the pallet.
223176 #[ pallet:: storage]
@@ -230,7 +183,7 @@ pub mod pallet {
230183 #[ pallet:: call_index( 0 ) ]
231184 #[ pallet:: weight( T :: WeightInfo :: submit( ) ) ]
232185 pub fn submit ( origin : OriginFor < T > , message : Message ) -> DispatchResult {
233- let who = ensure_signed ( origin) ?;
186+ let _who = ensure_signed ( origin) ?;
234187 ensure ! ( !Self :: operating_mode( ) . is_halted( ) , Error :: <T >:: Halted ) ;
235188
236189 // submit message to verifier for verification
@@ -244,63 +197,46 @@ pub mod pallet {
244197 // Verify that the message was submitted from the known Gateway contract
245198 ensure ! ( T :: GatewayAddress :: get( ) == envelope. gateway, Error :: <T >:: InvalidGateway ) ;
246199
247- // Retrieve the registered channel for this message
248- let channel =
249- T :: ChannelLookup :: lookup ( envelope. channel_id ) . ok_or ( Error :: < T > :: InvalidChannel ) ?;
250-
251- // Verify message nonce
252- <Nonce < T > >:: try_mutate ( envelope. channel_id , |nonce| -> DispatchResult {
253- if * nonce == u64:: MAX {
254- return Err ( Error :: < T > :: MaxNonceReached . into ( ) )
255- }
256- if envelope. nonce != nonce. saturating_add ( 1 ) {
257- Err ( Error :: < T > :: InvalidNonce . into ( ) )
258- } else {
259- * nonce = nonce. saturating_add ( 1 ) ;
260- Ok ( ( ) )
261- }
262- } ) ?;
263-
264- // Reward relayer from the sovereign account of the destination parachain, only if funds
265- // are available
266- let sovereign_account = sibling_sovereign_account :: < T > ( channel. para_id ) ;
267- let delivery_cost = Self :: calculate_delivery_cost ( message. encode ( ) . len ( ) as u32 ) ;
268- let amount = T :: Token :: reducible_balance (
269- & sovereign_account,
270- Preservation :: Preserve ,
271- Fortitude :: Polite ,
272- )
273- . min ( delivery_cost) ;
274- if !amount. is_zero ( ) {
275- T :: Token :: transfer ( & sovereign_account, & who, amount, Preservation :: Preserve ) ?;
276- }
200+ // Verify the message has not been processed
201+ ensure ! ( !<Nonce <T >>:: contains_key( envelope. nonce) , Error :: <T >:: InvalidNonce ) ;
277202
278- // Decode payload into `VersionedMessage `
279- let message = VersionedMessage :: decode_all ( & mut envelope. payload . as_ref ( ) )
203+ // Decode payload into `MessageV2 `
204+ let message = MessageV2 :: decode_all ( & mut envelope. payload . as_ref ( ) )
280205 . map_err ( |_| Error :: < T > :: InvalidPayload ) ?;
281206
282- // Decode message into XCM
283- let ( xcm, fee) = Self :: do_convert ( envelope. message_id , message. clone ( ) ) ?;
207+ // Decode xcm
208+ let versioned_xcm = VersionedXcm :: < ( ) > :: decode_with_depth_limit (
209+ MAX_XCM_DECODE_DEPTH ,
210+ & mut message. xcm . as_ref ( ) ,
211+ )
212+ . map_err ( |_| Error :: < T > :: InvalidPayload ) ?;
213+ let xcm: Xcm < ( ) > = versioned_xcm. try_into ( ) . map_err ( |_| <Error < T > >:: InvalidPayload ) ?;
284214
285215 log:: info!(
286216 target: LOG_TARGET ,
287- "💫 xcm decoded as {:?} with fee {:?} " ,
217+ "💫 xcm decoded as {:?}" ,
288218 xcm,
289- fee
290219 ) ;
291220
292- // Burning fees for teleport
293- Self :: burn_fees ( channel. para_id , fee) ?;
221+ // Set nonce flag to true
222+ <Nonce < T > >:: try_mutate ( envelope. nonce , |done| -> DispatchResult {
223+ * done = true ;
224+ Ok ( ( ) )
225+ } ) ?;
226+
227+ // Todo: Deposit fee(in Ether) to RewardLeger which should cover all of:
228+ // T::RewardLeger::deposit(who, envelope.fee.into())?;
229+ // a. The submit extrinsic cost on BH
230+ // b. The delivery cost to AH
231+ // c. The execution cost on AH
232+ // d. The execution cost on destination chain(if any)
233+ // e. The reward
294234
295- // Attempt to send XCM to a dest parachain
296- let message_id = Self :: send_xcm ( xcm, channel. para_id ) ?;
235+ // Attempt to forward XCM to AH
236+ let dest = Location :: new ( 1 , [ Parachain ( 1000 ) ] ) ;
237+ let ( message_id, _) = send_xcm :: < T :: XcmSender > ( dest, xcm) . map_err ( Error :: < T > :: from) ?;
297238
298- Self :: deposit_event ( Event :: MessageReceived {
299- channel_id : envelope. channel_id ,
300- nonce : envelope. nonce ,
301- message_id,
302- fee_burned : fee,
303- } ) ;
239+ Self :: deposit_event ( Event :: MessageReceived { nonce : envelope. nonce , message_id } ) ;
304240
305241 Ok ( ( ) )
306242 }
@@ -318,61 +254,4 @@ pub mod pallet {
318254 Ok ( ( ) )
319255 }
320256 }
321-
322- impl < T : Config > Pallet < T > {
323- pub fn do_convert (
324- message_id : H256 ,
325- message : VersionedMessage ,
326- ) -> Result < ( Xcm < ( ) > , BalanceOf < T > ) , Error < T > > {
327- let ( xcm, fee) = T :: MessageConverter :: convert ( message_id, message)
328- . map_err ( |e| Error :: < T > :: ConvertMessage ( e) ) ?;
329- Ok ( ( xcm, fee) )
330- }
331-
332- pub fn send_xcm ( xcm : Xcm < ( ) > , dest : ParaId ) -> Result < XcmHash , Error < T > > {
333- let dest = Location :: new ( 1 , [ Parachain ( dest. into ( ) ) ] ) ;
334- let ( xcm_hash, _) = send_xcm :: < T :: XcmSender > ( dest, xcm) . map_err ( Error :: < T > :: from) ?;
335- Ok ( xcm_hash)
336- }
337-
338- pub fn calculate_delivery_cost ( length : u32 ) -> BalanceOf < T > {
339- let weight_fee = T :: WeightToFee :: weight_to_fee ( & T :: WeightInfo :: submit ( ) ) ;
340- let len_fee = T :: LengthToFee :: weight_to_fee ( & Weight :: from_parts ( length as u64 , 0 ) ) ;
341- weight_fee
342- . saturating_add ( len_fee)
343- . saturating_add ( T :: PricingParameters :: get ( ) . rewards . local )
344- }
345-
346- /// Burn the amount of the fee embedded into the XCM for teleports
347- pub fn burn_fees ( para_id : ParaId , fee : BalanceOf < T > ) -> DispatchResult {
348- let dummy_context =
349- XcmContext { origin : None , message_id : Default :: default ( ) , topic : None } ;
350- let dest = Location :: new ( 1 , [ Parachain ( para_id. into ( ) ) ] ) ;
351- let fees = ( Location :: parent ( ) , fee. saturated_into :: < u128 > ( ) ) . into ( ) ;
352- T :: AssetTransactor :: can_check_out ( & dest, & fees, & dummy_context) . map_err ( |error| {
353- log:: error!(
354- target: LOG_TARGET ,
355- "XCM asset check out failed with error {:?}" , error
356- ) ;
357- TokenError :: FundsUnavailable
358- } ) ?;
359- T :: AssetTransactor :: check_out ( & dest, & fees, & dummy_context) ;
360- T :: AssetTransactor :: withdraw_asset ( & fees, & dest, None ) . map_err ( |error| {
361- log:: error!(
362- target: LOG_TARGET ,
363- "XCM asset withdraw failed with error {:?}" , error
364- ) ;
365- TokenError :: FundsUnavailable
366- } ) ?;
367- Ok ( ( ) )
368- }
369- }
370-
371- /// API for accessing the delivery cost of a message
372- impl < T : Config > Get < BalanceOf < T > > for Pallet < T > {
373- fn get ( ) -> BalanceOf < T > {
374- // Cost here based on MaxMessagePayloadSize(the worst case)
375- Self :: calculate_delivery_cost ( T :: MaxMessageSize :: get ( ) )
376- }
377- }
378257}
0 commit comments