Skip to content

Commit 3fe6514

Browse files
authored
add error messages to traces (#846)
* add error messages to traces * include review comments * combine has_erred and error in Evm
1 parent 0fdcaa0 commit 3fe6514

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+557
-436
lines changed

src/ethereum/arrow_glacier/fork.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ def check_transaction(
442442

443443
def make_receipt(
444444
tx: Transaction,
445-
has_erred: bool,
445+
error: Optional[Exception],
446446
cumulative_gas_used: Uint,
447447
logs: Tuple[Log, ...],
448448
) -> Union[Bytes, Receipt]:
@@ -453,8 +453,8 @@ def make_receipt(
453453
----------
454454
tx :
455455
The executed transaction.
456-
has_erred :
457-
Whether the top level frame of the transaction exited with an error.
456+
error :
457+
Error in the top level frame of the transaction, if any.
458458
cumulative_gas_used :
459459
The total gas used so far in the block after the transaction was
460460
executed.
@@ -467,7 +467,7 @@ def make_receipt(
467467
The receipt for the transaction.
468468
"""
469469
receipt = Receipt(
470-
succeeded=not has_erred,
470+
succeeded=error is None,
471471
cumulative_gas_used=cumulative_gas_used,
472472
bloom=logs_bloom(logs),
473473
logs=logs,
@@ -579,11 +579,11 @@ def apply_body(
579579
traces=[],
580580
)
581581

582-
gas_used, logs, has_erred = process_transaction(env, tx)
582+
gas_used, logs, error = process_transaction(env, tx)
583583
gas_available -= gas_used
584584

585585
receipt = make_receipt(
586-
tx, has_erred, (block_gas_limit - gas_available), logs
586+
tx, error, (block_gas_limit - gas_available), logs
587587
)
588588

589589
trie_set(
@@ -732,7 +732,7 @@ def pay_rewards(
732732

733733
def process_transaction(
734734
env: vm.Environment, tx: Transaction
735-
) -> Tuple[Uint, Tuple[Log, ...], bool]:
735+
) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
736736
"""
737737
Execute a transaction against the provided environment.
738738
@@ -838,7 +838,7 @@ def process_transaction(
838838
if account_exists_and_is_empty(env.state, address):
839839
destroy_account(env.state, address)
840840

841-
return total_gas_used, output.logs, output.has_erred
841+
return total_gas_used, output.logs, output.error
842842

843843

844844
def validate_transaction(tx: Transaction) -> bool:

src/ethereum/arrow_glacier/vm/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ class Evm:
8787
output: Bytes
8888
accounts_to_delete: Set[Address]
8989
touched_accounts: Set[Address]
90-
has_erred: bool
9190
return_data: Bytes
9291
error: Optional[Exception]
9392
accessed_addresses: Set[Address]

src/ethereum/arrow_glacier/vm/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,11 @@ class InvalidContractPrefix(ExceptionalHalt):
118118
"""
119119

120120
pass
121+
122+
123+
class AddressCollision(ExceptionalHalt):
124+
"""
125+
Raised when the new contract address has a collision.
126+
"""
127+
128+
pass

src/ethereum/arrow_glacier/vm/instructions/system.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def generic_create(
118118
)
119119
child_evm = process_create_message(child_message, evm.env)
120120

121-
if child_evm.has_erred:
121+
if child_evm.error:
122122
incorporate_child_on_error(evm, child_evm)
123123
evm.return_data = child_evm.output
124124
push(evm.stack, U256(0))
@@ -288,7 +288,7 @@ def generic_call(
288288
)
289289
child_evm = process_message(child_message, evm.env)
290290

291-
if child_evm.has_erred:
291+
if child_evm.error:
292292
incorporate_child_on_error(evm, child_evm)
293293
evm.return_data = child_evm.output
294294
push(evm.stack, U256(0))

src/ethereum/arrow_glacier/vm/interpreter.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
A straightforward interpreter that executes EVM code.
1313
"""
1414
from dataclasses import dataclass
15-
from typing import Iterable, Set, Tuple
15+
from typing import Iterable, Optional, Set, Tuple
1616

1717
from ethereum.base_types import U256, Bytes0, Uint
1818
from ethereum.trace import (
@@ -46,6 +46,7 @@
4646
from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS
4747
from . import Environment, Evm
4848
from .exceptions import (
49+
AddressCollision,
4950
ExceptionalHalt,
5051
InvalidContractPrefix,
5152
InvalidOpcode,
@@ -72,15 +73,15 @@ class MessageCallOutput:
7273
3. `logs`: list of `Log` generated during execution.
7374
4. `accounts_to_delete`: Contracts which have self-destructed.
7475
5. `touched_accounts`: Accounts that have been touched.
75-
6. `has_erred`: True if execution has caused an error.
76+
6. `error`: The error from the execution if any.
7677
"""
7778

7879
gas_left: Uint
7980
refund_counter: U256
8081
logs: Tuple[Log, ...]
8182
accounts_to_delete: Set[Address]
8283
touched_accounts: Iterable[Address]
83-
has_erred: bool
84+
error: Optional[Exception]
8485

8586

8687
def process_message_call(
@@ -109,7 +110,7 @@ def process_message_call(
109110
)
110111
if is_collision:
111112
return MessageCallOutput(
112-
Uint(0), U256(0), tuple(), set(), set(), True
113+
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
113114
)
114115
else:
115116
evm = process_create_message(message, env)
@@ -118,7 +119,7 @@ def process_message_call(
118119
if account_exists_and_is_empty(env.state, Address(message.target)):
119120
evm.touched_accounts.add(Address(message.target))
120121

121-
if evm.has_erred:
122+
if evm.error:
122123
logs: Tuple[Log, ...] = ()
123124
accounts_to_delete = set()
124125
touched_accounts = set()
@@ -129,9 +130,7 @@ def process_message_call(
129130
touched_accounts = evm.touched_accounts
130131
refund_counter = U256(evm.refund_counter)
131132

132-
tx_end = TransactionEnd(
133-
message.gas - evm.gas_left, evm.output, evm.has_erred
134-
)
133+
tx_end = TransactionEnd(message.gas - evm.gas_left, evm.output, evm.error)
135134
evm_trace(evm, tx_end)
136135

137136
return MessageCallOutput(
@@ -140,7 +139,7 @@ def process_message_call(
140139
logs=logs,
141140
accounts_to_delete=accounts_to_delete,
142141
touched_accounts=touched_accounts,
143-
has_erred=evm.has_erred,
142+
error=evm.error,
144143
)
145144

146145

@@ -179,19 +178,19 @@ def process_create_message(message: Message, env: Environment) -> Evm:
179178

180179
increment_nonce(env.state, message.current_target)
181180
evm = process_message(message, env)
182-
if not evm.has_erred:
181+
if not evm.error:
183182
contract_code = evm.output
184183
contract_code_gas = len(contract_code) * GAS_CODE_DEPOSIT
185184
try:
186185
if len(contract_code) > 0:
187186
ensure(contract_code[0] != 0xEF, InvalidContractPrefix)
188187
charge_gas(evm, contract_code_gas)
189188
ensure(len(contract_code) <= MAX_CODE_SIZE, OutOfGasError)
190-
except ExceptionalHalt:
189+
except ExceptionalHalt as error:
191190
rollback_transaction(env.state)
192191
evm.gas_left = Uint(0)
193192
evm.output = b""
194-
evm.has_erred = True
193+
evm.error = error
195194
else:
196195
set_code(env.state, message.current_target, contract_code)
197196
commit_transaction(env.state)
@@ -230,7 +229,7 @@ def process_message(message: Message, env: Environment) -> Evm:
230229
)
231230

232231
evm = execute_code(message, env)
233-
if evm.has_erred:
232+
if evm.error:
234233
# revert state to the last saved checkpoint
235234
# since the message call resulted in an error
236235
rollback_transaction(env.state)
@@ -273,7 +272,6 @@ def execute_code(message: Message, env: Environment) -> Evm:
273272
output=b"",
274273
accounts_to_delete=set(),
275274
touched_accounts=set(),
276-
has_erred=False,
277275
return_data=b"",
278276
error=None,
279277
accessed_addresses=message.accessed_addresses,
@@ -299,13 +297,12 @@ def execute_code(message: Message, env: Environment) -> Evm:
299297

300298
evm_trace(evm, EvmStop(Ops.STOP))
301299

302-
except ExceptionalHalt:
303-
evm_trace(evm, OpException())
300+
except ExceptionalHalt as error:
301+
evm_trace(evm, OpException(error))
304302
evm.gas_left = Uint(0)
305303
evm.output = b""
306-
evm.has_erred = True
307-
except Revert as e:
308-
evm_trace(evm, OpException())
309-
evm.error = e
310-
evm.has_erred = True
304+
evm.error = error
305+
except Revert as error:
306+
evm_trace(evm, OpException(error))
307+
evm.error = error
311308
return evm

src/ethereum/berlin/fork.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ def check_transaction(
347347

348348
def make_receipt(
349349
tx: Transaction,
350-
has_erred: bool,
350+
error: Optional[Exception],
351351
cumulative_gas_used: Uint,
352352
logs: Tuple[Log, ...],
353353
) -> Union[Bytes, Receipt]:
@@ -358,8 +358,8 @@ def make_receipt(
358358
----------
359359
tx :
360360
The executed transaction.
361-
has_erred :
362-
Whether the top level frame of the transaction exited with an error.
361+
error :
362+
Error in the top level frame of the transaction, if any.
363363
cumulative_gas_used :
364364
The total gas used so far in the block after the transaction was
365365
executed.
@@ -372,7 +372,7 @@ def make_receipt(
372372
The receipt for the transaction.
373373
"""
374374
receipt = Receipt(
375-
succeeded=not has_erred,
375+
succeeded=error is None,
376376
cumulative_gas_used=cumulative_gas_used,
377377
bloom=logs_bloom(logs),
378378
logs=logs,
@@ -476,11 +476,11 @@ def apply_body(
476476
traces=[],
477477
)
478478

479-
gas_used, logs, has_erred = process_transaction(env, tx)
479+
gas_used, logs, error = process_transaction(env, tx)
480480
gas_available -= gas_used
481481

482482
receipt = make_receipt(
483-
tx, has_erred, (block_gas_limit - gas_available), logs
483+
tx, error, (block_gas_limit - gas_available), logs
484484
)
485485

486486
trie_set(
@@ -629,7 +629,7 @@ def pay_rewards(
629629

630630
def process_transaction(
631631
env: vm.Environment, tx: Transaction
632-
) -> Tuple[Uint, Tuple[Log, ...], bool]:
632+
) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
633633
"""
634634
Execute a transaction against the provided environment.
635635
@@ -721,7 +721,7 @@ def process_transaction(
721721
if account_exists_and_is_empty(env.state, address):
722722
destroy_account(env.state, address)
723723

724-
return total_gas_used, output.logs, output.has_erred
724+
return total_gas_used, output.logs, output.error
725725

726726

727727
def validate_transaction(tx: Transaction) -> bool:

src/ethereum/berlin/vm/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ class Evm:
8686
output: Bytes
8787
accounts_to_delete: Set[Address]
8888
touched_accounts: Set[Address]
89-
has_erred: bool
9089
return_data: Bytes
9190
error: Optional[Exception]
9291
accessed_addresses: Set[Address]

src/ethereum/berlin/vm/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,11 @@ class InvalidParameter(ExceptionalHalt):
110110
"""
111111

112112
pass
113+
114+
115+
class AddressCollision(ExceptionalHalt):
116+
"""
117+
Raised when the new contract address has a collision.
118+
"""
119+
120+
pass

src/ethereum/berlin/vm/instructions/system.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def generic_create(
119119
)
120120
child_evm = process_create_message(child_message, evm.env)
121121

122-
if child_evm.has_erred:
122+
if child_evm.error:
123123
incorporate_child_on_error(evm, child_evm)
124124
evm.return_data = child_evm.output
125125
push(evm.stack, U256(0))
@@ -289,7 +289,7 @@ def generic_call(
289289
)
290290
child_evm = process_message(child_message, evm.env)
291291

292-
if child_evm.has_erred:
292+
if child_evm.error:
293293
incorporate_child_on_error(evm, child_evm)
294294
evm.return_data = child_evm.output
295295
push(evm.stack, U256(0))

0 commit comments

Comments
 (0)