feat: use next free nonce in eth_sendTransaction (#11873)

This commit is contained in:
caglarkaya
2024-10-20 01:14:52 +03:00
committed by GitHub
parent cf4a4454ec
commit 422ab17354
2 changed files with 38 additions and 3 deletions

View File

@ -272,6 +272,42 @@ pub trait LoadState: EthApiTypes {
}
}
/// Returns the next available nonce without gaps for the given address
/// Next available nonce is either the on chain nonce of the account or the highest consecutive
/// nonce in the pool + 1
fn next_available_nonce(
&self,
address: Address,
) -> impl Future<Output = Result<u64, Self::Error>> + Send
where
Self: SpawnBlocking,
{
self.spawn_blocking_io(move |this| {
// first fetch the on chain nonce of the account
let on_chain_account_nonce = this
.latest_state()?
.account_nonce(address)
.map_err(Self::Error::from_eth_err)?
.unwrap_or_default();
let mut next_nonce = on_chain_account_nonce;
// Retrieve the highest consecutive transaction for the sender from the transaction pool
if let Some(highest_tx) = this
.pool()
.get_highest_consecutive_transaction_by_sender(address, on_chain_account_nonce)
{
// Return the nonce of the highest consecutive transaction + 1
next_nonce = highest_tx.nonce().checked_add(1).ok_or_else(|| {
Self::Error::from(EthApiError::InvalidTransaction(
RpcInvalidTransactionError::NonceMaxValue,
))
})?;
}
Ok(next_nonce)
})
}
/// Returns the number of transactions sent from an address at the given block identifier.
///
/// If this is [`BlockNumberOrTag::Pending`](reth_primitives::BlockNumberOrTag) then this will

View File

@ -365,9 +365,8 @@ pub trait EthTransactions: LoadTransaction {
// set nonce if not already set before
if request.nonce.is_none() {
let nonce = self.transaction_count(from, Some(BlockId::pending())).await?;
// note: `.to()` can't panic because the nonce is constructed from a `u64`
request.nonce = Some(nonce.to());
let nonce = self.next_available_nonce(from).await?;
request.nonce = Some(nonce);
}
let chain_id = self.chain_id();