Skip to content

Commit 8def8b5

Browse files
authored
Merge pull request #2270 from opentensor/mevshield-dynmaic-tx-construction
MevShield - Dynamic Transaction Construction
2 parents 8a8a5cb + 3eb55e5 commit 8def8b5

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

node/src/mev_shield/author.rs

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ pub async fn submit_announce_extrinsic<B, C, Pool>(
316316
) -> anyhow::Result<()>
317317
where
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

Comments
 (0)