Using eth-tester=0.11.0b2 w/ py-evm=0.10.1b1 and auto_mine_transactions=False (not sending one transaction per block as is usually the case with automine enabled).
py-evm seems to apply transaction against last block head StateAPI rather than pending state, resulting in transactions with sequential nonces from the same sender, within a single block, being invalid (think, (sender=A, nonce=1, block=1) being valid but (sender=A, nonce=2, block=1) being invalid.
Root cause seems to be the validate_frontier_transaction(StateAPI, SignedTransactionAPI) function checking for current sender_nonce against finalized state, not pending (returning the last included tx nonce and not the last applied against pending state).
Code that produced the error
def validate_frontier_transaction(
state: StateAPI, transaction: SignedTransactionAPI
) -> None:
max_gas_cost = transaction.gas * state.get_gas_price(transaction)
sender_balance = state.get_balance(transaction.sender)
if sender_balance < max_gas_cost:
raise ValidationError(
f"Sender {transaction.sender!r} cannot afford txn gas "
f"{max_gas_cost} with account balance {sender_balance}"
)
total_cost = transaction.value + max_gas_cost
if sender_balance < total_cost:
raise ValidationError(
f"Sender does not have enough balance to cover transaction value and gas "
f" (has {sender_balance}, needs {total_cost})"
)
sender_nonce = state.get_nonce(transaction.sender)
if sender_nonce != transaction.nonce:
raise ValidationError(
f"Invalid transaction nonce: Expected {sender_nonce}, "
f"but got {transaction.nonce}"
)
Full error output
File "/Users/anishagnihotri/project-name/env/lib/python3.10/site-packages/eth/vm/forks/frontier/validation.py", line 35, in validate_frontier_transaction
raise ValidationError(
eth_utils.exceptions.ValidationError: Invalid transaction nonce: Expected 1, but got 2
Fill this section in if you know how this could or should be fixed
At some point during Chain.apply_transaction(self, SignedTransactionAPI), the correct new_block is being generated with the pending tx applied, but isn't being bubbled up back to eth-tester. Could be here or upstream.
What happened?
Using
eth-tester=0.11.0b2
w/py-evm=0.10.1b1
andauto_mine_transactions=False
(not sending one transaction per block as is usually the case with automine enabled).py-evm
seems to apply transaction against last block headStateAPI
rather than pending state, resulting in transactions with sequential nonces from the same sender, within a single block, being invalid (think,(sender=A, nonce=1, block=1)
being valid but(sender=A, nonce=2, block=1)
being invalid.Root cause seems to be the
validate_frontier_transaction(StateAPI, SignedTransactionAPI)
function checking for currentsender_nonce
against finalized state, not pending (returning the last included tx nonce and not the last applied against pending state).Code that produced the error
Full error output
Fill this section in if you know how this could or should be fixed
At some point during
Chain.apply_transaction(self, SignedTransactionAPI)
, the correctnew_block
is being generated with the pending tx applied, but isn't being bubbled up back toeth-tester
. Could be here or upstream.py-evm Version
0.10.1b1
Python Version
3.10.14
Operating System
macOS 13.3.1
Output from pip-freeze
No response