@@ -273,6 +273,13 @@ def fixture_vm_class(fixture_data):
273
273
raise ValueError ("Unknown Fork Name: {0}" .format (fork_name ))
274
274
275
275
276
+ PRE_STATE_CLEARING_VMS = (
277
+ FrontierVMForTesting ,
278
+ HomesteadVMForTesting ,
279
+ TangerineWhistleVMForTesting ,
280
+ )
281
+
282
+
276
283
def test_state_fixtures (fixture , fixture_vm_class ):
277
284
header = BlockHeader (
278
285
coinbase = fixture ['env' ]['currentCoinbase' ],
@@ -320,19 +327,44 @@ def test_state_fixtures(fixture, fixture_vm_class):
320
327
r = r ,
321
328
s = s ,
322
329
)
330
+ else :
331
+ raise Exception ("Invariant: No transaction specified" )
323
332
324
333
try :
325
334
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 )
329
335
except ValidationError as err :
330
- block = vm .block
331
- transaction_error = err
332
336
logger .warning ("Got transaction error" , exc_info = True )
337
+ transaction_error = err
333
338
else :
334
339
transaction_error = False
335
340
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
+
336
368
if not transaction_error :
337
369
log_entries = computation .get_log_entries ()
338
370
actual_logs_hash = hash_log_entries (log_entries )
0 commit comments