From 1635829a0d06056afd1b0cc7c46752c1408893a7 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 11:41:18 -0600 Subject: [PATCH 1/9] Fix invalid transactions behavior --- src/ethereum_test/blockchain_test.py | 14 +- src/ethereum_test/state_test.py | 9 +- src/ethereum_test/types.py | 8 + tests/ethereum_test/test_filler.py | 54 ++++-- .../blockchain_london_invalid_filled.json | 169 ++++++++++++++++++ ...on => blockchain_london_valid_filled.json} | 4 + 6 files changed, 234 insertions(+), 24 deletions(-) create mode 100644 tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json rename tests/ethereum_test/test_fixtures/{blockchain_london_filled.json => blockchain_london_valid_filled.json} (99%) diff --git a/src/ethereum_test/blockchain_test.py b/src/ethereum_test/blockchain_test.py index 8d33d78a778..073da636e29 100644 --- a/src/ethereum_test/blockchain_test.py +++ b/src/ethereum_test/blockchain_test.py @@ -145,10 +145,14 @@ def make_block( txs_rlp = txs_rlp_file.read().decode().strip('"') rejected_txs = verify_transactions(block.txs, result) - if len(rejected_txs) > 0: - # TODO: This block is invalid because it contains intrinsically - # invalid transactions - pass + if len(rejected_txs) > 0 and block.exception is None: + raise Exception( + "one or more transactions in `BlockchainTest` are " + + "intrinsically invalid, but the block was not expected " + + "to be invalid. Please verify whether the transaction " + + "was indeed expected to fail and add the proper " + + "`block.exception`" + ) header = FixtureHeader.from_dict( result @@ -186,6 +190,7 @@ def make_block( FixtureBlock( rlp=rlp, block_header=header, + block_number=header.number, ), env.apply_new_parent(header), next_alloc, @@ -196,6 +201,7 @@ def make_block( FixtureBlock( rlp=rlp, expected_exception=block.exception, + block_number=header.number, ), previous_env, previous_alloc, diff --git a/src/ethereum_test/state_test.py b/src/ethereum_test/state_test.py index 476ed88d7be..65fc2a8d6ad 100644 --- a/src/ethereum_test/state_test.py +++ b/src/ethereum_test/state_test.py @@ -124,9 +124,12 @@ def make_blocks( rejected_txs = verify_transactions(self.txs, result) if len(rejected_txs) > 0: - # TODO: This block is invalid because it contains intrinsically - # invalid transactions - pass + raise Exception( + "one or more transactions in `StateTest` are " + + "intrinsically invalid, which are not allowed. " + + "Use `BlockchainTest` to verify rejection of blocks " + + "that include invalid transactions." + ) verify_post_alloc(self.post, alloc) diff --git a/src/ethereum_test/types.py b/src/ethereum_test/types.py index 99fc0086fbe..966d80a4144 100644 --- a/src/ethereum_test/types.py +++ b/src/ethereum_test/types.py @@ -572,6 +572,8 @@ class FixtureBlock: rlp: str block_header: Optional[FixtureHeader] = None expected_exception: Optional[str] = None + block_number: Optional[int] = None + chain_name: Optional[str] = None @dataclass(kw_only=True) @@ -696,6 +698,12 @@ def default(self, obj): b["blockHeader"] = json.loads( json.dumps(obj.block_header, cls=JSONEncoder) ) + if obj.expected_exception is not None: + b["expectException"] = obj.expected_exception + if obj.block_number is not None: + b["blocknumber"] = str(obj.block_number) + if obj.chain_name is not None: + b["chainname"] = obj.chain_name return b elif isinstance(obj, Fixture): f = { diff --git a/tests/ethereum_test/test_filler.py b/tests/ethereum_test/test_filler.py index a794c55925f..0d2f03df33e 100644 --- a/tests/ethereum_test/test_filler.py +++ b/tests/ethereum_test/test_filler.py @@ -3,7 +3,6 @@ """ import json -import tempfile from typing import Generator, List from ethereum_test import ( @@ -376,14 +375,11 @@ def generator(_) -> Generator[BlockchainTest, None, None]: fixture = fill_test(generator, ["London"], "NoProof") with open( - "tests/ethereum_test/test_fixtures/blockchain_london_filled.json" + "tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json" ) as f: expected = json.load(f) fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) - fixture_tmp_output_file = tempfile.NamedTemporaryFile() - with open(fixture_tmp_output_file.name, "w") as f: - json.dump(fixture, f, cls=JSONEncoder) assert fixture_json == expected @@ -520,6 +516,20 @@ def test_fill_london_blockchain_test_invalid_txs(): to="0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD", error="TR_TipGtFeeCap", ), + ], + exception="invalid transaction", + ), + Block( + coinbase="0xba5e000000000000000000000000000000000000", + txs=[ + Transaction( + data="0x0301", + nonce=4, + gas_limit=1000000, + max_priority_fee_per_gas=1000, + max_fee_per_gas=1000, + to="0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + ), Transaction( data="0x0303", nonce=5, @@ -558,6 +568,20 @@ def test_fill_london_blockchain_test_invalid_txs(): to="0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD", error="TR_TipGtFeeCap", ), + ], + exception="invalid transaction", + ), + Block( + coinbase="0xba5e000000000000000000000000000000000000", + txs=[ + Transaction( + data="0x0401", + nonce=7, + gas_limit=1000000, + max_priority_fee_per_gas=1000, + max_fee_per_gas=1000, + to="0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + ), Transaction( data="0x0403", nonce=8, @@ -665,17 +689,13 @@ def generator(_) -> Generator[BlockchainTest, None, None]: genesis_environment=genesis_environment, ) - # TODO: Test needs to be fixed according to new behavior where invalid txs - # produce block rejection. - fill_test(generator, ["London"], "NoProof") + fixture = fill_test(generator, ["London"], "NoProof") - # with open( - # "tests/ethereum_test/test_fixtures/blockchain_london_filled.json" - # ) as f: - # expected = json.load(f) + with open( + "tests/ethereum_test/test_fixtures/" + + "blockchain_london_invalid_filled.json" + ) as f: + expected = json.load(f) - # fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) - # fixture_tmp_output_file = tempfile.NamedTemporaryFile() - # with open(fixture_tmp_output_file.name, "w") as f: - # json.dump(fixture, f, cls=JSONEncoder) - # assert fixture_json == expected + fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) + assert fixture_json == expected diff --git a/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json b/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json new file mode 100644 index 00000000000..50813fa7b68 --- /dev/null +++ b/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json @@ -0,0 +1,169 @@ +{ + "london": { + "_info": {}, + "blocks": [ + { + "blocknumber": "1", + "rlp": "0xf9026ef901fea06241b4534da26b654ec5bb30d29b1d5202454af544b05828433354da7471957ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a03eb2e72e8ed9a59768bb9ac05915b781a764f2582edcf111053fe6531e466613a0586f963eea0fb4726f0f91f895f2aa5d67bffb5207a529b40d781244a0c7017ba029b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000188016345785d8a0000830155340c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082036bf86ab86802f8650180018203e8830f424094cccccccccccccccccccccccccccccccccccccccc8001c080a03351b6993208fc7b03fd770c8c06440cfb0d75b29aafee0a4c64c8ba20a80e58a067817fdb3058e75c5d26e51a33d1e338346bc7d406e115447a4bb5f7ab01625bc0", + "blockHeader": { + "parentHash": "0x6241b4534da26b654ec5bb30d29b1d5202454af544b05828433354da7471957c", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0xba5e000000000000000000000000000000000000", + "stateRoot": "0x3eb2e72e8ed9a59768bb9ac05915b781a764f2582edcf111053fe6531e466613", + "transactionsTrie": "0x586f963eea0fb4726f0f91f895f2aa5d67bffb5207a529b40d781244a0c7017b", + "receiptTrie": "0x29b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x20000", + "number": "0x1", + "gasLimit": "0x16345785d8a0000", + "gasUsed": "0x15534", + "timestamp": "0xc", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x36b", + "hash": "0x12bba91a7e1f277f1549e832e06820f8849308f70f8659acf846bdc15f5d586e" + } + }, + { + "blocknumber": "2", + "rlp": "0xf90349f901fea012bba91a7e1f277f1549e832e06820f8849308f70f8659acf846bdc15f5d586ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0d9d9cc8ae73834ba9dc75fe8c68d36e980c82fcaf887dc220a05f152a327ae55a05521d9ad5adef72f021e4270a1f6851ca772dd56acaf4ff03362151bfb715298a0e225d44649351c3dccc61c1d904451d6f0f5a407c072099fe1085cfad88447d6b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000288016345785d8a000083053c421880a000000000000000000000000000000000000000000000000000000000000000008800000000000000008202fef90144b86a02f86701010a8203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820201c080a06ea285a870a051df2b8c80c462b7d3517f984815e09c4748efc8548a40434050a052f635268c1b9e1538ac76b37cb69c7b897595744d6de2dda9507b6624d352d0b86a02f8670102648203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820202c080a0218549e818b36b3823c3f11a65ab5c1e16f6886469c385503cc2f1af1f53825da058b082850f55fd61290a99add11b7af6356ac8d55fbe4d513f06bf648824a64db86a02f8670103648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820203c001a0339e9ed3f6342f2644e4cd33a775b7e62a8208a137dcf2e354c7473caa77782aa074004c85b651c8ca9828aac28414997f3eff46edbba2bb606a545d95fd4c9b3ac0", + "blockHeader": { + "parentHash": "0x12bba91a7e1f277f1549e832e06820f8849308f70f8659acf846bdc15f5d586e", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0xba5e000000000000000000000000000000000000", + "stateRoot": "0xd9d9cc8ae73834ba9dc75fe8c68d36e980c82fcaf887dc220a05f152a327ae55", + "transactionsTrie": "0x5521d9ad5adef72f021e4270a1f6851ca772dd56acaf4ff03362151bfb715298", + "receiptTrie": "0xe225d44649351c3dccc61c1d904451d6f0f5a407c072099fe1085cfad88447d6", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x20000", + "number": "0x2", + "gasLimit": "0x16345785d8a0000", + "gasUsed": "0x53c42", + "timestamp": "0x18", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x2fe", + "hash": "0x0e043cb2eb0339900f6199c0ab517e5be3a81d898fa58078ed8b866ddc60b010" + } + }, + { + "blocknumber": "3", + "rlp": "0xf902e1f901fea00e043cb2eb0339900f6199c0ab517e5be3a81d898fa58078ed8b866ddc60b010a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a069f3a735c7a7e1ea24a03a7107eba6a880d2d0251aaf24eaa7f109ece7969bf9a0ab28cd18f912c2177d3f787591ccc9ba7742c877cdeabe0098e7263ead8893c1a0976beb67b634171d419ef326220dfdda98074e3495940240a105e17643f0a4efb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000388016345785d8a0000830155442480a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082029ff8ddb86c02f86901048203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820301c001a0720e2870881f8b0e285b7ec02c169f1165847bcb5f36ea5f33f3db6079854f63a04448266b715d7d99acd1e31dcab50d7119faa620d44c69b3f64f97d636634169b86d02f86a0105830186a08203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820302c080a06c7fb2be7e001a210d72480522b9ebecade52d721360ce5242e34a6c05a02715a01220e3cb7418cd6294443b38d05f5ed9f2967b182d25c784e11e7863454b8f9bc0", + "expectException": "invalid transaction" + }, + { + "blocknumber": "3", + "rlp": "0xf9034ff901fea00e043cb2eb0339900f6199c0ab517e5be3a81d898fa58078ed8b866ddc60b010a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0bb08d7ca9c904f3d01b78041a9d70f69e83b0a6ec7af471cbd00933a47fdacaea027f7b224df1d270bfa03ba564cd4962071b89f91c965dbbfacff55e7ec66c652a0f42d43454db7c51eadf004bd9e43522c4894f02c602b709cd45e67597c622f2eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000388016345785d8a000083053c422480a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082029ff9014ab86c02f86901048203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820301c001a0720e2870881f8b0e285b7ec02c169f1165847bcb5f36ea5f33f3db6079854f63a04448266b715d7d99acd1e31dcab50d7119faa620d44c69b3f64f97d636634169b86a02f8670105648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820303c080a09c8531a41f9281633470c5e12b6c72c8930409a6433f26bf7b394a703d18512ea07a0c6151fde75f10a7e4efdd17a21f1f25206559bd4b8cf7880e5bc30e1cfe33b86e02f86b0106830186a0830186a0830f424094cccccccccccccccccccccccccccccccccccccccd80820304c001a0c8b85e158b532a0e3b3b5848fad0f4d5c6807805a4ce65e8591de13a62f3ac6aa03e923eb1be030c3ca69623f31ad3a357368b1ccb7ee48ac8deec5cb5dc49cb0cc0", + "blockHeader": { + "parentHash": "0x0e043cb2eb0339900f6199c0ab517e5be3a81d898fa58078ed8b866ddc60b010", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0xba5e000000000000000000000000000000000000", + "stateRoot": "0xbb08d7ca9c904f3d01b78041a9d70f69e83b0a6ec7af471cbd00933a47fdacae", + "transactionsTrie": "0x27f7b224df1d270bfa03ba564cd4962071b89f91c965dbbfacff55e7ec66c652", + "receiptTrie": "0xf42d43454db7c51eadf004bd9e43522c4894f02c602b709cd45e67597c622f2e", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x20000", + "number": "0x3", + "gasLimit": "0x16345785d8a0000", + "gasUsed": "0x53c42", + "timestamp": "0x24", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x29f", + "hash": "0x5c66e5b6d6513ec98e9d8ee88137f1a2418542550977ea02015439acd2bf8f8e" + } + }, + { + "blocknumber": "4", + "rlp": "0xf902e1f901fea05c66e5b6d6513ec98e9d8ee88137f1a2418542550977ea02015439acd2bf8f8ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0e834ba6cd27f2702b0adf2ef6a85e2fbc340fb948c96e75b674e9a73a5dbc3d1a04ed2c2147e0a0d1c248330338f51778f350af8c209c528799278ac980786632ea0976beb67b634171d419ef326220dfdda98074e3495940240a105e17643f0a4efb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000488016345785d8a0000830155443080a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082024cf8ddb86c02f86901078203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820401c001a0113c54f83e1b1e5c689ba86d288ec0ce2877f350b71821c4c7a3f7073b46602ca0548848e711b86ceeb657fd0a0bf44b792f6665ed18ec8a04f498471e811f8f97b86d02f86a0108830186a08203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820402c001a0ebc8ad530ec3d510998aa2485763fcd1c6958c900c8d8ae6eaf86e1eddde8b23a0341e4a021f7b77da28d853c07d11253b92331ab640ad3f28f5d7b2cdbc7ceca7c0", + "expectException": "invalid transaction" + }, + { + "blocknumber": "4", + "rlp": "0xf9034ff901fea05c66e5b6d6513ec98e9d8ee88137f1a2418542550977ea02015439acd2bf8f8ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0e2b2b992b108bcd0e036067ef693f2d1b94c2f48d074a4f6b9d98537bbf15e9aa07617400c1efcb3e64b8cf55ccaaae8e335621bd6897b5e439d93b8dc011a4331a0f42d43454db7c51eadf004bd9e43522c4894f02c602b709cd45e67597c622f2eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000488016345785d8a000083053c423080a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082024cf9014ab86c02f86901078203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820401c001a0113c54f83e1b1e5c689ba86d288ec0ce2877f350b71821c4c7a3f7073b46602ca0548848e711b86ceeb657fd0a0bf44b792f6665ed18ec8a04f498471e811f8f97b86a02f8670108648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820403c080a08d7ec1116399aab6e1297b09302b291d73c5898a0338fb62a46c74b037d15a15a03cacc1a12eb47c261394443d490b8436f53a99d2109dac9ca5018cf531e6b29db86e02f86b0109830186a0830186a0830f424094cccccccccccccccccccccccccccccccccccccccd80820404c001a054bd3a30ee3c2182d92f30223adb53feb0f51d76970a2628d9479536ff3edfe9a06f681aa0ad9362eeeafb981394526ca6425f3a24e1c7f44c413b68dd2e56e5d0c0", + "blockHeader": { + "parentHash": "0x5c66e5b6d6513ec98e9d8ee88137f1a2418542550977ea02015439acd2bf8f8e", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0xba5e000000000000000000000000000000000000", + "stateRoot": "0xe2b2b992b108bcd0e036067ef693f2d1b94c2f48d074a4f6b9d98537bbf15e9a", + "transactionsTrie": "0x7617400c1efcb3e64b8cf55ccaaae8e335621bd6897b5e439d93b8dc011a4331", + "receiptTrie": "0xf42d43454db7c51eadf004bd9e43522c4894f02c602b709cd45e67597c622f2e", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x20000", + "number": "0x4", + "gasLimit": "0x16345785d8a0000", + "gasUsed": "0x53c42", + "timestamp": "0x30", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x24c", + "hash": "0xf5e2f23d9a212edbb35a07bc9f582f4a632b694bd4ef8742de8ad6c6acacf72c" + } + } + ], + "genesisBlockHeader": { + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x89a5be1d3306f6f05b42678ef13ac3dbc37bef9a2a80862c21eb22eee29194c2", + "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x20000", + "number": "0x0", + "gasLimit": "0x16345785d8a0000", + "gasUsed": "0x0", + "timestamp": "0x0", + "extraData": "0x00", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x3e8", + "hash": "0x6241b4534da26b654ec5bb30d29b1d5202454af544b05828433354da7471957c" + }, + "lastblockhash": "0xf5e2f23d9a212edbb35a07bc9f582f4a632b694bd4ef8742de8ad6c6acacf72c", + "network": "London", + "pre": { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x0", + "balance": "0x1000000000000000000", + "code": "0x", + "storage": {} + }, + "0xd02d72E067e77158444ef2020Ff2d325f929B363": { + "nonce": "0x1", + "balance": "0x1000000000000000000", + "code": "0x", + "storage": {} + }, + "0xcccccccccccccccccccccccccccccccccccccccc": { + "nonce": "0x1", + "balance": "0x10000000000", + "code": "0x484355483a036110004301554761200043015500", + "storage": {} + }, + "0xcccccccccccccccccccccccccccccccccccccccd": { + "nonce": "0x1", + "balance": "0x20000000000", + "code": "0x60008060008073cccccccccccccccccccccccccccccccccccccccc5af450", + "storage": {} + }, + "0x000000000000000000000000000000000000c0de": { + "nonce": "0x1", + "balance": "0x0", + "code": "0x60008060008073cccccccccccccccccccccccccccccccccccccccc5af450", + "storage": {} + }, + "0xccccccccccccccccccccccccccccccccccccccce": { + "nonce": "0x1", + "balance": "0x20000000000", + "code": "0x60008060008061100061c0de5af160008060008073cccccccccccccccccccccccccccccccccccccccc5af4905050", + "storage": {} + } + }, + "sealEngine": "NoProof" + } +} \ No newline at end of file diff --git a/tests/ethereum_test/test_fixtures/blockchain_london_filled.json b/tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json similarity index 99% rename from tests/ethereum_test/test_fixtures/blockchain_london_filled.json rename to tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json index 233c3e7db97..64274b3ac6a 100644 --- a/tests/ethereum_test/test_fixtures/blockchain_london_filled.json +++ b/tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json @@ -3,6 +3,7 @@ "_info": {}, "blocks": [ { + "blocknumber": "1", "rlp": "0xf9026ef901fea06241b4534da26b654ec5bb30d29b1d5202454af544b05828433354da7471957ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a03eb2e72e8ed9a59768bb9ac05915b781a764f2582edcf111053fe6531e466613a0586f963eea0fb4726f0f91f895f2aa5d67bffb5207a529b40d781244a0c7017ba029b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000188016345785d8a0000830155340c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082036bf86ab86802f8650180018203e8830f424094cccccccccccccccccccccccccccccccccccccccc8001c080a03351b6993208fc7b03fd770c8c06440cfb0d75b29aafee0a4c64c8ba20a80e58a067817fdb3058e75c5d26e51a33d1e338346bc7d406e115447a4bb5f7ab01625bc0", "blockHeader": { "parentHash": "0x6241b4534da26b654ec5bb30d29b1d5202454af544b05828433354da7471957c", @@ -25,6 +26,7 @@ } }, { + "blocknumber": "2", "rlp": "0xf90349f901fea012bba91a7e1f277f1549e832e06820f8849308f70f8659acf846bdc15f5d586ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0d9d9cc8ae73834ba9dc75fe8c68d36e980c82fcaf887dc220a05f152a327ae55a05521d9ad5adef72f021e4270a1f6851ca772dd56acaf4ff03362151bfb715298a0e225d44649351c3dccc61c1d904451d6f0f5a407c072099fe1085cfad88447d6b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000288016345785d8a000083053c421880a000000000000000000000000000000000000000000000000000000000000000008800000000000000008202fef90144b86a02f86701010a8203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820201c080a06ea285a870a051df2b8c80c462b7d3517f984815e09c4748efc8548a40434050a052f635268c1b9e1538ac76b37cb69c7b897595744d6de2dda9507b6624d352d0b86a02f8670102648203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820202c080a0218549e818b36b3823c3f11a65ab5c1e16f6886469c385503cc2f1af1f53825da058b082850f55fd61290a99add11b7af6356ac8d55fbe4d513f06bf648824a64db86a02f8670103648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820203c001a0339e9ed3f6342f2644e4cd33a775b7e62a8208a137dcf2e354c7473caa77782aa074004c85b651c8ca9828aac28414997f3eff46edbba2bb606a545d95fd4c9b3ac0", "blockHeader": { "parentHash": "0x12bba91a7e1f277f1549e832e06820f8849308f70f8659acf846bdc15f5d586e", @@ -47,6 +49,7 @@ } }, { + "blocknumber": "3", "rlp": "0xf9034ff901fea00e043cb2eb0339900f6199c0ab517e5be3a81d898fa58078ed8b866ddc60b010a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0bb08d7ca9c904f3d01b78041a9d70f69e83b0a6ec7af471cbd00933a47fdacaea027f7b224df1d270bfa03ba564cd4962071b89f91c965dbbfacff55e7ec66c652a0f42d43454db7c51eadf004bd9e43522c4894f02c602b709cd45e67597c622f2eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000388016345785d8a000083053c422480a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082029ff9014ab86c02f86901048203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820301c001a0720e2870881f8b0e285b7ec02c169f1165847bcb5f36ea5f33f3db6079854f63a04448266b715d7d99acd1e31dcab50d7119faa620d44c69b3f64f97d636634169b86a02f8670105648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820303c080a09c8531a41f9281633470c5e12b6c72c8930409a6433f26bf7b394a703d18512ea07a0c6151fde75f10a7e4efdd17a21f1f25206559bd4b8cf7880e5bc30e1cfe33b86e02f86b0106830186a0830186a0830f424094cccccccccccccccccccccccccccccccccccccccd80820304c001a0c8b85e158b532a0e3b3b5848fad0f4d5c6807805a4ce65e8591de13a62f3ac6aa03e923eb1be030c3ca69623f31ad3a357368b1ccb7ee48ac8deec5cb5dc49cb0cc0", "blockHeader": { "parentHash": "0x0e043cb2eb0339900f6199c0ab517e5be3a81d898fa58078ed8b866ddc60b010", @@ -69,6 +72,7 @@ } }, { + "blocknumber": "4", "rlp": "0xf9034ff901fea05c66e5b6d6513ec98e9d8ee88137f1a2418542550977ea02015439acd2bf8f8ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0e2b2b992b108bcd0e036067ef693f2d1b94c2f48d074a4f6b9d98537bbf15e9aa07617400c1efcb3e64b8cf55ccaaae8e335621bd6897b5e439d93b8dc011a4331a0f42d43454db7c51eadf004bd9e43522c4894f02c602b709cd45e67597c622f2eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000488016345785d8a000083053c423080a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082024cf9014ab86c02f86901078203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820401c001a0113c54f83e1b1e5c689ba86d288ec0ce2877f350b71821c4c7a3f7073b46602ca0548848e711b86ceeb657fd0a0bf44b792f6665ed18ec8a04f498471e811f8f97b86a02f8670108648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820403c080a08d7ec1116399aab6e1297b09302b291d73c5898a0338fb62a46c74b037d15a15a03cacc1a12eb47c261394443d490b8436f53a99d2109dac9ca5018cf531e6b29db86e02f86b0109830186a0830186a0830f424094cccccccccccccccccccccccccccccccccccccccd80820404c001a054bd3a30ee3c2182d92f30223adb53feb0f51d76970a2628d9479536ff3edfe9a06f681aa0ad9362eeeafb981394526ca6425f3a24e1c7f44c413b68dd2e56e5d0c0", "blockHeader": { "parentHash": "0x5c66e5b6d6513ec98e9d8ee88137f1a2418542550977ea02015439acd2bf8f8e", From 7d26c6b96666d9370a874f86b3049e0df0508c63 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 12:57:30 -0600 Subject: [PATCH 2/9] Update README --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 6b6617f4b72..b83d3f08837 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ The Blockchain tests span multiple blocks which can contain or not transactions, - Verify system-level operations such as coinbase balance updates or withdrawals - Verify fork transitions +- Verify blocks with invalid transactions/properties are rejected ### Adding a New Test @@ -231,6 +232,19 @@ check that test is effective. E.g. when a transaction is supposed to fail, it is necessary to check that the failure error is actually the one expected by the test. +### Failing or invalid transactions + +Transactions included in a StateTest are expected to be intrinsically valid, +i.e. the account sending the transaction must have enough funds to cover the +gas costs, the max fee of the transaction must be equal or higher than the +base fee of the block, etc. + +An intrinsically valid transaction can still revert during its execution. + +Blocks in a BlockchainTest can contain intrinsically invalid transactions but +in this case the block is expected to be completely rejected, along with all +transactions in it, including other valid transactions. + [t8n]: https://github.com/ethereum/go-ethereum/tree/master/cmd/evm [b11r]: https://github.com/ethereum/go-ethereum/pull/23843 [yul]: https://docs.soliditylang.org/en/latest/yul.html From 68f55ba6b28548f5aa59f0fc954bc2fcd2bc179c Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 14:43:16 -0600 Subject: [PATCH 3/9] Abstract block builder and transition tool changes --- src/ethereum_test/decorators.py | 36 +++++++++++------ src/ethereum_test/fill.py | 8 ++-- src/ethereum_test_filler/main.py | 7 +++- src/evm_block_builder/__init__.py | 28 ++++++++++++- src/evm_transition_tool/__init__.py | 31 +++++++++++++++ tests/ethereum_test/test_filler.py | 46 ++++++++++++++-------- tests/evm_block_builder/test_build.py | 10 +++-- tests/evm_transition_tool/test_evaluate.py | 10 +++-- 8 files changed, 135 insertions(+), 41 deletions(-) diff --git a/src/ethereum_test/decorators.py b/src/ethereum_test/decorators.py index 70caa4a11b8..f7a3a8c9983 100644 --- a/src/ethereum_test/decorators.py +++ b/src/ethereum_test/decorators.py @@ -12,7 +12,9 @@ def test_from_until( fork_from: str, fork_until: str, -) -> Callable[[StateTestSpec], Callable[[str], Mapping[str, Fixture]]]: +) -> Callable[ + [StateTestSpec], Callable[[Any, Any, str], Mapping[str, Fixture]] +]: """ Decorator that takes a test generator and fills it for all forks after the specified fork. @@ -20,10 +22,12 @@ def test_from_until( fork_from = fork_from.capitalize() fork_until = fork_until.capitalize() - def decorator(fn: StateTestSpec) -> Callable[[str], Mapping[str, Fixture]]: - def inner(engine) -> Mapping[str, Fixture]: + def decorator( + fn: StateTestSpec, + ) -> Callable[[Any, Any, str], Mapping[str, Fixture]]: + def inner(t8n, b11r, engine) -> Mapping[str, Fixture]: return fill_test( - fn, forks_from_until(fork_from, fork_until), engine + t8n, b11r, fn, forks_from_until(fork_from, fork_until), engine ) cast(Any, inner).__filler_metadata__ = { @@ -38,16 +42,20 @@ def inner(engine) -> Mapping[str, Fixture]: def test_from( fork: str, -) -> Callable[[StateTestSpec], Callable[[str], Mapping[str, Fixture]]]: +) -> Callable[ + [StateTestSpec], Callable[[Any, Any, str], Mapping[str, Fixture]] +]: """ Decorator that takes a test generator and fills it for all forks after the specified fork. """ fork = fork.capitalize() - def decorator(fn: StateTestSpec) -> Callable[[str], Mapping[str, Fixture]]: - def inner(engine) -> Mapping[str, Fixture]: - return fill_test(fn, forks_from(fork), engine) + def decorator( + fn: StateTestSpec, + ) -> Callable[[Any, Any, str], Mapping[str, Fixture]]: + def inner(t8n, b11r, engine) -> Mapping[str, Fixture]: + return fill_test(t8n, b11r, fn, forks_from(fork), engine) cast(Any, inner).__filler_metadata__ = { "fork": fork, @@ -61,16 +69,20 @@ def inner(engine) -> Mapping[str, Fixture]: def test_only( fork: str, -) -> Callable[[StateTestSpec], Callable[[str], Mapping[str, Fixture]]]: +) -> Callable[ + [StateTestSpec], Callable[[Any, Any, str], Mapping[str, Fixture]] +]: """ Decorator that takes a test generator and fills it only for the specified fork. """ fork = fork.capitalize() - def decorator(fn: StateTestSpec) -> Callable[[str], Mapping[str, Fixture]]: - def inner(engine) -> Mapping[str, Fixture]: - return fill_test(fn, [fork], engine) + def decorator( + fn: StateTestSpec, + ) -> Callable[[Any, Any, str], Mapping[str, Fixture]]: + def inner(t8n, b11r, engine) -> Mapping[str, Fixture]: + return fill_test(t8n, b11r, fn, [fork], engine) cast(Any, inner).__filler_metadata__ = { "fork": fork, diff --git a/src/ethereum_test/fill.py b/src/ethereum_test/fill.py index 6c5a24547d6..454f711f0f6 100644 --- a/src/ethereum_test/fill.py +++ b/src/ethereum_test/fill.py @@ -11,15 +11,17 @@ def fill_test( - test_spec: TestSpec, forks: List[str], engine: str + t8n: TransitionTool, + b11r: BlockBuilder, + test_spec: TestSpec, + forks: List[str], + engine: str, ) -> Mapping[str, Fixture]: """ Fills fixtures for certain forks. """ fixtures: List[Fixture] = [] for fork in forks: - b11r = BlockBuilder() - t8n = TransitionTool() for test in test_spec(fork): diff --git a/src/ethereum_test_filler/main.py b/src/ethereum_test_filler/main.py index 2014bd4b91f..50676660853 100755 --- a/src/ethereum_test_filler/main.py +++ b/src/ethereum_test_filler/main.py @@ -16,6 +16,8 @@ import setuptools from ethereum_test.types import JSONEncoder +from evm_block_builder import EvmBlockBuilder +from evm_transition_tool import EvmTransitionTool class Filler: @@ -105,6 +107,9 @@ def fill(self) -> None: os.makedirs(self.options.output, exist_ok=True) + t8n = EvmTransitionTool() + b11r = EvmBlockBuilder() + for filler in fillers: name = filler.__filler_metadata__["name"] output_dir = os.path.join( @@ -115,7 +120,7 @@ def fill(self) -> None: path = os.path.join(output_dir, f"{name}.json") self.log.debug(f"filling {name}") - fixture = filler("NoProof") + fixture = filler(t8n, b11r, "NoProof") with open(path, "w", encoding="utf-8") as f: json.dump( diff --git a/src/evm_block_builder/__init__.py b/src/evm_block_builder/__init__.py index bfe097db3cd..9bead40c3b0 100644 --- a/src/evm_block_builder/__init__.py +++ b/src/evm_block_builder/__init__.py @@ -4,6 +4,7 @@ import json import subprocess +from abc import abstractmethod from pathlib import Path from shutil import which from typing import Any, Optional, Tuple @@ -11,7 +12,29 @@ class BlockBuilder: """ - Block builder frontend. + Generic Block builder frontend. + """ + + @abstractmethod + def build( + self, + header: Any, + txs: Any, + ommers: Any, + clique: Optional[Any] = None, + ethash: bool = False, + ethashMode: str = "normal", + ) -> Tuple[str, str]: + pass + + @abstractmethod + def version(self) -> str: + pass + + +class EvmBlockBuilder(BlockBuilder): + """ + Go-ethereum `evm` Block builder frontend. """ binary: Path @@ -78,3 +101,6 @@ def build( Exception("malformed result") return (output["rlp"], output["hash"]) + + def version(self) -> str: + return "" diff --git a/src/evm_transition_tool/__init__.py b/src/evm_transition_tool/__init__.py index 755d15656b2..137bc094af0 100644 --- a/src/evm_transition_tool/__init__.py +++ b/src/evm_transition_tool/__init__.py @@ -4,6 +4,7 @@ import json import subprocess +from abc import abstractmethod from pathlib import Path from shutil import which from typing import Any, Optional, Tuple @@ -14,6 +15,33 @@ class TransitionTool: Transition tool frontend. """ + @abstractmethod + def evaluate( + self, + alloc: Any, + txs: Any, + env: Any, + fork: str, + chain_id: int = 1, + reward: int = 0, + txsPath: Optional[str] = None, + ) -> Tuple[Any, Any]: + pass + + @abstractmethod + def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: + pass + + @abstractmethod + def version(self) -> str: + pass + + +class EvmTransitionTool(TransitionTool): + """ + Go-ethereum `evm` Transition tool frontend. + """ + binary: Path def __init__(self, binary: Optional[Path] = None): @@ -102,6 +130,9 @@ def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: (_, result) = self.evaluate(alloc, [], env, fork) return result.get("stateRoot") + def version(self) -> str: + return "" + fork_map = { "frontier": "Frontier", diff --git a/tests/ethereum_test/test_filler.py b/tests/ethereum_test/test_filler.py index 0d2f03df33e..0a5610cd48a 100644 --- a/tests/ethereum_test/test_filler.py +++ b/tests/ethereum_test/test_filler.py @@ -5,6 +5,8 @@ import json from typing import Generator, List +import pytest + from ethereum_test import ( Account, Block, @@ -17,11 +19,14 @@ ) from ethereum_test.blockchain_test import BlockchainTest from ethereum_test.yul import Yul -from evm_block_builder import BlockBuilder -from evm_transition_tool import TransitionTool +from evm_block_builder import EvmBlockBuilder +from evm_transition_tool import EvmTransitionTool -def test_make_genesis(): +@pytest.mark.parametrize( + "fork,hash", [("Berlin", "0x87c5fa7cef8b"), ("London", "0xe3c84688fa32")] +) +def test_make_genesis(fork: str, hash: str): env = Environment() pre = { @@ -43,17 +48,14 @@ def test_make_genesis(): TestAddress: Account(balance=0x0BA1A9CE0BA1A9CE), } - b11r = BlockBuilder() - t8n = TransitionTool() + b11r = EvmBlockBuilder() + t8n = EvmTransitionTool() - london_genesis = StateTest(env=env, pre=pre, post={}, txs=[]).make_genesis( - b11r, t8n, "London" - ) - assert london_genesis.hash.startswith("0xe3c84688fa32") - berlin_genesis = StateTest(env=env, pre=pre, post={}, txs=[]).make_genesis( - b11r, t8n, "Berlin" + genesis = StateTest(env=env, pre=pre, post={}, txs=[]).make_genesis( + b11r, t8n, fork ) - assert berlin_genesis.hash.startswith("0x87c5fa7cef8b") + assert genesis.hash is not None + assert genesis.hash.startswith(hash) def test_fill_state_test(): @@ -94,9 +96,15 @@ def test_fill_state_test(): } def generator(_) -> Generator[StateTest, None, None]: + """ + Test test test + """ yield StateTest(env=env, pre=pre, post=post, txs=[tx]) - fixture = fill_test(generator, ["London"], "NoProof") + b11r = EvmBlockBuilder() + t8n = EvmTransitionTool() + + fixture = fill_test(t8n, b11r, generator, ["London"], "NoProof") with open( "tests/ethereum_test/test_fixtures/chainid_london_filled.json" ) as f: @@ -104,7 +112,7 @@ def generator(_) -> Generator[StateTest, None, None]: fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) assert fixture_json == expected - fixture = fill_test(generator, ["Istanbul"], "NoProof") + fixture = fill_test(t8n, b11r, generator, ["Istanbul"], "NoProof") with open( "tests/ethereum_test/test_fixtures/chainid_istanbul_filled.json" ) as f: @@ -372,7 +380,10 @@ def generator(_) -> Generator[BlockchainTest, None, None]: genesis_environment=genesis_environment, ) - fixture = fill_test(generator, ["London"], "NoProof") + b11r = EvmBlockBuilder() + t8n = EvmTransitionTool() + + fixture = fill_test(t8n, b11r, generator, ["London"], "NoProof") with open( "tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json" @@ -689,7 +700,10 @@ def generator(_) -> Generator[BlockchainTest, None, None]: genesis_environment=genesis_environment, ) - fixture = fill_test(generator, ["London"], "NoProof") + b11r = EvmBlockBuilder() + t8n = EvmTransitionTool() + + fixture = fill_test(t8n, b11r, generator, ["London"], "NoProof") with open( "tests/ethereum_test/test_fixtures/" diff --git a/tests/evm_block_builder/test_build.py b/tests/evm_block_builder/test_build.py index daddf5cdba1..9786928bd30 100644 --- a/tests/evm_block_builder/test_build.py +++ b/tests/evm_block_builder/test_build.py @@ -2,13 +2,15 @@ import os from pathlib import Path -from evm_block_builder import BlockBuilder +import pytest -FIXTURES_ROOT = Path("tests/evm_block_builder/fixtures") +from evm_block_builder import BlockBuilder, EvmBlockBuilder +FIXTURES_ROOT = Path(os.path.join("tests", "evm_block_builder", "fixtures")) -def test_simple() -> None: - b11r = BlockBuilder() + +@pytest.mark.parametrize("b11r", [EvmBlockBuilder()]) +def test_evm_simple(b11r: BlockBuilder) -> None: for test_dir in os.listdir(path=FIXTURES_ROOT): env_path = Path(FIXTURES_ROOT, test_dir, "header.json") diff --git a/tests/evm_transition_tool/test_evaluate.py b/tests/evm_transition_tool/test_evaluate.py index 76784c87712..cafc0c859aa 100644 --- a/tests/evm_transition_tool/test_evaluate.py +++ b/tests/evm_transition_tool/test_evaluate.py @@ -2,13 +2,15 @@ import os from pathlib import Path -from evm_transition_tool import TransitionTool +import pytest -FIXTURES_ROOT = Path("tests/evm_transition_tool/fixtures") +from evm_transition_tool import EvmTransitionTool, TransitionTool +FIXTURES_ROOT = Path(os.path.join("tests", "evm_transition_tool", "fixtures")) -def test_t8n() -> None: - t8n = TransitionTool() + +@pytest.mark.parametrize("t8n", [EvmTransitionTool()]) +def test_evm_t8n(t8n: TransitionTool) -> None: for test_dir in os.listdir(path=FIXTURES_ROOT): alloc_path = Path(FIXTURES_ROOT, test_dir, "alloc.json") From 00d6b67a8a0e9f9a52207da98fcda464a2a1eaa3 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 15:20:14 -0600 Subject: [PATCH 4/9] Add t8n version to filled info --- src/ethereum_test/fill.py | 20 +++++----- src/ethereum_test/types.py | 10 ++++- src/evm_block_builder/__init__.py | 20 +++++++++- src/evm_transition_tool/__init__.py | 20 +++++++++- tests/ethereum_test/test_filler.py | 38 +++++++++++-------- .../blockchain_london_invalid_filled.json | 1 - .../blockchain_london_valid_filled.json | 1 - .../chainid_istanbul_filled.json | 1 - .../test_fixtures/chainid_london_filled.json | 1 - 9 files changed, 80 insertions(+), 32 deletions(-) diff --git a/src/ethereum_test/fill.py b/src/ethereum_test/fill.py index 454f711f0f6..9e67f0b133a 100644 --- a/src/ethereum_test/fill.py +++ b/src/ethereum_test/fill.py @@ -39,17 +39,17 @@ def fill_test( b11r, t8n, genesis, fork, reward=2000000000000000000 ) - fixtures.append( - Fixture( - blocks=blocks, - genesis=genesis, - head=head, - fork=fork, - pre_state=test.pre, - post_state=None, - seal_engine=engine, - ) + fixture = Fixture( + blocks=blocks, + genesis=genesis, + head=head, + fork=fork, + pre_state=test.pre, + post_state=None, + seal_engine=engine, ) + fixture.set_info(t8n, b11r) + fixtures.append(fixture) out = {} for fixture in fixtures: diff --git a/src/ethereum_test/types.py b/src/ethereum_test/types.py index 966d80a4144..c7b19e9dd95 100644 --- a/src/ethereum_test/types.py +++ b/src/ethereum_test/types.py @@ -6,6 +6,9 @@ from dataclasses import dataclass, field from typing import Any, Dict, List, Mapping, Optional, Tuple, Type, Union +from evm_block_builder import BlockBuilder +from evm_transition_tool import TransitionTool + from .code import Code, code_to_hex from .common import AddrAA, TestPrivateKey @@ -589,6 +592,11 @@ class Fixture: pre_state: Mapping[str, Account] post_state: Optional[Mapping[str, Account]] seal_engine: str + info: Dict[str, str] = field(default_factory=dict) + + def set_info(self, t8n: TransitionTool, b11r: BlockBuilder): + self.info["filling-transition-tool"] = t8n.version() + self.info["filling-block-build-tool"] = b11r.version() class JSONEncoder(json.JSONEncoder): @@ -707,7 +715,7 @@ def default(self, obj): return b elif isinstance(obj, Fixture): f = { - "_info": {}, + "_info": obj.info, "blocks": [ json.loads(json.dumps(b, cls=JSONEncoder)) for b in obj.blocks diff --git a/src/evm_block_builder/__init__.py b/src/evm_block_builder/__init__.py index 9bead40c3b0..f111af70d24 100644 --- a/src/evm_block_builder/__init__.py +++ b/src/evm_block_builder/__init__.py @@ -38,6 +38,7 @@ class EvmBlockBuilder(BlockBuilder): """ binary: Path + cached_version: Optional[str] = None def __init__(self, binary: Optional[Path] = None): if binary is None: @@ -103,4 +104,21 @@ def build( return (output["rlp"], output["hash"]) def version(self) -> str: - return "" + """ + Gets `evm` binary version. + """ + if self.cached_version is None: + + result = subprocess.run( + [str(self.binary), "-v"], + stdout=subprocess.PIPE, + ) + + if result.returncode != 0: + raise Exception( + "failed to evaluate: " + result.stderr.decode() + ) + + self.cached_version = result.stdout.decode().strip() + + return self.cached_version diff --git a/src/evm_transition_tool/__init__.py b/src/evm_transition_tool/__init__.py index 137bc094af0..aa80497b7b9 100644 --- a/src/evm_transition_tool/__init__.py +++ b/src/evm_transition_tool/__init__.py @@ -43,6 +43,7 @@ class EvmTransitionTool(TransitionTool): """ binary: Path + cached_version: Optional[str] = None def __init__(self, binary: Optional[Path] = None): if binary is None: @@ -131,7 +132,24 @@ def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: return result.get("stateRoot") def version(self) -> str: - return "" + """ + Gets `evm` binary version. + """ + if self.cached_version is None: + + result = subprocess.run( + [str(self.binary), "-v"], + stdout=subprocess.PIPE, + ) + + if result.returncode != 0: + raise Exception( + "failed to evaluate: " + result.stderr.decode() + ) + + self.cached_version = result.stdout.decode().strip() + + return self.cached_version fork_map = { diff --git a/tests/ethereum_test/test_filler.py b/tests/ethereum_test/test_filler.py index 0a5610cd48a..780d0ac52da 100644 --- a/tests/ethereum_test/test_filler.py +++ b/tests/ethereum_test/test_filler.py @@ -3,7 +3,8 @@ """ import json -from typing import Generator, List +import os +from typing import Any, Dict, Generator, List import pytest @@ -23,6 +24,12 @@ from evm_transition_tool import EvmTransitionTool +def remove_info(fixture_json: Dict[str, Any]): + for t in fixture_json: + if "_info" in fixture_json[t]: + del fixture_json[t]["_info"] + + @pytest.mark.parametrize( "fork,hash", [("Berlin", "0x87c5fa7cef8b"), ("London", "0xe3c84688fa32")] ) @@ -58,7 +65,14 @@ def test_make_genesis(fork: str, hash: str): assert genesis.hash.startswith(hash) -def test_fill_state_test(): +@pytest.mark.parametrize( + "fork,expected_json_file", + [ + ("Istanbul", "chainid_istanbul_filled.json"), + ("London", "chainid_london_filled.json"), + ], +) +def test_fill_state_test(fork: str, expected_json_file: str): """ Test `ethereum_test.filler.fill_fixtures` with `StateTest`. """ @@ -96,28 +110,20 @@ def test_fill_state_test(): } def generator(_) -> Generator[StateTest, None, None]: - """ - Test test test - """ yield StateTest(env=env, pre=pre, post=post, txs=[tx]) b11r = EvmBlockBuilder() t8n = EvmTransitionTool() - fixture = fill_test(t8n, b11r, generator, ["London"], "NoProof") - with open( - "tests/ethereum_test/test_fixtures/chainid_london_filled.json" - ) as f: - expected = json.load(f) - fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) - assert fixture_json == expected - - fixture = fill_test(t8n, b11r, generator, ["Istanbul"], "NoProof") + fixture = fill_test(t8n, b11r, generator, [fork], "NoProof") with open( - "tests/ethereum_test/test_fixtures/chainid_istanbul_filled.json" + os.path.join( + "tests", "ethereum_test", "test_fixtures", expected_json_file + ) ) as f: expected = json.load(f) fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) + remove_info(fixture_json) assert fixture_json == expected @@ -391,6 +397,7 @@ def generator(_) -> Generator[BlockchainTest, None, None]: expected = json.load(f) fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) + remove_info(fixture_json) assert fixture_json == expected @@ -712,4 +719,5 @@ def generator(_) -> Generator[BlockchainTest, None, None]: expected = json.load(f) fixture_json = json.loads(json.dumps(fixture, cls=JSONEncoder)) + remove_info(fixture_json) assert fixture_json == expected diff --git a/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json b/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json index 50813fa7b68..a6104d3d00d 100644 --- a/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json +++ b/tests/ethereum_test/test_fixtures/blockchain_london_invalid_filled.json @@ -1,6 +1,5 @@ { "london": { - "_info": {}, "blocks": [ { "blocknumber": "1", diff --git a/tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json b/tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json index 64274b3ac6a..e76337df175 100644 --- a/tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json +++ b/tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json @@ -1,6 +1,5 @@ { "london": { - "_info": {}, "blocks": [ { "blocknumber": "1", diff --git a/tests/ethereum_test/test_fixtures/chainid_istanbul_filled.json b/tests/ethereum_test/test_fixtures/chainid_istanbul_filled.json index dd70d0040c8..f36be847779 100644 --- a/tests/ethereum_test/test_fixtures/chainid_istanbul_filled.json +++ b/tests/ethereum_test/test_fixtures/chainid_istanbul_filled.json @@ -1,6 +1,5 @@ { "istanbul": { - "_info": {}, "blocks": [ { "rlp": "0xf90262f901f9a007a0192766c62d9bdb9e357ebdffd4d8c1d12c15b467c453772c3f8027f02886a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa0330a7882a8fadd60d0b6bf3d8ce7a8ae024800ae31ad8fae24d654a6a83fcad6a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba0fa9e942c7bab1017c29ab8b7f9484e311f3a2ba680c2ec8abbaea2365cecc93eb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a02d8203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0", diff --git a/tests/ethereum_test/test_fixtures/chainid_london_filled.json b/tests/ethereum_test/test_fixtures/chainid_london_filled.json index f945aaf4310..6303017f773 100644 --- a/tests/ethereum_test/test_fixtures/chainid_london_filled.json +++ b/tests/ethereum_test/test_fixtures/chainid_london_filled.json @@ -1,6 +1,5 @@ { "london": { - "_info": {}, "blocks": [ { "rlp": "0xf90263f901faa0c23ec9a992cd009c20de66b8b0b54f358f1b684ed55f841d71aa5031e1c11b5fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa0a48abc194fdd8e58a32a90874e9144e19eb68306ec5e51bca9389d1043eeb20fa08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba0c598f69a5674cae9337261b669970e24abc0b46e6d284372a239ec8ccbf20b0ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8618203e800a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0", From ba8815b5cee311acca344b04b63e8c1a4c290003 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 15:48:51 -0600 Subject: [PATCH 5/9] Add generic calc state root + tests --- src/evm_transition_tool/__init__.py | 44 +++++++-------- tests/evm_transition_tool/test_evaluate.py | 66 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 24 deletions(-) diff --git a/src/evm_transition_tool/__init__.py b/src/evm_transition_tool/__init__.py index aa80497b7b9..414cb0f839f 100644 --- a/src/evm_transition_tool/__init__.py +++ b/src/evm_transition_tool/__init__.py @@ -28,14 +28,30 @@ def evaluate( ) -> Tuple[Any, Any]: pass - @abstractmethod - def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: - pass - @abstractmethod def version(self) -> str: pass + def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: + """ + Calculate the state root for the given `alloc`. + """ + base_fee = env.base_fee + env = { + "currentCoinbase": "0x0000000000000000000000000000000000000000", + "currentDifficulty": "0x0", + "currentGasLimit": "0x0", + "currentNumber": "0", + "currentTimestamp": "0", + } + if base_fee is not None: + env["currentBaseFee"] = str(base_fee) + elif base_fee_required(fork): + env["currentBaseFee"] = "7" + + (_, result) = self.evaluate(alloc, [], env, fork) + return result.get("stateRoot") + class EvmTransitionTool(TransitionTool): """ @@ -111,26 +127,6 @@ def evaluate( return (output["alloc"], output["result"]) - def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: - """ - Calculate the state root for the given `alloc`. - """ - base_fee = env.base_fee - env = { - "currentCoinbase": "0x0000000000000000000000000000000000000000", - "currentDifficulty": "0x0", - "currentGasLimit": "0x0", - "currentNumber": "0", - "currentTimestamp": "0", - } - if base_fee is not None: - env["currentBaseFee"] = str(base_fee) - elif base_fee_required(fork): - env["currentBaseFee"] = "7" - - (_, result) = self.evaluate(alloc, [], env, fork) - return result.get("stateRoot") - def version(self) -> str: """ Gets `evm` binary version. diff --git a/tests/evm_transition_tool/test_evaluate.py b/tests/evm_transition_tool/test_evaluate.py index cafc0c859aa..d9f102dd416 100644 --- a/tests/evm_transition_tool/test_evaluate.py +++ b/tests/evm_transition_tool/test_evaluate.py @@ -1,6 +1,7 @@ import json import os from pathlib import Path +from typing import Dict, Optional import pytest @@ -9,6 +10,71 @@ FIXTURES_ROOT = Path(os.path.join("tests", "evm_transition_tool", "fixtures")) +class TestEnv: + base_fee: Optional[int] + + def __init__(self, base_fee: Optional[int] = None): + self.base_fee = base_fee + + +@pytest.mark.parametrize("t8n", [EvmTransitionTool()]) +@pytest.mark.parametrize("fork", ["London", "Istanbul"]) +@pytest.mark.parametrize( + "alloc,env,hash", + [ + ( + { + "0x1000000000000000000000000000000000000000": { + "balance": "0x0BA1A9CE0BA1A9CE", + "code": "0x", + "nonce": "0", + "storage": {}, + }, + }, + TestEnv(7), + "0x51e7c7508e76dca0", + ), + ( + { + "0x1000000000000000000000000000000000000000": { + "balance": "0x0BA1A9CE0BA1A9CE", + }, + }, + TestEnv(), + "0x51e7c7508e76dca0", + ), + ( + { + "0x1000000000000000000000000000000000000000": { + "balance": "0x0BA1A9CE0BA1A9CE", + "code": "0x", + "nonce": "1", + "storage": {}, + }, + }, + TestEnv(), + "0x37c2dedbdea6b3af", + ), + ( + { + "0x1000000000000000000000000000000000000000": { + "balance": "0", + "storage": { + "0x01": "0x01", + }, + }, + }, + TestEnv(), + "0x096122e88929baec", + ), + ], +) +def test_calc_state_root( + t8n: TransitionTool, fork: str, alloc: Dict, env: TestEnv, hash: str +) -> None: + assert t8n.calc_state_root(env, alloc, fork).startswith(hash) + + @pytest.mark.parametrize("t8n", [EvmTransitionTool()]) def test_evm_t8n(t8n: TransitionTool) -> None: From e91dbe2f80853d9220928cb3829f20cb46538126 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 15:52:00 -0600 Subject: [PATCH 6/9] Parametrize existing tests --- tests/evm_block_builder/test_build.py | 38 +++++++++++----------- tests/evm_transition_tool/test_evaluate.py | 36 ++++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/tests/evm_block_builder/test_build.py b/tests/evm_block_builder/test_build.py index 9786928bd30..2dd92347e91 100644 --- a/tests/evm_block_builder/test_build.py +++ b/tests/evm_block_builder/test_build.py @@ -10,22 +10,22 @@ @pytest.mark.parametrize("b11r", [EvmBlockBuilder()]) -def test_evm_simple(b11r: BlockBuilder) -> None: - - for test_dir in os.listdir(path=FIXTURES_ROOT): - env_path = Path(FIXTURES_ROOT, test_dir, "header.json") - txs_path = Path(FIXTURES_ROOT, test_dir, "txs.rlp") - ommers_path = Path(FIXTURES_ROOT, test_dir, "ommers.json") - expected_path = Path(FIXTURES_ROOT, test_dir, "exp.json") - - with open(env_path, "r") as env, open(txs_path, "r") as txs, open( - ommers_path, "r" - ) as ommers, open(expected_path, "r") as exp: - env = json.load(env) - txs = json.load(txs) - ommers = json.load(ommers) - expected = json.load(exp) - - (rlp, h) = b11r.build(env, txs, ommers, None) - assert rlp == expected.get("rlp") - assert h == expected.get("hash") +@pytest.mark.parametrize("test_dir", os.listdir(path=FIXTURES_ROOT)) +def test_evm_simple(b11r: BlockBuilder, test_dir: str) -> None: + + env_path = Path(FIXTURES_ROOT, test_dir, "header.json") + txs_path = Path(FIXTURES_ROOT, test_dir, "txs.rlp") + ommers_path = Path(FIXTURES_ROOT, test_dir, "ommers.json") + expected_path = Path(FIXTURES_ROOT, test_dir, "exp.json") + + with open(env_path, "r") as env, open(txs_path, "r") as txs, open( + ommers_path, "r" + ) as ommers, open(expected_path, "r") as exp: + env = json.load(env) + txs = json.load(txs) + ommers = json.load(ommers) + expected = json.load(exp) + + (rlp, h) = b11r.build(env, txs, ommers, None) + assert rlp == expected.get("rlp") + assert h == expected.get("hash") diff --git a/tests/evm_transition_tool/test_evaluate.py b/tests/evm_transition_tool/test_evaluate.py index d9f102dd416..cb4437ee177 100644 --- a/tests/evm_transition_tool/test_evaluate.py +++ b/tests/evm_transition_tool/test_evaluate.py @@ -76,24 +76,24 @@ def test_calc_state_root( @pytest.mark.parametrize("t8n", [EvmTransitionTool()]) -def test_evm_t8n(t8n: TransitionTool) -> None: +@pytest.mark.parametrize("test_dir", os.listdir(path=FIXTURES_ROOT)) +def test_evm_t8n(t8n: TransitionTool, test_dir: str) -> None: - for test_dir in os.listdir(path=FIXTURES_ROOT): - alloc_path = Path(FIXTURES_ROOT, test_dir, "alloc.json") - txs_path = Path(FIXTURES_ROOT, test_dir, "txs.json") - env_path = Path(FIXTURES_ROOT, test_dir, "env.json") - expected_path = Path(FIXTURES_ROOT, test_dir, "exp.json") + alloc_path = Path(FIXTURES_ROOT, test_dir, "alloc.json") + txs_path = Path(FIXTURES_ROOT, test_dir, "txs.json") + env_path = Path(FIXTURES_ROOT, test_dir, "env.json") + expected_path = Path(FIXTURES_ROOT, test_dir, "exp.json") - with open(alloc_path, "r") as alloc, open(txs_path, "r") as txs, open( - env_path, "r" - ) as env, open(expected_path, "r") as exp: - print(expected_path) - alloc = json.load(alloc) - txs = json.load(txs) - env = json.load(env) - expected = json.load(exp) + with open(alloc_path, "r") as alloc, open(txs_path, "r") as txs, open( + env_path, "r" + ) as env, open(expected_path, "r") as exp: + print(expected_path) + alloc = json.load(alloc) + txs = json.load(txs) + env = json.load(env) + expected = json.load(exp) - (alloc, result) = t8n.evaluate(alloc, txs, env, "Berlin") - print(result) - assert alloc == expected.get("alloc") - assert result == expected.get("result") + (alloc, result) = t8n.evaluate(alloc, txs, env, "Berlin") + print(result) + assert alloc == expected.get("alloc") + assert result == expected.get("result") From a39c57cc8b392e248e31ac1caf33a06c200725ff Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 16:01:34 -0600 Subject: [PATCH 7/9] Tox fixes --- src/ethereum_test/fill.py | 2 +- src/ethereum_test/types.py | 5 ++++- src/evm_block_builder/__init__.py | 6 ++++++ src/evm_transition_tool/__init__.py | 6 ++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ethereum_test/fill.py b/src/ethereum_test/fill.py index 9e67f0b133a..3caec2ba3b3 100644 --- a/src/ethereum_test/fill.py +++ b/src/ethereum_test/fill.py @@ -48,7 +48,7 @@ def fill_test( post_state=None, seal_engine=engine, ) - fixture.set_info(t8n, b11r) + fixture.fill_info(t8n, b11r) fixtures.append(fixture) out = {} diff --git a/src/ethereum_test/types.py b/src/ethereum_test/types.py index c7b19e9dd95..d5c722d27e0 100644 --- a/src/ethereum_test/types.py +++ b/src/ethereum_test/types.py @@ -594,7 +594,10 @@ class Fixture: seal_engine: str info: Dict[str, str] = field(default_factory=dict) - def set_info(self, t8n: TransitionTool, b11r: BlockBuilder): + def fill_info(self, t8n: TransitionTool, b11r: BlockBuilder): + """ + Fill the info field for this fixture + """ self.info["filling-transition-tool"] = t8n.version() self.info["filling-block-build-tool"] = b11r.version() diff --git a/src/evm_block_builder/__init__.py b/src/evm_block_builder/__init__.py index f111af70d24..8f4baaa9314 100644 --- a/src/evm_block_builder/__init__.py +++ b/src/evm_block_builder/__init__.py @@ -25,10 +25,16 @@ def build( ethash: bool = False, ethashMode: str = "normal", ) -> Tuple[str, str]: + """ + Build a block with specified parameters and return RLP and hash + """ pass @abstractmethod def version(self) -> str: + """ + Return name and version of tool used to build the block + """ pass diff --git a/src/evm_transition_tool/__init__.py b/src/evm_transition_tool/__init__.py index 414cb0f839f..8531bc2ac20 100644 --- a/src/evm_transition_tool/__init__.py +++ b/src/evm_transition_tool/__init__.py @@ -26,10 +26,16 @@ def evaluate( reward: int = 0, txsPath: Optional[str] = None, ) -> Tuple[Any, Any]: + """ + Simulate a state transition with specified parameters + """ pass @abstractmethod def version(self) -> str: + """ + Return name and version of tool used to state transition + """ pass def calc_state_root(self, env: Any, alloc: Any, fork: str) -> str: From baacb4ae003b473759cc9941e34b287a803c9b87 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 16:02:21 -0600 Subject: [PATCH 8/9] Fix test --- tests/evm_transition_tool/test_evaluate.py | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/evm_transition_tool/test_evaluate.py b/tests/evm_transition_tool/test_evaluate.py index cb4437ee177..8e315a8d0a9 100644 --- a/tests/evm_transition_tool/test_evaluate.py +++ b/tests/evm_transition_tool/test_evaluate.py @@ -1,7 +1,7 @@ import json import os from pathlib import Path -from typing import Dict, Optional +from typing import Dict, Union import pytest @@ -10,17 +10,10 @@ FIXTURES_ROOT = Path(os.path.join("tests", "evm_transition_tool", "fixtures")) -class TestEnv: - base_fee: Optional[int] - - def __init__(self, base_fee: Optional[int] = None): - self.base_fee = base_fee - - @pytest.mark.parametrize("t8n", [EvmTransitionTool()]) @pytest.mark.parametrize("fork", ["London", "Istanbul"]) @pytest.mark.parametrize( - "alloc,env,hash", + "alloc,base_fee,hash", [ ( { @@ -31,7 +24,7 @@ def __init__(self, base_fee: Optional[int] = None): "storage": {}, }, }, - TestEnv(7), + 7, "0x51e7c7508e76dca0", ), ( @@ -40,7 +33,7 @@ def __init__(self, base_fee: Optional[int] = None): "balance": "0x0BA1A9CE0BA1A9CE", }, }, - TestEnv(), + None, "0x51e7c7508e76dca0", ), ( @@ -52,7 +45,7 @@ def __init__(self, base_fee: Optional[int] = None): "storage": {}, }, }, - TestEnv(), + None, "0x37c2dedbdea6b3af", ), ( @@ -64,14 +57,23 @@ def __init__(self, base_fee: Optional[int] = None): }, }, }, - TestEnv(), + None, "0x096122e88929baec", ), ], ) def test_calc_state_root( - t8n: TransitionTool, fork: str, alloc: Dict, env: TestEnv, hash: str + t8n: TransitionTool, + fork: str, + alloc: Dict, + base_fee: Union[int, None], + hash: str, ) -> None: + class TestEnv: + base_fee: Union[int, None] + + env = TestEnv() + env.base_fee = base_fee assert t8n.calc_state_root(env, alloc, fork).startswith(hash) From fb3275745c60d496c559fea8695ad79b073bd0f7 Mon Sep 17 00:00:00 2001 From: marioevz Date: Thu, 3 Nov 2022 16:18:58 -0600 Subject: [PATCH 9/9] Path join use in test --- tests/ethereum_test/test_filler.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/ethereum_test/test_filler.py b/tests/ethereum_test/test_filler.py index 780d0ac52da..ed26c2453da 100644 --- a/tests/ethereum_test/test_filler.py +++ b/tests/ethereum_test/test_filler.py @@ -392,7 +392,12 @@ def generator(_) -> Generator[BlockchainTest, None, None]: fixture = fill_test(t8n, b11r, generator, ["London"], "NoProof") with open( - "tests/ethereum_test/test_fixtures/blockchain_london_valid_filled.json" + os.path.join( + "tests", + "ethereum_test", + "test_fixtures", + "blockchain_london_valid_filled.json", + ) ) as f: expected = json.load(f) @@ -713,8 +718,12 @@ def generator(_) -> Generator[BlockchainTest, None, None]: fixture = fill_test(t8n, b11r, generator, ["London"], "NoProof") with open( - "tests/ethereum_test/test_fixtures/" - + "blockchain_london_invalid_filled.json" + os.path.join( + "tests", + "ethereum_test", + "test_fixtures", + "blockchain_london_invalid_filled.json", + ) ) as f: expected = json.load(f)