Skip to content

Commit 01b93d9

Browse files
committed
no exception, just reset return data for insufficient funds
This is what the ethereum state tests are expecting. Though there are insufficient funds, we burn only the appropriate gas here. Rather than raising an InsufficientFunds exception (`burns_gas = True` - would burn all the gas), we just reset the return data and log the error. Same scenario when a stack depth limit has been reached.
1 parent 53fa723 commit 01b93d9

File tree

3 files changed

+14
-16
lines changed

3 files changed

+14
-16
lines changed

eth/vm/logic/system.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
from eth import constants
88
from eth.exceptions import (
99
Halt,
10-
InsufficientFunds,
1110
Revert,
12-
StackDepthLimit,
1311
WriteProtection,
1412
)
1513

@@ -163,12 +161,13 @@ def __call__(self, computation: ComputationAPI) -> None:
163161

164162
if insufficient_funds or stack_too_deep:
165163
computation.stack_push_int(0)
164+
computation.return_data = b''
166165
if insufficient_funds:
167-
raise InsufficientFunds(
168-
f"Insufficient funds: {storage_address_balance} < {stack_data.endowment}"
169-
)
166+
err_msg = f"Insufficient Funds: {storage_address_balance} < {stack_data.endowment}"
170167
elif stack_too_deep:
171-
raise StackDepthLimit("Stack depth limit reached")
168+
err_msg = "Stack limit reached"
169+
self.logger.debug2("%s failure: %s", self.mnemonic, err_msg,)
170+
return
172171

173172
call_data = computation.memory_read_bytes(
174173
stack_data.memory_start, stack_data.memory_length

newsfragments/2023.bugfix.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Erase return data for exceptions with `erases_return_data` flag set to True
1+
Erase return data for exceptions with `erases_return_data` flag set to True and for CREATE / CREATE2 computations with insufficient funds

tests/core/vm/test_computation.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from eth import constants
1111
from eth.consensus import NoProofConsensus
1212
from eth.exceptions import (
13-
InsufficientFunds,
1413
InvalidInstruction,
1514
)
1615

@@ -76,20 +75,20 @@ def test_CREATE_and_CREATE2_resets_return_data_if_account_has_insufficient_funds
7675
value=0,
7776
code=code,
7877
data=code,
79-
gas=400000,
78+
gas=40000,
8079
gas_price=1,
8180
)
8281

83-
assert computation.is_error
84-
85-
if isinstance(computation.error, InvalidInstruction):
82+
if computation.is_error:
83+
assert isinstance(computation.error, InvalidInstruction)
8684
# only test CREATE case for byzantium as the CREATE2 opcode (0xf5) was not yet introduced
8785
assert vm.fork == "byzantium"
8886
assert "0xf5" in repr(computation.error).lower()
8987

9088
else:
91-
assert isinstance(computation.error, InsufficientFunds)
92-
93-
assert computation.get_gas_used() == 400000
94-
assert computation.get_gas_refund() == 0
89+
# We provide 40000 gas and a simple create uses 32000 gas. This test doesn't particularly
90+
# care (and isn't testing for) the exact gas, we just want to make sure not all the gas
91+
# is burned since if, say, a VMError were to be raised it would burn all the gas
92+
# (burns_gas = True).
93+
assert 34000 < computation.get_gas_used() < 39000
9594
assert computation.return_data == b''

0 commit comments

Comments
 (0)