diff --git a/.circleci/config.yml b/.circleci/config.yml index f304262d43..c6fc615ceb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -102,42 +102,42 @@ jobs: environment: TOXENV: py36-docs - py35-native-state-byzantium: + py35-native-blockchain-byzantium: <<: *common docker: - image: circleci/python:3.5 environment: - TOXENV: py35-native-state-byzantium - py35-native-state-frontier: + TOXENV: py35-native-blockchain-byzantium + py35-native-blockchain-frontier: <<: *common docker: - image: circleci/python:3.5 environment: - TOXENV: py35-native-state-frontier - py35-native-state-homestead: + TOXENV: py35-native-blockchain-frontier + py35-native-blockchain-homestead: <<: *common docker: - image: circleci/python:3.5 environment: - TOXENV: py35-native-state-homestead - py35-native-state-eip150: + TOXENV: py35-native-blockchain-homestead + py35-native-blockchain-eip150: <<: *common docker: - image: circleci/python:3.5 environment: - TOXENV: py35-native-state-eip150 - py35-native-state-eip158: + TOXENV: py35-native-blockchain-eip150 + py35-native-blockchain-eip158: <<: *common docker: - image: circleci/python:3.5 environment: - TOXENV: py35-native-state-eip158 - py35-native-blockchain: + TOXENV: py35-native-blockchain-eip158 + py35-native-blockchain-transition: <<: *common docker: - image: circleci/python:3.5 environment: - TOXENV: py35-native-blockchain + TOXENV: py35-native-blockchain-transition py35-vm: <<: *common docker: @@ -169,36 +169,42 @@ jobs: - image: circleci/python:3.6 environment: TOXENV: py36-benchmark - py36-native-state-byzantium: + py36-native-blockchain-byzantium: <<: *common docker: - image: circleci/python:3.6 environment: - TOXENV: py36-native-state-byzantium - py36-native-state-frontier: + TOXENV: py36-native-blockchain-byzantium + py36-native-blockchain-frontier: <<: *common docker: - image: circleci/python:3.6 environment: - TOXENV: py36-native-state-frontier - py36-native-state-homestead: + TOXENV: py36-native-blockchain-frontier + py36-native-blockchain-homestead: <<: *common docker: - image: circleci/python:3.6 environment: - TOXENV: py36-native-state-homestead - py36-native-state-eip150: + TOXENV: py36-native-blockchain-homestead + py36-native-blockchain-eip150: <<: *common docker: - image: circleci/python:3.6 environment: - TOXENV: py36-native-state-eip150 - py36-native-state-eip158: + TOXENV: py36-native-blockchain-eip150 + py36-native-blockchain-eip158: <<: *common docker: - image: circleci/python:3.6 environment: - TOXENV: py36-native-state-eip158 + TOXENV: py36-native-blockchain-eip158 + py36-native-blockchain-transition: + <<: *common + docker: + - image: circleci/python:3.6 + environment: + TOXENV: py36-native-blockchain-transition py36-rpc-state-byzantium: <<: *common docker: @@ -229,12 +235,6 @@ jobs: - image: circleci/python:3.6 environment: TOXENV: py36-rpc-state-eip158 - py36-native-blockchain: - <<: *common - docker: - - image: circleci/python:3.6 - environment: - TOXENV: py36-native-blockchain py36-rpc-blockchain: <<: *common docker: @@ -339,17 +339,17 @@ workflows: - py37-trinity-integration - py37-beacon - - py36-native-state-byzantium - - py36-native-state-frontier - - py36-native-state-homestead - - py36-native-state-eip150 - - py36-native-state-eip158 + - py36-native-blockchain-byzantium + - py36-native-blockchain-frontier + - py36-native-blockchain-homestead + - py36-native-blockchain-eip150 + - py36-native-blockchain-eip158 + - py36-native-blockchain-transition - py36-rpc-state-byzantium - py36-rpc-state-frontier - py36-rpc-state-homestead - py36-rpc-state-eip150 - py36-rpc-state-eip158 - - py36-native-blockchain - py36-rpc-blockchain - py36-vm - py36-benchmark @@ -363,12 +363,12 @@ workflows: - py36-rpc-state-quadratic - py36-beacon - - py35-native-state-byzantium - - py35-native-state-frontier - - py35-native-state-homestead - - py35-native-state-eip150 - - py35-native-state-eip158 - - py35-native-blockchain + - py35-native-blockchain-byzantium + - py35-native-blockchain-frontier + - py35-native-blockchain-homestead + - py35-native-blockchain-eip150 + - py35-native-blockchain-eip158 + - py35-native-blockchain-transition - py35-vm - py35-core - py35-transactions diff --git a/tests/json-fixtures/test_blockchain.py b/tests/json-fixtures/test_blockchain.py index f2effeff4c..5e914e9be2 100644 --- a/tests/json-fixtures/test_blockchain.py +++ b/tests/json-fixtures/test_blockchain.py @@ -3,6 +3,7 @@ import rlp from eth_utils import ( + to_tuple, ValidationError, ) @@ -24,6 +25,7 @@ genesis_params_from_fixture, load_fixture, new_chain_from_fixture, + should_run_slow_tests, verify_account_db, ) @@ -34,6 +36,84 @@ BASE_FIXTURE_PATH = os.path.join(ROOT_PROJECT_DIR, 'fixtures', 'BlockchainTests') +# These are the slowest tests from the full blockchain test run. This list +# should be regenerated occasionally using `--durations 100`. +SLOWEST_TESTS = { + ('GeneralStateTests/stStaticCall/static_Call50000_sha256_d0g0v0.json', 'static_Call50000_sha256_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_sha256_d1g0v0.json', 'static_Call50000_sha256_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_rip160_d0g0v0.json', 'static_Call50000_rip160_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_d1g0v0.json', 'static_Call50000_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_ecrec_d1g0v0.json', 'static_Call50000_ecrec_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_rip160_d1g0v0.json', 'static_Call50000_rip160_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_identity2_d1g0v0.json', 'static_Call50000_identity2_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_identity_d1g0v0.json', 'static_Call50000_identity_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Return50000_2_d0g0v0.json', 'static_Return50000_2_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_d0g0v0.json', 'static_Call50000_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000bytesContract50_1_d1g0v0.json', 'static_Call50000bytesContract50_1_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000bytesContract50_2_d1g0v0.json', 'static_Call50000bytesContract50_2_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stChangedEIP150/Call1024PreCalls_d0g0v0.json', 'Call1024PreCalls_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stChangedEIP150/Call1024PreCalls_d0g0v0.json', 'Call1024PreCalls_d0g0v0_EIP150'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/Call1024PreCalls_d0g0v0.json', 'Call1024PreCalls_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_ecrec_d0g0v0.json', 'static_Call50000_ecrec_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stAttackTest/ContractCreationSpam_d0g0v0.json', 'ContractCreationSpam_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stAttackTest/ContractCreationSpam_d0g0v0.json', 'ContractCreationSpam_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/Call1024PreCalls_d0g0v0.json', 'Call1024PreCalls_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call1024PreCalls2_d0g0v0.json', 'static_Call1024PreCalls2_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_identity2_d0g0v0.json', 'static_Call50000_identity2_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000_identity_d0g0v0.json', 'static_Call50000_identity_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stRecursiveCreate/recursiveCreateReturnValue_d0g0v0.json', 'recursiveCreateReturnValue_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_LoopCallsThenRevert_d0g0v0.json', 'static_LoopCallsThenRevert_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/Callcode1024OOG_d0g0v0.json', 'Callcode1024OOG_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_LoopCallsThenRevert_d0g1v0.json', 'static_LoopCallsThenRevert_d0g1v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call1024PreCalls3_d1g0v0.json', 'static_Call1024PreCalls3_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call1024PreCalls_d1g0v0.json', 'static_Call1024PreCalls_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call1024PreCalls2_d1g0v0.json', 'static_Call1024PreCalls2_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/Delegatecall1024OOG_d0g0v0.json', 'Delegatecall1024OOG_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stChangedEIP150/Call1024BalanceTooLow_d0g0v0.json', 'Call1024BalanceTooLow_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBombLog_d0g0v0.json', 'CallRecursiveBombLog_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stChangedEIP150/Callcode1024BalanceTooLow_d0g0v0.json', 'Callcode1024BalanceTooLow_d0g0v0_Byzantium'), # noqa: E501 + ('bcForkStressTest/ForkStressTest.json', 'ForkStressTest_Frontier'), # noqa: E501 + ('bcForkStressTest/ForkStressTest.json', 'ForkStressTest_Byzantium'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/Call1024OOG_d0g0v0.json', 'Call1024OOG_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/Call1024OOG_d0g0v0.json', 'Call1024OOG_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0.json', 'CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBombLog_d0g0v0.json', 'CallRecursiveBombLog_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb1_d0g0v0.json', 'CallRecursiveBomb1_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBombLog2_d0g0v0.json', 'CallRecursiveBombLog2_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0.json', 'CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/Call1024BalanceTooLow_d0g0v0.json', 'Call1024BalanceTooLow_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stChangedEIP150/Call1024BalanceTooLow_d0g0v0.json', 'Call1024BalanceTooLow_d0g0v0_EIP150'), # noqa: E501 + ('bcForkStressTest/ForkStressTest.json', 'ForkStressTest_EIP150'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/CallRecursiveBombPreCall_d0g0v0.json', 'CallRecursiveBombPreCall_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stChangedEIP150/Callcode1024BalanceTooLow_d0g0v0.json', 'Callcode1024BalanceTooLow_d0g0v0_EIP150'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb1_d0g0v0.json', 'CallRecursiveBomb1_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/CallRecursiveBombPreCall_d0g0v0.json', 'CallRecursiveBombPreCall_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb2_d0g0v0.json', 'CallRecursiveBomb2_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/Callcode1024BalanceTooLow_d0g0v0.json', 'Callcode1024BalanceTooLow_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/ABAcalls2_d0g0v0.json', 'ABAcalls2_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/Delegatecall1024_d0g0v0.json', 'Delegatecall1024_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBombLog2_d0g0v0.json', 'CallRecursiveBombLog2_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb2_d0g0v0.json', 'CallRecursiveBomb2_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0.json', 'CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_EIP150'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb0_d0g0v0.json', 'CallRecursiveBomb0_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/Call1024BalanceTooLow_d0g0v0.json', 'Call1024BalanceTooLow_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb0_d0g0v0.json', 'CallRecursiveBomb0_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000bytesContract50_1_d0g0v0.json', 'static_Call50000bytesContract50_1_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stDelegatecallTestHomestead/Delegatecall1024_d0g0v0.json', 'Delegatecall1024_d0g0v0_EIP150'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0.json', 'CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/CallRecursiveBombPreCall_d0g0v0.json', 'CallRecursiveBombPreCall_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/ABAcalls1_d0g0v0.json', 'ABAcalls1_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stCallCreateCallCodeTest/CallRecursiveBombPreCall_d0g0v0.json', 'CallRecursiveBombPreCall_d0g0v0_Frontier'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call1MB1024Calldepth_d1g0v0.json', 'static_Call1MB1024Calldepth_d1g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stRevertTest/LoopCallsDepthThenRevert2_d0g0v0.json', 'LoopCallsDepthThenRevert2_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stSystemOperationsTest/ABAcalls2_d0g0v0.json', 'ABAcalls2_d0g0v0_Homestead'), # noqa: E501 + ('GeneralStateTests/stStaticCall/static_Call50000bytesContract50_2_d0g0v0.json', 'static_Call50000bytesContract50_2_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stRevertTest/LoopCallsDepthThenRevert2_d0g0v0.json', 'LoopCallsDepthThenRevert2_d0g0v0_EIP158'), # noqa: E501 + ('GeneralStateTests/stRevertTest/LoopCallsDepthThenRevert3_d0g0v0.json', 'LoopCallsDepthThenRevert3_d0g0v0_EIP158'), # noqa: E501 + ('GeneralStateTests/stRevertTest/LoopCallsDepthThenRevert3_d0g0v0.json', 'LoopCallsDepthThenRevert3_d0g0v0_Byzantium'), # noqa: E501 +} + + # These are tests that are thought to be incorrect or buggy upstream, # at the commit currently checked out in submodule `fixtures`. # Ideally, this list should be empty. @@ -48,37 +128,60 @@ } -def blockchain_fixture_mark_fn(fixture_path, fixture_name): +def blockchain_fixture_mark_fn(fixture_path, fixture_name, fixture_fork): + fixture_id = (fixture_path, fixture_name) + if fixture_path.startswith('bcExploitTest'): return pytest.mark.skip("Exploit tests are slow") elif fixture_path == 'bcWalletTest/walletReorganizeOwners.json': return pytest.mark.skip("Wallet owner reorganization tests are slow") - elif (fixture_path, fixture_name) in INCORRECT_UPSTREAM_TESTS: + elif fixture_id in INCORRECT_UPSTREAM_TESTS: return pytest.mark.xfail(reason="Listed in INCORRECT_UPSTREAM_TESTS.") + elif 'stTransactionTest/zeroSigTransa' in fixture_path: + return pytest.mark.skip("EIP-86 not supported.") + elif fixture_id in SLOWEST_TESTS: + if should_run_slow_tests(): + return + else: + return pytest.mark.skip("Skipping slow test") + elif 'stQuadraticComplexityTest' in fixture_path: + return pytest.mark.skip("Skipping slow test") + + +def generate_ignore_fn_for_fork(passed_fork): + if passed_fork: + passed_fork = passed_fork.lower() + + def ignore_fn(fixture_path, fixture_key, fixture_fork): + return fixture_fork.lower() != passed_fork + + return ignore_fn -def blockchain_fixture_ignore_fn(fixture_path, fixture_name): - if fixture_path.startswith('GeneralStateTests'): - # General state tests are also exported as blockchain tests. We - # skip them here so we don't run them twice - return True +@to_tuple +def expand_fixtures_forks(all_fixtures): + for fixture_path, fixture_key in all_fixtures: + fixture = load_fixture(fixture_path, fixture_key) + yield fixture_path, fixture_key, fixture['network'] def pytest_generate_tests(metafunc): + fork = metafunc.config.getoption('fork') generate_fixture_tests( metafunc=metafunc, base_fixture_path=BASE_FIXTURE_PATH, + preprocess_fn=expand_fixtures_forks, filter_fn=filter_fixtures( fixtures_base_dir=BASE_FIXTURE_PATH, mark_fn=blockchain_fixture_mark_fn, - ignore_fn=blockchain_fixture_ignore_fn, + ignore_fn=generate_ignore_fn_for_fork(fork) ), ) @pytest.fixture def fixture(fixture_data): - fixture_path, fixture_key = fixture_data + fixture_path, fixture_key, fixture_fork = fixture_data fixture = load_fixture( fixture_path, fixture_key, diff --git a/tests/json-fixtures/test_state.py b/tests/json-fixtures/test_state.py deleted file mode 100644 index bac660cfca..0000000000 --- a/tests/json-fixtures/test_state.py +++ /dev/null @@ -1,408 +0,0 @@ -import logging -import os - -import pytest - -from eth_keys import keys - -from eth_utils import ( - to_bytes, - to_tuple, - ValidationError, -) - -from eth_hash.auto import keccak - -from eth_typing.enums import ( - ForkName -) - - -from eth.db import ( - get_db_backend, -) -from eth.db.chain import ChainDB -from eth.vm.forks import ( - TangerineWhistleVM, - FrontierVM, - HomesteadVM, - SpuriousDragonVM, - ByzantiumVM, -) -from eth.vm.forks.tangerine_whistle.state import TangerineWhistleState -from eth.vm.forks.frontier.state import FrontierState -from eth.vm.forks.homestead.state import HomesteadState -from eth.vm.forks.spurious_dragon.state import SpuriousDragonState -from eth.vm.forks.byzantium.state import ByzantiumState - -from eth.rlp.headers import ( - BlockHeader, -) -from eth.tools._utils.hashing import ( - hash_log_entries, -) -from eth.tools.fixtures import ( - filter_fixtures, - generate_fixture_tests, - load_fixture, - normalize_statetest_fixture, - should_run_slow_tests, -) -from eth.utils.db import ( - apply_state_dict, -) - - -ROOT_PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) - - -BASE_FIXTURE_PATH = os.path.join(ROOT_PROJECT_DIR, 'fixtures', 'GeneralStateTests') - - -logger = logging.getLogger('eth.tests.fixtures.GeneralStateTests') - - -@to_tuple -def expand_fixtures_forks(all_fixtures): - """ - The statetest fixtures have different definitions for each fork and must be - expanded one step further to have one fixture for each defined fork within - the fixture. - """ - - for fixture_path, fixture_key in all_fixtures: - fixture = load_fixture(fixture_path, fixture_key) - for fixture_fork, post_states in sorted(fixture['post'].items()): - for post_state_index in range(len(post_states)): - yield fixture_path, fixture_key, fixture_fork, post_state_index - - -# These are the slowest 50 tests from the full statetest run. This list should -# be regenerated occasionally using `--durations 50`. -SLOWEST_TESTS = { - ('stStaticCall/static_Call50000_sha256.json', 'static_Call50000_sha256', 'Byzantium', 0), - ('stStaticCall/static_Call50000_rip160.json', 'static_Call50000_rip160', 'Byzantium', 0), - ('stStaticCall/static_Call50000_sha256.json', 'static_Call50000_sha256', 'Byzantium', 1), - ('stStaticCall/static_Call50000.json', 'static_Call50000', 'Byzantium', 1), - ('stStaticCall/static_Call50000_ecrec.json', 'static_Call50000_ecrec', 'Byzantium', 1), - ('stStaticCall/static_Call50000_rip160.json', 'static_Call50000_rip160', 'Byzantium', 1), - ('stStaticCall/static_LoopCallsThenRevert.json', 'static_LoopCallsThenRevert', 'Byzantium', 0), - ('stStaticCall/static_Call50000_identity2.json', 'static_Call50000_identity2', 'Byzantium', 1), - ('stStaticCall/static_Call50000_identity.json', 'static_Call50000_identity', 'Byzantium', 1), - ('stStaticCall/static_Return50000_2.json', 'static_Return50000_2', 'Byzantium', 0), - ('stCallCreateCallCodeTest/Call1024PreCalls.json', 'Call1024PreCalls', 'Byzantium', 0), - ('stChangedEIP150/Call1024PreCalls.json', 'Call1024PreCalls', 'Byzantium', 0), - ('stDelegatecallTestHomestead/Call1024PreCalls.json', 'Call1024PreCalls', 'Byzantium', 0), - ('stStaticCall/static_Call50000.json', 'static_Call50000', 'Byzantium', 0), - ('stStaticCall/static_Call50000_ecrec.json', 'static_Call50000_ecrec', 'Byzantium', 0), - ('stStaticCall/static_Call1024PreCalls2.json', 'static_Call1024PreCalls2', 'Byzantium', 0), - ('stStaticCall/static_Call50000_identity.json', 'static_Call50000_identity', 'Byzantium', 0), - ('stStaticCall/static_Call50000_identity2.json', 'static_Call50000_identity2', 'Byzantium', 0), - ('stStaticCall/static_LoopCallsThenRevert.json', 'static_LoopCallsThenRevert', 'Byzantium', 1), - ('stCallCreateCallCodeTest/Call1024BalanceTooLow.json', 'Call1024BalanceTooLow', 'Byzantium', 0), # noqa: E501 - ('stChangedEIP150/Call1024BalanceTooLow.json', 'Call1024BalanceTooLow', 'Byzantium', 0), - ('stCallCreateCallCodeTest/Callcode1024BalanceTooLow.json', 'Callcode1024BalanceTooLow', 'Byzantium', 0), # noqa: E501 - ('stChangedEIP150/Callcode1024BalanceTooLow.json', 'Callcode1024BalanceTooLow', 'Byzantium', 0), # noqa: E501 - ('stSystemOperationsTest/CallRecursiveBomb0_OOG_atMaxCallDepth.json', 'CallRecursiveBomb0_OOG_atMaxCallDepth', 'Byzantium', 0), # noqa: E501 - ('stRevertTest/LoopCallsDepthThenRevert2.json', 'LoopCallsDepthThenRevert2', 'Byzantium', 0), - ('stRevertTest/LoopCallsDepthThenRevert3.json', 'LoopCallsDepthThenRevert3', 'Byzantium', 0), - ('stDelegatecallTestHomestead/CallRecursiveBombPreCall.json', 'CallRecursiveBombPreCall', 'Byzantium', 0), # noqa: E501 - ('stRevertTest/LoopCallsThenRevert.json', 'LoopCallsThenRevert', 'Byzantium', 0), - ('stCallCreateCallCodeTest/CallRecursiveBombPreCall.json', 'CallRecursiveBombPreCall', 'Byzantium', 0), # noqa: E501 - ('stStaticCall/static_Call50000bytesContract50_1.json', 'static_Call50000bytesContract50_1', 'Byzantium', 1), # noqa: E501 - ('stStaticCall/static_Call1024PreCalls.json', 'static_Call1024PreCalls', 'Byzantium', 1), - ('stDelegatecallTestHomestead/Call1024BalanceTooLow.json', 'Call1024BalanceTooLow', 'Byzantium', 0), # noqa: E501 - ('stDelegatecallTestHomestead/Delegatecall1024.json', 'Delegatecall1024', 'Byzantium', 0), - ('stRevertTest/LoopCallsThenRevert.json', 'LoopCallsThenRevert', 'Byzantium', 1), - ('stStaticCall/static_Call50000bytesContract50_2.json', 'static_Call50000bytesContract50_2', 'Byzantium', 1), # noqa: E501 - ('stStaticCall/static_Call1024PreCalls2.json', 'static_Call1024PreCalls2', 'Byzantium', 1), - ('stRandom/randomStatetest636.json', 'randomStatetest636', 'Byzantium', 0), - ('stStaticCall/static_Call1024PreCalls3.json', 'static_Call1024PreCalls3', 'Byzantium', 1), - ('stRandom/randomStatetest467.json', 'randomStatetest467', 'Byzantium', 0), - ('stRandom/randomStatetest458.json', 'randomStatetest458', 'Byzantium', 0), - ('stRandom/randomStatetest150.json', 'randomStatetest150', 'Byzantium', 0), - ('stRandom/randomStatetest639.json', 'randomStatetest639', 'Byzantium', 0), - ('stStaticCall/static_LoopCallsDepthThenRevert2.json', 'static_LoopCallsDepthThenRevert2', 'Byzantium', 0), # noqa: E501 - ('stRandom/randomStatetest154.json', 'randomStatetest154', 'Byzantium', 0), - ('stRecursiveCreate/recursiveCreateReturnValue.json', 'recursiveCreateReturnValue', 'Byzantium', 0), # noqa: E501 - ('stStaticCall/static_LoopCallsDepthThenRevert3.json', 'static_LoopCallsDepthThenRevert3', 'Byzantium', 0), # noqa: E501 - ('stSystemOperationsTest/ABAcalls1.json', 'ABAcalls1', 'Byzantium', 0), - ('stSpecialTest/failed_tx_xcf416c53.json', 'failed_tx_xcf416c53', 'Byzantium', 0), - ('stRandom/randomStatetest159.json', 'randomStatetest159', 'Byzantium', 0), - ('stRandom/randomStatetest554.json', 'randomStatetest554', 'Byzantium', 0), -} - - -# These are tests that are thought to be incorrect or buggy upstream, -# at the commit currently checked out in submodule `fixtures`. -# Ideally, this list should be empty. -# WHEN ADDING ENTRIES, ALWAYS PROVIDE AN EXPLANATION! -INCORRECT_UPSTREAM_TESTS = { - # The test considers a "synthetic" scenario (the state described there can't - # be arrived at using regular consensus rules). - # * https://github.com/ethereum/py-evm/pull/1224#issuecomment-418775512 - # The result is in conflict with the yellow-paper: - # * https://github.com/ethereum/py-evm/pull/1224#issuecomment-418800369 - ('stRevertTest/RevertInCreateInInit.json', 'RevertInCreateInInit', 'Byzantium', 0), -} - - -def mark_statetest_fixtures(fixture_path, fixture_key, fixture_fork, fixture_index): - fixture_id = (fixture_path, fixture_key, fixture_fork, fixture_index) - if fixture_path.startswith('stTransactionTest/zeroSigTransa'): - return pytest.mark.skip("EIP-86 not supported.") - elif fixture_id in SLOWEST_TESTS: - if should_run_slow_tests(): - return - else: - return pytest.mark.skip("Skipping slow test") - elif fixture_path.startswith('stQuadraticComplexityTest'): - return pytest.mark.skip("Skipping slow test") - elif fixture_id in INCORRECT_UPSTREAM_TESTS: - return pytest.mark.xfail(reason="Listed in INCORRECT_UPSTREAM_TESTS.") - - -def generate_ignore_fn_for_fork(metafunc): - """ - The statetest fixtures have different definitions for each fork and we must ensure to only run - test against against the intended fork (e.g run Constantinople state tests against - Constantinople VM). - We can not rely on `pytest -k` matching for that as that matches against an identification - string that includes the path and name of the test which in some cases also contains fork - fork names. A test file may be named "ConstantinopleSomething.json" but still contains - individual definitions per fork. - """ - passed_fork = metafunc.config.getoption('fork') - if passed_fork: - passed_fork = passed_fork.lower() - - def ignore_fn(fixture_path, fixture_key, fixture_fork, post_state_index): - return fixture_fork.lower() != passed_fork - - return ignore_fn - - -def pytest_generate_tests(metafunc): - generate_fixture_tests( - metafunc=metafunc, - base_fixture_path=BASE_FIXTURE_PATH, - preprocess_fn=expand_fixtures_forks, - filter_fn=filter_fixtures( - ignore_fn=generate_ignore_fn_for_fork(metafunc), - fixtures_base_dir=BASE_FIXTURE_PATH, - mark_fn=mark_statetest_fixtures, - ), - ) - - -@pytest.fixture -def fixture(fixture_data): - fixture_path, fixture_key, fixture_fork, post_state_index = fixture_data - fixture = load_fixture( - fixture_path, - fixture_key, - normalize_statetest_fixture(fork=fixture_fork, post_state_index=post_state_index), - ) - return fixture - - -# -# Test Chain Setup -# -def get_block_hash_for_testing(self, block_number): - if block_number >= self.block_number: - return b'' - elif block_number < 0: - return b'' - elif block_number < self.block_number - 256: - return b'' - else: - return keccak(to_bytes(text="{0}".format(block_number))) - - -def get_prev_hashes_testing(self, last_block_hash, db): - prev_hashes = [] - return prev_hashes - - -FrontierStateForTesting = FrontierState.configure( - __name__='FrontierStateForTesting', - get_ancestor_hash=get_block_hash_for_testing, -) -HomesteadStateForTesting = HomesteadState.configure( - __name__='HomesteadStateForTesting', - get_ancestor_hash=get_block_hash_for_testing, -) -TangerineWhistleStateForTesting = TangerineWhistleState.configure( - __name__='TangerineWhistleStateForTesting', - get_ancestor_hash=get_block_hash_for_testing, -) -SpuriousDragonStateForTesting = SpuriousDragonState.configure( - __name__='SpuriousDragonStateForTesting', - get_ancestor_hash=get_block_hash_for_testing, -) -ByzantiumStateForTesting = ByzantiumState.configure( - __name__='ByzantiumStateForTesting', - get_ancestor_hash=get_block_hash_for_testing, -) - -FrontierVMForTesting = FrontierVM.configure( - __name__='FrontierVMForTesting', - _state_class=FrontierStateForTesting, - get_prev_hashes=get_prev_hashes_testing, -) -HomesteadVMForTesting = HomesteadVM.configure( - __name__='HomesteadVMForTesting', - _state_class=HomesteadStateForTesting, - get_prev_hashes=get_prev_hashes_testing, -) -TangerineWhistleVMForTesting = TangerineWhistleVM.configure( - __name__='TangerineWhistleVMForTesting', - _state_class=TangerineWhistleStateForTesting, - get_prev_hashes=get_prev_hashes_testing, -) -SpuriousDragonVMForTesting = SpuriousDragonVM.configure( - __name__='SpuriousDragonVMForTesting', - _state_class=SpuriousDragonStateForTesting, - get_prev_hashes=get_prev_hashes_testing, -) -ByzantiumVMForTesting = ByzantiumVM.configure( - __name__='ByzantiumVMForTesting', - _state_class=ByzantiumStateForTesting, - get_prev_hashes=get_prev_hashes_testing, -) - - -@pytest.fixture -def fixture_vm_class(fixture_data): - _, _, fork_name, _ = fixture_data - if fork_name == ForkName.Frontier: - return FrontierVMForTesting - elif fork_name == ForkName.Homestead: - return HomesteadVMForTesting - elif fork_name == ForkName.EIP150: - return TangerineWhistleVMForTesting - elif fork_name == ForkName.EIP158: - return SpuriousDragonVMForTesting - elif fork_name == ForkName.Byzantium: - return ByzantiumVMForTesting - elif fork_name == ForkName.Constantinople: - pytest.skip("Constantinople VM has not been implemented") - elif fork_name == ForkName.Metropolis: - pytest.skip("Metropolis VM has not been implemented") - else: - raise ValueError("Unknown Fork Name: {0}".format(fork_name)) - - -PRE_STATE_CLEARING_VMS = ( - FrontierVMForTesting, - HomesteadVMForTesting, - TangerineWhistleVMForTesting, -) - - -def test_state_fixtures(fixture, fixture_vm_class): - header = BlockHeader( - coinbase=fixture['env']['currentCoinbase'], - difficulty=fixture['env']['currentDifficulty'], - block_number=fixture['env']['currentNumber'], - gas_limit=fixture['env']['currentGasLimit'], - timestamp=fixture['env']['currentTimestamp'], - parent_hash=fixture['env']['previousHash'], - ) - - chaindb = ChainDB(get_db_backend()) - vm = fixture_vm_class(header=header, chaindb=chaindb) - - state = vm.state - apply_state_dict(state.account_db, fixture['pre']) - state.account_db.persist() - - # Update state_root manually - vm.block = vm.block.copy(header=vm.block.header.copy(state_root=state.state_root)) - if 'secretKey' in fixture['transaction']: - unsigned_transaction = vm.create_unsigned_transaction( - nonce=fixture['transaction']['nonce'], - gas_price=fixture['transaction']['gasPrice'], - gas=fixture['transaction']['gasLimit'], - to=fixture['transaction']['to'], - value=fixture['transaction']['value'], - data=fixture['transaction']['data'], - ) - private_key = keys.PrivateKey(fixture['transaction']['secretKey']) - transaction = unsigned_transaction.as_signed_transaction(private_key=private_key) - elif 'vrs' in fixture['transaction']: - v, r, s = ( - fixture['transaction']['v'], - fixture['transaction']['r'], - fixture['transaction']['s'], - ) - transaction = vm.create_transaction( - nonce=fixture['transaction']['nonce'], - gas_price=fixture['transaction']['gasPrice'], - gas=fixture['transaction']['gasLimit'], - to=fixture['transaction']['to'], - value=fixture['transaction']['value'], - data=fixture['transaction']['data'], - v=v, - r=r, - s=s, - ) - else: - raise Exception("Invariant: No transaction specified") - - try: - header, receipt, computation = vm.apply_transaction(vm.block.header, transaction) - except ValidationError as err: - logger.warning("Got transaction error", exc_info=True) - transaction_error = err - else: - transaction_error = False - - transactions = vm.block.transactions + (transaction, ) - receipts = vm.block.get_receipts(chaindb) + (receipt, ) - vm.block = vm.set_block_transactions(vm.block, header, transactions, receipts) - finally: - # This is necessary due to the manner in which the state tests are - # generated. State tests are generated from the BlockChainTest tests - # in which these transactions are included in the larger context of a - # block and thus, the mechanisms which would touch/create/clear the - # coinbase account based on the mining reward are present during test - # generation, but not part of the execution, thus we must artificially - # create the account in VMs prior to the state clearing rules, - # as well as conditionally cleaning up the coinbase account when left - # empty in VMs after the state clearing rules came into effect. - # Related change in geth: - # https://github.com/ethereum/go-ethereum/commit/32f28a9360d26a661d55915915f12fd3c70f012b#diff-f53696be8527ac422b8d4de7c8e945c1R149 # noqa: E501 - - if isinstance(vm, PRE_STATE_CLEARING_VMS): - state.account_db.touch_account(vm.block.header.coinbase) - state.account_db.persist() - vm.block = vm.block.copy(header=vm.block.header.copy(state_root=state.state_root)) - elif state.account_db.account_is_empty(vm.block.header.coinbase): - state.account_db.delete_account(vm.block.header.coinbase) - state.account_db.persist() - vm.block = vm.block.copy(header=vm.block.header.copy(state_root=state.state_root)) - - block = vm.block - - if not transaction_error: - log_entries = computation.get_log_entries() - actual_logs_hash = hash_log_entries(log_entries) - if 'logs' in fixture['post']: - expected_logs_hash = fixture['post']['logs'] - assert expected_logs_hash == actual_logs_hash - elif log_entries: - raise AssertionError("Got log {0} entries. hash:{1}".format( - len(log_entries), - actual_logs_hash, - )) - - if 'out' in fixture: - expected_output = fixture['out'] - if isinstance(expected_output, int): - assert len(computation.output) == expected_output - else: - assert computation.output == expected_output - - assert block.header.state_root == fixture['post']['hash'] diff --git a/tox.ini b/tox.ini index 86e48878c8..392867c3f2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,10 @@ [tox] envlist= - py{35,36}-{core,database,transactions,vm,native-blockchain} + py{35,36}-{core,database,transactions,vm} py{36}-{benchmark,p2p,trinity,lightchain_integration,beacon} py{36}-rpc-blockchain py{36}-rpc-state-{frontier,homestead,eip150,eip158,byzantium,quadratic} - py{35,36}-native-state-{frontier,homestead,eip150,eip158,byzantium,constantinople,metropolis} + py{35,36}-native-blockchain-{frontier,homestead,eip150,eip158,byzantium,constantinople,metropolis,transition} py37-{core,trinity,trinity-integration,beacon} py{35,36}-lint py36-docs @@ -35,14 +35,14 @@ commands= rpc-state-quadratic: pytest {posargs:tests/trinity/json-fixtures-over-rpc/test_rpc_fixtures.py -k 'GeneralStateTests and stQuadraticComplexityTest'} transactions: pytest {posargs:tests/json-fixtures/test_transactions.py} vm: pytest {posargs:tests/json-fixtures/test_virtual_machine.py} - native-blockchain: pytest {posargs:tests/json-fixtures/test_blockchain.py} - native-state-frontier: pytest {posargs:tests/json-fixtures/test_state.py --fork Frontier} - native-state-homestead: pytest {posargs:tests/json-fixtures/test_state.py --fork Homestead} - native-state-eip150: pytest {posargs:tests/json-fixtures/test_state.py --fork EIP150} - native-state-eip158: pytest {posargs:tests/json-fixtures/test_state.py --fork EIP158} - native-state-byzantium: pytest {posargs:tests/json-fixtures/test_state.py --fork Byzantium} - native-state-constantinople: pytest {posargs:tests/json-fixtures/test_state.py --fork Constantinople} - native-state-metropolis: pytest {posargs:tests/json-fixtures/test_state.py --fork Metropolis} + native-blockchain-frontier: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork Frontier} + native-blockchain-homestead: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork Homestead} + native-blockchain-eip150: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork EIP150} + native-blockchain-eip158: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork EIP158} + native-blockchain-byzantium: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork Byzantium} + native-blockchain-constantinople: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork Constantinople} + native-blockchain-metropolis: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork Metropolis} + native-blockchain-transition: pytest {posargs:tests/json-fixtures/test_blockchain.py -k BlockchainTests/TransitionTests} lightchain_integration: pytest --integration {posargs:tests/trinity/integration/test_lightchain_integration.py} deps = .[p2p,trinity,eth-extra,test]