From 2695f46f4850351013d4bea658208a4a2e41e2cc Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 1 Dec 2025 16:44:15 -0800 Subject: [PATCH 1/3] fix stale nonce --- node/src/mev_shield/author.rs | 81 +++++++++++++++++------------------ 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/node/src/mev_shield/author.rs b/node/src/mev_shield/author.rs index 3c79b1f075..2752c8f685 100644 --- a/node/src/mev_shield/author.rs +++ b/node/src/mev_shield/author.rs @@ -2,11 +2,13 @@ use chacha20poly1305::{ KeyInit, XChaCha20Poly1305, XNonce, aead::{Aead, Payload}, }; +use frame_system_rpc_runtime_api::AccountNonceApi; use ml_kem::{EncodedSizeUser, KemCore, MlKem768}; use node_subtensor_runtime as runtime; use rand::rngs::OsRng; +use sp_api::ProvideRuntimeApi; use sp_core::blake2_256; -use sp_runtime::KeyTypeId; +use sp_runtime::{AccountId32, KeyTypeId}; use std::sync::{Arc, Mutex}; use subtensor_macros::freeze_struct; use tokio::time::sleep; @@ -139,7 +141,13 @@ pub fn spawn_author_tasks( ) -> ShieldContext where B: sp_runtime::traits::Block, - C: sc_client_api::HeaderBackend + sc_client_api::BlockchainEvents + Send + Sync + 'static, + C: sc_client_api::HeaderBackend + + sc_client_api::BlockchainEvents + + ProvideRuntimeApi + + Send + + Sync + + 'static, + C::Api: AccountNonceApi, Pool: sc_transaction_pool_api::TransactionPool + Send + Sync + 'static, B::Extrinsic: From, { @@ -162,6 +170,7 @@ where } }; + let aura_account: AccountId32 = local_aura_pub.into(); let ctx_clone = ctx.clone(); let client_clone = client.clone(); let pool_clone = pool.clone(); @@ -194,15 +203,13 @@ where ); let mut import_stream = client_clone.import_notification_stream(); - let mut local_nonce: u32 = 0; while let Some(notif) = import_stream.next().await { - // ✅ Only act on blocks that this node authored. + // Only act on blocks that this node authored. if notif.origin != BlockOrigin::Own { continue; } - // This block is the start of a slot for which we are the author. let (curr_pk_len, next_pk_len) = match ctx_clone.keys.lock() { Ok(k) => (k.current_pk.len(), k.next_pk.len()), Err(e) => { @@ -236,49 +243,39 @@ where } }; - // Submit announce_next_key once, signed with the local Aura authority that authors this block - match submit_announce_extrinsic::( + // 🔑 Fetch the current on-chain nonce for the Aura account using the best block hash. + let best_hash = client_clone.info().best_hash; + + let nonce: u32 = match client_clone + .runtime_api() + .account_nonce(best_hash, aura_account.clone()) + { + Ok(n) => n, + Err(e) => { + log::debug!( + target: "mev-shield", + "spawn_author_tasks: failed to fetch account nonce for MEV-Shield author: {e:?}", + ); + continue; + } + }; + + // Submit announce_next_key signed with the Aura key using the correct nonce. + if let Err(e) = submit_announce_extrinsic::( client_clone.clone(), pool_clone.clone(), keystore_clone.clone(), local_aura_pub, next_pk.clone(), - local_nonce, + nonce, ) .await { - Ok(()) => { - local_nonce = local_nonce.saturating_add(1); - } - Err(e) => { - let msg = format!("{e:?}"); - // If the nonce is stale, bump once and retry. - if msg.contains("InvalidTransaction::Stale") || msg.contains("Stale") { - if submit_announce_extrinsic::( - client_clone.clone(), - pool_clone.clone(), - keystore_clone.clone(), - local_aura_pub, - next_pk, - local_nonce.saturating_add(1), - ) - .await - .is_ok() - { - local_nonce = local_nonce.saturating_add(2); - } else { - log::debug!( - target: "mev-shield", - "announce_next_key retry failed after stale nonce: {e:?}" - ); - } - } else { - log::debug!( - target: "mev-shield", - "announce_next_key submit error: {e:?}" - ); - } - } + log::debug!( + target: "mev-shield", + "announce_next_key submit error (nonce={:?}): {e:?}", + nonce + ); } // Sleep the remainder of the slot (if any). @@ -332,7 +329,7 @@ where use sp_core::H256; use sp_runtime::codec::Encode; use sp_runtime::{ - AccountId32, BoundedVec, MultiSignature, + BoundedVec, MultiSignature, generic::Era, traits::{ConstU32, TransactionExtension}, }; @@ -442,7 +439,7 @@ where log::debug!( target: "mev-shield", - "announce_next_key submitted: xt=0x{xt_hash_hex}, nonce={nonce}", + "announce_next_key submitted: xt=0x{xt_hash_hex}, nonce={nonce:?}", ); Ok(()) From 25e9b19237deab6261e268bf680736cc68ec9a92 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 1 Dec 2025 17:51:43 -0800 Subject: [PATCH 2/3] bump spec --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index e3230ae540..f10d7c067b 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -237,7 +237,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 353, + spec_version: 354, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 62e558735955763e26e77388a26f2efb10ff3c8b Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 1 Dec 2025 17:58:26 -0800 Subject: [PATCH 3/3] clippy --- node/src/mev_shield/author.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/node/src/mev_shield/author.rs b/node/src/mev_shield/author.rs index 2752c8f685..2f6c86f5df 100644 --- a/node/src/mev_shield/author.rs +++ b/node/src/mev_shield/author.rs @@ -273,8 +273,7 @@ where { log::debug!( target: "mev-shield", - "announce_next_key submit error (nonce={:?}): {e:?}", - nonce + "announce_next_key submit error (nonce={nonce:?}): {e:?}" ); }