Skip to content

Commit

Permalink
feat: fix + retry transaction for geth --dev when gas limit exceeds…
Browse files Browse the repository at this point in the history
… block gas limit (#2402)
  • Loading branch information
antazoey authored Dec 9, 2024
1 parent abbe95e commit 02bec21
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/ape_node/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from ape.api.config import PluginConfig
from ape.api.providers import SubprocessProvider, TestProviderAPI
from ape.exceptions import VirtualMachineError
from ape.logging import LogLevel, logger
from ape.utils._web3_compat import ExtraDataToPOAMiddleware
from ape.utils.misc import ZERO_ADDRESS, log_instead_of_fail, raises_not_implemented
Expand All @@ -40,6 +41,7 @@
from geth.types import GenesisDataTypedDict

from ape.api.accounts import TestAccountAPI
from ape.api.transactions import ReceiptAPI, TransactionAPI
from ape.types.vm import SnapshotID


Expand Down Expand Up @@ -485,6 +487,24 @@ def disconnect(self):

super().disconnect()

def send_transaction(self, txn: "TransactionAPI") -> "ReceiptAPI":
try:
return super().send_transaction(txn)
except VirtualMachineError as err:
if (
txn.sender in self.account_manager.test_accounts
and "exceeds block gas limit" in str(err)
):
# Changed, possibly due to other transactions (x-dist?).
# Retry using block gas limit.
txn.gas_limit = self.chain_manager.blocks.head.gas_limit
account = self.account_manager.test_accounts[txn.sender]
signed_transaction = account.sign_transaction(txn)
logger.debug("Gas-limit exceeds block gas limit. Retrying using block gas limit.")
return super().send_transaction(signed_transaction)

raise # Whatever error it already is (Ape-ified from ape-ethereum.provider base).

def snapshot(self) -> "SnapshotID":
return self._get_latest_block().number or 0

Expand Down
16 changes: 16 additions & 0 deletions tests/functional/geth/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,22 @@ def test_send_transaction_when_no_error_and_receipt_fails(
geth_provider._web3 = start_web3


@geth_process_test
def test_send_transaction_exceed_block_gas_limit(chain, geth_provider, geth_contract, geth_account):
"""
Shows that the local geth node will retry the transaction
with a new gas if this happens, automatically.
"""
transaction = geth_contract.setNumber.as_transaction(23333322101, sender=geth_account)
prepared = geth_account.prepare_transaction(transaction)
prepared.gas_limit += 100000
signed = geth_account.sign_transaction(prepared)
expected_gas_limit = chain.blocks.head.gas_limit
geth_provider.send_transaction(signed)
tx_sent = geth_account.history[-1]
assert tx_sent.gas_limit == expected_gas_limit


@geth_process_test
def test_send_call(geth_provider, ethereum, tx_for_call):
actual = geth_provider.send_call(tx_for_call)
Expand Down

0 comments on commit 02bec21

Please sign in to comment.