Skip to content

Commit baaa5bc

Browse files
authored
feat: Implement sender nonce refresh from RPC (#2284)
* Implement sender nonce refresh from RPC Added a method to refresh the sender's nonce from the RPC before building transactions to ensure accuracy with pending transactions. * shorter comment * remove ignore
1 parent 6e804d2 commit baaa5bc

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/pytest_plugins/execute/pre_alloc.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
from ethereum_test_vm import Bytecode, EVMCodeType, Opcodes
4141

4242
MAX_BYTECODE_SIZE = 24576
43-
4443
MAX_INITCODE_SIZE = MAX_BYTECODE_SIZE * 2
4544

4645

@@ -205,6 +204,19 @@ def __init__(
205204
self._node_id = node_id
206205
self._address_stubs = address_stubs or AddressStubs(root={})
207206

207+
# always refresh _sender nonce from RPC ("pending") before building tx
208+
def _refresh_sender_nonce(self) -> None:
209+
"""
210+
Synchronize self._sender.nonce with the node's view.
211+
Prefer 'pending' to account for in-flight transactions.
212+
"""
213+
try:
214+
rpc_nonce = self._eth_rpc.get_transaction_count(self._sender, block_number="pending")
215+
except TypeError:
216+
# If EthRPC.get_transaction_count has no 'block' kwarg
217+
rpc_nonce = self._eth_rpc.get_transaction_count(self._sender)
218+
self._sender.nonce = Number(rpc_nonce)
219+
208220
def __setitem__(self, address: Address | FixedSizeBytesConvertible, account: Account | None):
209221
"""Set account associated with an address."""
210222
raise ValueError("Tests are not allowed to set pre-alloc items in execute mode")
@@ -300,6 +312,8 @@ def deploy_contract(
300312
deploy_gas_limit = min(deploy_gas_limit * 2, 30_000_000)
301313
print(f"Deploying contract with gas limit: {deploy_gas_limit}")
302314

315+
self._refresh_sender_nonce()
316+
303317
deploy_tx = Transaction(
304318
sender=self._sender,
305319
to=None,
@@ -362,6 +376,9 @@ def fund_eoa(
362376
sum(Op.SSTORE(key, value) for key, value in storage.root.items()) + Op.STOP
363377
)
364378
)
379+
380+
self._refresh_sender_nonce()
381+
365382
set_storage_tx = Transaction(
366383
sender=self._sender,
367384
to=eoa,
@@ -386,6 +403,8 @@ def fund_eoa(
386403
self._eth_rpc.send_transaction(set_storage_tx)
387404
self._txs.append(set_storage_tx)
388405

406+
self._refresh_sender_nonce()
407+
389408
if delegation is not None:
390409
if not isinstance(delegation, Address) and delegation == "Self":
391410
delegation = eoa
@@ -426,6 +445,8 @@ def fund_eoa(
426445

427446
else:
428447
if Number(amount) > 0:
448+
self._refresh_sender_nonce()
449+
429450
fund_tx = Transaction(
430451
sender=self._sender,
431452
to=eoa,
@@ -459,6 +480,8 @@ def fund_address(self, address: Address, amount: NumberConvertible):
459480
If the address is already present in the pre-alloc the amount will be
460481
added to its existing balance.
461482
"""
483+
self._refresh_sender_nonce()
484+
462485
fund_tx = Transaction(
463486
sender=self._sender,
464487
to=address,

0 commit comments

Comments
 (0)