Skip to content

Commit e68e7c3

Browse files
pipermerriamcburgdorf
authored andcommitted
Workaround test setup issue related to state clearing
1 parent da8fc6c commit e68e7c3

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

tests/json-fixtures/test_state.py

+37-5
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,13 @@ def fixture_vm_class(fixture_data):
273273
raise ValueError("Unknown Fork Name: {0}".format(fork_name))
274274

275275

276+
PRE_STATE_CLEARING_VMS = (
277+
FrontierVMForTesting,
278+
HomesteadVMForTesting,
279+
TangerineWhistleVMForTesting,
280+
)
281+
282+
276283
def test_state_fixtures(fixture, fixture_vm_class):
277284
header = BlockHeader(
278285
coinbase=fixture['env']['currentCoinbase'],
@@ -320,19 +327,44 @@ def test_state_fixtures(fixture, fixture_vm_class):
320327
r=r,
321328
s=s,
322329
)
330+
else:
331+
raise Exception("Invariant: No transaction specified")
323332

324333
try:
325334
header, receipt, computation = vm.apply_transaction(vm.block.header, transaction)
326-
transactions = vm.block.transactions + (transaction, )
327-
receipts = vm.block.get_receipts(chaindb) + (receipt, )
328-
block = vm.set_block_transactions(vm.block, header, transactions, receipts)
329335
except ValidationError as err:
330-
block = vm.block
331-
transaction_error = err
332336
logger.warning("Got transaction error", exc_info=True)
337+
transaction_error = err
333338
else:
334339
transaction_error = False
335340

341+
transactions = vm.block.transactions + (transaction, )
342+
receipts = vm.block.get_receipts(chaindb) + (receipt, )
343+
vm.block = vm.set_block_transactions(vm.block, header, transactions, receipts)
344+
finally:
345+
# This is necessary due to the manner in which the state tests are
346+
# generated. State tests are generated from the BlockChainTest tests
347+
# in which these transactions are included in the larger context of a
348+
# block and thus, the mechanisms which would touch/create/clear the
349+
# coinbase account based on the mining reward are present during test
350+
# generation, but not part of the execution, thus we must artificially
351+
# create the account in VMs prior to the state clearing rules,
352+
# as well as conditionally cleaning up the coinbase account when left
353+
# empty in VMs after the state clearing rules came into effect.
354+
# Related change in geth:
355+
# https://github.com/ethereum/go-ethereum/commit/32f28a9360d26a661d55915915f12fd3c70f012b#diff-f53696be8527ac422b8d4de7c8e945c1R149 # noqa: E501
356+
357+
if isinstance(vm, PRE_STATE_CLEARING_VMS):
358+
state.account_db.touch_account(vm.block.header.coinbase)
359+
state.account_db.persist()
360+
vm.block = vm.block.copy(header=vm.block.header.copy(state_root=state.state_root))
361+
elif state.account_db.account_is_empty(vm.block.header.coinbase):
362+
state.account_db.delete_account(vm.block.header.coinbase)
363+
state.account_db.persist()
364+
vm.block = vm.block.copy(header=vm.block.header.copy(state_root=state.state_root))
365+
366+
block = vm.block
367+
336368
if not transaction_error:
337369
log_entries = computation.get_log_entries()
338370
actual_logs_hash = hash_log_entries(log_entries)

0 commit comments

Comments
 (0)