@@ -138,6 +138,15 @@ struct ClientData {
138138 client : Arc < RpcClient > ,
139139}
140140
141+ /// Already encoded value.
142+ struct PreEncoded ( Vec < u8 > ) ;
143+
144+ impl Encode for PreEncoded {
145+ fn encode ( & self ) -> Vec < u8 > {
146+ self . 0 . clone ( )
147+ }
148+ }
149+
141150#[ async_trait]
142151impl < C : Chain > relay_utils:: relay_loop:: Client for Client < C > {
143152 type Error = Error ;
@@ -438,6 +447,16 @@ impl<C: Chain> Client<C> {
438447 ///
439448 /// Note: The given transaction needs to be SCALE encoded beforehand.
440449 pub async fn submit_unsigned_extrinsic ( & self , transaction : Bytes ) -> Result < C :: Hash > {
450+ // one last check that the transaction is valid. Most of checks happen in the relay loop and
451+ // it is the "final" check before submission.
452+ let best_header_hash = self . best_header ( ) . await ?. hash ( ) ;
453+ self . validate_transaction ( best_header_hash, PreEncoded ( transaction. 0 . clone ( ) ) )
454+ . await
455+ . map_err ( |e| {
456+ log:: error!( target: "bridge" , "Pre-submit {} transaction validation failed: {:?}" , C :: NAME , e) ;
457+ e
458+ } ) ??;
459+
441460 self . jsonrpsee_execute ( move |client| async move {
442461 let tx_hash = SubstrateAuthorClient :: < C > :: submit_extrinsic ( & * client, transaction)
443462 . await
@@ -494,9 +513,19 @@ impl<C: Chain> Client<C> {
494513 // will be dropped from the pool.
495514 let best_header_id = best_header. parent_id ( ) . unwrap_or_else ( || best_header. id ( ) ) ;
496515
516+ let extrinsic = prepare_extrinsic ( best_header_id, transaction_nonce) ?;
517+ let signed_extrinsic = C :: sign_transaction ( signing_data, extrinsic) ?. encode ( ) ;
518+
519+ // one last check that the transaction is valid. Most of checks happen in the relay loop and
520+ // it is the "final" check before submission.
521+ self . validate_transaction ( best_header_id. 1 , PreEncoded ( signed_extrinsic. clone ( ) ) )
522+ . await
523+ . map_err ( |e| {
524+ log:: error!( target: "bridge" , "Pre-submit {} transaction validation failed: {:?}" , C :: NAME , e) ;
525+ e
526+ } ) ??;
527+
497528 self . jsonrpsee_execute ( move |client| async move {
498- let extrinsic = prepare_extrinsic ( best_header_id, transaction_nonce) ?;
499- let signed_extrinsic = C :: sign_transaction ( signing_data, extrinsic) ?. encode ( ) ;
500529 let tx_hash =
501530 SubstrateAuthorClient :: < C > :: submit_extrinsic ( & * client, Bytes ( signed_extrinsic) )
502531 . await
@@ -529,16 +558,27 @@ impl<C: Chain> Client<C> {
529558 let transaction_nonce = self . next_account_index ( signer. public ( ) . into ( ) ) . await ?;
530559 let best_header = self . best_header ( ) . await ?;
531560 let best_header_id = best_header. id ( ) ;
561+
562+ let extrinsic = prepare_extrinsic ( best_header_id, transaction_nonce) ?;
563+ let stall_timeout = transaction_stall_timeout (
564+ extrinsic. era . mortality_period ( ) ,
565+ C :: AVERAGE_BLOCK_INTERVAL ,
566+ STALL_TIMEOUT ,
567+ ) ;
568+ let signed_extrinsic = C :: sign_transaction ( signing_data, extrinsic) ?. encode ( ) ;
569+
570+ // one last check that the transaction is valid. Most of checks happen in the relay loop and
571+ // it is the "final" check before submission.
572+ self . validate_transaction ( best_header_id. 1 , PreEncoded ( signed_extrinsic. clone ( ) ) )
573+ . await
574+ . map_err ( |e| {
575+ log:: error!( target: "bridge" , "Pre-submit {} transaction validation failed: {:?}" , C :: NAME , e) ;
576+ e
577+ } ) ??;
578+
532579 let ( sender, receiver) = futures:: channel:: mpsc:: channel ( MAX_SUBSCRIPTION_CAPACITY ) ;
533580 let ( tracker, subscription) = self
534581 . jsonrpsee_execute ( move |client| async move {
535- let extrinsic = prepare_extrinsic ( best_header_id, transaction_nonce) ?;
536- let stall_timeout = transaction_stall_timeout (
537- extrinsic. era . mortality_period ( ) ,
538- C :: AVERAGE_BLOCK_INTERVAL ,
539- STALL_TIMEOUT ,
540- ) ;
541- let signed_extrinsic = C :: sign_transaction ( signing_data, extrinsic) ?. encode ( ) ;
542582 let tx_hash = C :: Hasher :: hash ( & signed_extrinsic) ;
543583 let subscription = SubstrateAuthorClient :: < C > :: submit_and_watch_extrinsic (
544584 & * client,
0 commit comments