@@ -316,7 +316,8 @@ pub async fn submit_announce_extrinsic<B, C, Pool>(
316316) -> anyhow:: Result < ( ) >
317317where
318318 B : sp_runtime:: traits:: Block ,
319- C : sc_client_api:: HeaderBackend < B > + Send + Sync + ' static ,
319+ C : sc_client_api:: HeaderBackend < B > + sp_api:: ProvideRuntimeApi < B > + Send + Sync + ' static ,
320+ C :: Api : sp_api:: Core < B > ,
320321 Pool : sc_transaction_pool_api:: TransactionPool < Block = B > + Send + Sync + ' static ,
321322 B :: Extrinsic : From < sp_runtime:: OpaqueExtrinsic > ,
322323 B :: Hash : AsRef < [ u8 ] > ,
@@ -325,12 +326,13 @@ where
325326 use runtime:: { RuntimeCall , SignedPayload , UncheckedExtrinsic } ;
326327
327328 use sc_transaction_pool_api:: TransactionSource ;
329+ use sp_api:: Core as _;
328330 use sp_core:: H256 ;
329331 use sp_runtime:: codec:: Encode ;
330332 use sp_runtime:: {
331333 BoundedVec , MultiSignature ,
332334 generic:: Era ,
333- traits:: { ConstU32 , TransactionExtension } ,
335+ traits:: { ConstU32 , SaturatedConversion , TransactionExtension } ,
334336 } ;
335337
336338 fn to_h256 < H : AsRef < [ u8 ] > > ( h : H ) -> H256 {
@@ -365,13 +367,23 @@ where
365367
366368 // 2) Build the transaction extensions exactly like the runtime.
367369 type Extra = runtime:: TransactionExtensions ;
370+
371+ let info = client. info ( ) ;
372+ let at_hash = info. best_hash ;
373+ let at_hash_h256: H256 = to_h256 ( at_hash) ;
374+ let genesis_h256: H256 = to_h256 ( info. genesis_hash ) ;
375+
376+ const ERA_PERIOD : u64 = 12 ;
377+ let current_block: u64 = info. best_number . saturated_into ( ) ;
378+ let era = Era :: mortal ( ERA_PERIOD , current_block) ;
379+
368380 let extra: Extra =
369381 (
370382 frame_system:: CheckNonZeroSender :: < runtime:: Runtime > :: new ( ) ,
371383 frame_system:: CheckSpecVersion :: < runtime:: Runtime > :: new ( ) ,
372384 frame_system:: CheckTxVersion :: < runtime:: Runtime > :: new ( ) ,
373385 frame_system:: CheckGenesis :: < runtime:: Runtime > :: new ( ) ,
374- frame_system:: CheckEra :: < runtime:: Runtime > :: from ( Era :: Immortal ) ,
386+ frame_system:: CheckEra :: < runtime:: Runtime > :: from ( era ) ,
375387 node_subtensor_runtime:: check_nonce:: CheckNonce :: < runtime:: Runtime > :: from ( nonce) . into ( ) ,
376388 frame_system:: CheckWeight :: < runtime:: Runtime > :: new ( ) ,
377389 node_subtensor_runtime:: transaction_payment_wrapper:: ChargeTransactionPaymentWrapper :: <
@@ -389,21 +401,35 @@ where
389401 // 3) Manually construct the `Implicit` tuple that the runtime will also derive.
390402 type Implicit = <Extra as TransactionExtension < RuntimeCall > >:: Implicit ;
391403
392- let info = client. info ( ) ;
393- let genesis_h256: H256 = to_h256 ( info. genesis_hash ) ;
404+ // Try to get the *current* runtime version from on-chain WASM; if that fails,
405+ // fall back to the compiled runtime::VERSION.
406+ let ( spec_version, tx_version) = match client. runtime_api ( ) . version ( at_hash) {
407+ Ok ( v) => ( v. spec_version , v. transaction_version ) ,
408+ Err ( e) => {
409+ log:: debug!(
410+ target: "mev-shield" ,
411+ "runtime_api::version failed at_hash={at_hash:?}: {e:?}; \
412+ falling back to compiled runtime::VERSION",
413+ ) ;
414+ (
415+ runtime:: VERSION . spec_version ,
416+ runtime:: VERSION . transaction_version ,
417+ )
418+ }
419+ } ;
394420
395421 let implicit: Implicit = (
396- ( ) , // CheckNonZeroSender
397- runtime :: VERSION . spec_version , // CheckSpecVersion::Implicit = u32
398- runtime :: VERSION . transaction_version , // CheckTxVersion::Implicit = u32
399- genesis_h256, // CheckGenesis::Implicit = Hash
400- genesis_h256 , // CheckEra::Implicit (Immortal => genesis hash)
401- ( ) , // CheckNonce::Implicit = ()
402- ( ) , // CheckWeight::Implicit = ()
403- ( ) , // ChargeTransactionPaymentWrapper::Implicit = ()
404- ( ) , // SubtensorTransactionExtension::Implicit = ()
405- ( ) , // DrandPriority::Implicit = ()
406- None , // CheckMetadataHash::Implicit = Option<[u8; 32]>
422+ ( ) , // CheckNonZeroSender
423+ spec_version, // dynamic or fallback spec_version
424+ tx_version , // dynamic or fallback transaction_version
425+ genesis_h256, // CheckGenesis::Implicit = Hash
426+ at_hash_h256 , // CheckEra::Implicit = hash of the block the tx is created at
427+ ( ) , // CheckNonce::Implicit = ()
428+ ( ) , // CheckWeight::Implicit = ()
429+ ( ) , // ChargeTransactionPaymentWrapper::Implicit = ()
430+ ( ) , // SubtensorTransactionExtension::Implicit = ()
431+ ( ) , // DrandPriority::Implicit = ()
432+ None , // CheckMetadataHash::Implicit = Option<[u8; 32]>
407433 ) ;
408434
409435 // 4) Build the exact signable payload from call + extra + implicit.
@@ -433,12 +459,13 @@ where
433459 let opaque: sp_runtime:: OpaqueExtrinsic = uxt. into ( ) ;
434460 let xt: <B as sp_runtime:: traits:: Block >:: Extrinsic = opaque. into ( ) ;
435461
436- pool. submit_one ( info . best_hash , TransactionSource :: Local , xt)
462+ pool. submit_one ( at_hash , TransactionSource :: Local , xt)
437463 . await ?;
438464
439465 log:: debug!(
440466 target: "mev-shield" ,
441- "announce_next_key submitted: xt=0x{xt_hash_hex}, nonce={nonce:?}" ,
467+ "announce_next_key submitted: xt=0x{xt_hash_hex}, nonce={nonce:?}, \
468+ spec_version={spec_version}, tx_version={tx_version}, era={era:?}",
442469 ) ;
443470
444471 Ok ( ( ) )
0 commit comments