From 39e52e9a6d672cb8bd9636641c8c13e89ce60262 Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Tue, 14 Aug 2018 16:04:59 +0200 Subject: [PATCH 1/5] Enable Constantinople State tests --- .circleci/config.yml | 21 +++++++++++++++++++++ tests/json-fixtures/test_state.py | 13 ++++++++++++- tests/json-fixtures/test_transactions.py | 5 ++++- tox.ini | 4 +++- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f304262d43..e48d899e9c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -108,6 +108,12 @@ jobs: - image: circleci/python:3.5 environment: TOXENV: py35-native-state-byzantium + py35-native-state-constantinople: + <<: *common + docker: + - image: circleci/python:3.5 + environment: + TOXENV: py35-native-state-constantinople py35-native-state-frontier: <<: *common docker: @@ -175,6 +181,12 @@ jobs: - image: circleci/python:3.6 environment: TOXENV: py36-native-state-byzantium + py36-native-state-constantinople: + <<: *common + docker: + - image: circleci/python:3.6 + environment: + TOXENV: py36-native-state-constantinople py36-native-state-frontier: <<: *common docker: @@ -205,6 +217,12 @@ jobs: - image: circleci/python:3.6 environment: TOXENV: py36-rpc-state-byzantium + py36-rpc-state-constantinople: + <<: *common + docker: + - image: circleci/python:3.6 + environment: + TOXENV: py36-rpc-state-constantinople py36-rpc-state-frontier: <<: *common docker: @@ -340,11 +358,13 @@ workflows: - py37-beacon - py36-native-state-byzantium + - py36-native-state-constantinople - py36-native-state-frontier - py36-native-state-homestead - py36-native-state-eip150 - py36-native-state-eip158 - py36-rpc-state-byzantium + - py36-rpc-state-constantinople - py36-rpc-state-frontier - py36-rpc-state-homestead - py36-rpc-state-eip150 @@ -364,6 +384,7 @@ workflows: - py36-beacon - py35-native-state-byzantium + - py35-native-state-constantinople - py35-native-state-frontier - py35-native-state-homestead - py35-native-state-eip150 diff --git a/tests/json-fixtures/test_state.py b/tests/json-fixtures/test_state.py index bac660cfca..a57198bb6f 100644 --- a/tests/json-fixtures/test_state.py +++ b/tests/json-fixtures/test_state.py @@ -28,12 +28,14 @@ HomesteadVM, SpuriousDragonVM, ByzantiumVM, + ConstantinopleVM, ) 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.vm.forks.constantinople.state import ConstantinopleState from eth.rlp.headers import ( BlockHeader, @@ -245,6 +247,10 @@ def get_prev_hashes_testing(self, last_block_hash, db): __name__='ByzantiumStateForTesting', get_ancestor_hash=get_block_hash_for_testing, ) +ConstantinopleStateForTesting = ConstantinopleState.configure( + __name__='ConstantinopleStateForTesting', + get_ancestor_hash=get_block_hash_for_testing, +) FrontierVMForTesting = FrontierVM.configure( __name__='FrontierVMForTesting', @@ -271,6 +277,11 @@ def get_prev_hashes_testing(self, last_block_hash, db): _state_class=ByzantiumStateForTesting, get_prev_hashes=get_prev_hashes_testing, ) +ConstantinopleVMForTesting = ConstantinopleVM.configure( + __name__='ConstantinopleVMForTesting', + _state_class=ConstantinopleStateForTesting, + get_prev_hashes=get_prev_hashes_testing, +) @pytest.fixture @@ -287,7 +298,7 @@ def fixture_vm_class(fixture_data): elif fork_name == ForkName.Byzantium: return ByzantiumVMForTesting elif fork_name == ForkName.Constantinople: - pytest.skip("Constantinople VM has not been implemented") + return ConstantinopleVMForTesting elif fork_name == ForkName.Metropolis: pytest.skip("Metropolis VM has not been implemented") else: diff --git a/tests/json-fixtures/test_transactions.py b/tests/json-fixtures/test_transactions.py index 26d7a18395..3051bb2cdc 100644 --- a/tests/json-fixtures/test_transactions.py +++ b/tests/json-fixtures/test_transactions.py @@ -28,6 +28,9 @@ from eth.vm.forks.byzantium.transactions import ( ByzantiumTransaction ) +from eth.vm.forks.constantinople.transactions import ( + ConstantinopleTransaction +) from eth_typing.enums import ( ForkName @@ -92,7 +95,7 @@ def fixture_transaction_class(fixture_data): elif fork_name == ForkName.Byzantium: return ByzantiumTransaction elif fork_name == ForkName.Constantinople: - pytest.skip("Constantinople Transaction class has not been implemented") + return ConstantinopleTransaction elif fork_name == ForkName.Metropolis: pytest.skip("Metropolis Transaction class has not been implemented") else: diff --git a/tox.ini b/tox.ini index 86e48878c8..e84b3d86c4 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ envlist= py{35,36}-{core,database,transactions,vm,native-blockchain} py{36}-{benchmark,p2p,trinity,lightchain_integration,beacon} py{36}-rpc-blockchain - py{36}-rpc-state-{frontier,homestead,eip150,eip158,byzantium,quadratic} + py{36}-rpc-state-{frontier,homestead,eip150,eip158,byzantium,constantinople,quadratic} py{35,36}-native-state-{frontier,homestead,eip150,eip158,byzantium,constantinople,metropolis} py37-{core,trinity,trinity-integration,beacon} py{35,36}-lint @@ -32,6 +32,8 @@ commands= beacon: pytest {posargs:tests/beacon/} # The following test seems to consume a lot of memory. Restricting to 3 processes reduces crashes rpc-state-byzantium: pytest -n3 {posargs:tests/trinity/json-fixtures-over-rpc/test_rpc_fixtures.py -k 'GeneralStateTests and not stQuadraticComplexityTest and Byzantium'} + # Uncomment the next line + modify test_rpc_fixtures.py when Constantinople is included in the mainnet config + # rpc-state-constantinople: pytest -n3 {posargs:tests/trinity/json-fixtures-over-rpc/test_rpc_fixtures.py -k 'GeneralStateTests and not stQuadraticComplexityTest and Constantinople'} 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} From 04ac2a594b6d3b5a9f989008e0797287d5efd646 Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Tue, 20 Nov 2018 15:20:42 +0100 Subject: [PATCH 2/5] Upgrade tests to v6.0.0-beta.2 --- fixtures | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixtures b/fixtures index 95a3092038..420f443477 160000 --- a/fixtures +++ b/fixtures @@ -1 +1 @@ -Subproject commit 95a309203890e6244c6d4353ca411671973c13b5 +Subproject commit 420f443477caa8516f1f9ee8122fafc3415c0f34 From 010b840d533fc342154322730acbbcae5c0c4a40 Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Mon, 10 Dec 2018 14:22:33 -0700 Subject: [PATCH 3/5] Fix some failing tests --- eth/__init__.py | 2 +- eth/vm/logic/system.py | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/eth/__init__.py b/eth/__init__.py index 21a35c0c6b..0da2b8e042 100644 --- a/eth/__init__.py +++ b/eth/__init__.py @@ -21,7 +21,7 @@ # # Ensure we can reach 1024 frames of recursion # -EVM_RECURSION_LIMIT = 1024 * 10 +EVM_RECURSION_LIMIT = 1024 * 12 sys.setrecursionlimit(max(EVM_RECURSION_LIMIT, sys.getrecursionlimit())) diff --git a/eth/vm/logic/system.py b/eth/vm/logic/system.py index 7852e046ee..bb75c5f723 100644 --- a/eth/vm/logic/system.py +++ b/eth/vm/logic/system.py @@ -20,12 +20,9 @@ ceil32, ) from eth.vm import mnemonics -from eth.vm.computation import ( - BaseComputation -) -from eth.vm.opcode import ( - Opcode, -) +from eth.vm.computation import BaseComputation +from eth.vm.message import Message +from eth.vm.opcode import Opcode from .call import max_child_gas_eip150 @@ -193,13 +190,16 @@ def __call__(self, computation: BaseComputation) -> None: code=call_data, create_address=contract_address, ) + self.apply_create_message(computation, child_msg) + def apply_create_message(self, computation: BaseComputation, child_msg: Message) -> None: child_computation = computation.apply_child_computation(child_msg) if child_computation.is_error: computation.stack_push(0) else: - computation.stack_push(contract_address) + computation.stack_push(child_msg.storage_address) + computation.return_gas(child_computation.get_gas_remaining()) @@ -240,3 +240,22 @@ def generate_contract_address(self, stack_data.salt, call_data ) + + def apply_create_message(self, computation: BaseComputation, child_msg: Message) -> None: + # We need to ensure that creation operates on empty storage **and** + # that if the initialization code fails that we revert the account back + # to its original state root. + snapshot = computation.state.snapshot() + + computation.state.account_db.delete_storage(child_msg.storage_address) + + child_computation = computation.apply_child_computation(child_msg) + + if child_computation.is_error: + computation.state.revert(snapshot) + computation.stack_push(0) + else: + computation.state.commit(snapshot) + computation.stack_push(child_msg.storage_address) + + computation.return_gas(child_computation.get_gas_remaining()) From 01176045a12241a5fbe0749bb252bd682fc2e7c7 Mon Sep 17 00:00:00 2001 From: Noel Maersk Date: Fri, 7 Dec 2018 22:11:19 +0200 Subject: [PATCH 4/5] misc: fix up test harness. 2 COMMITS SQUASHED: fixtures: include missing Constantinople in helpers. Debugging CREATE2 using the full "Blockchain" tests in `fixtures` (they are disabled in `py-evm`, because they're slow and a duplication of "State" tests). A few definitions are missing - so add them. tests/conftest: fix VM-tracing log-to-file helper. Also move `import`s out of the helper, so they're not encountered by the interpreter on every invocation of the helper. --- eth/tools/fixtures/helpers.py | 5 +++++ tests/conftest.py | 7 +++++-- tests/json-fixtures/test_blockchain.py | 2 -- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/eth/tools/fixtures/helpers.py b/eth/tools/fixtures/helpers.py index 06c0c15b3d..0340f9e32e 100644 --- a/eth/tools/fixtures/helpers.py +++ b/eth/tools/fixtures/helpers.py @@ -40,6 +40,7 @@ BaseVM, ) from eth.vm.forks import ( + ConstantinopleVM, ByzantiumVM, TangerineWhistleVM, FrontierVM, @@ -123,6 +124,10 @@ def chain_vm_configuration(fixture: Dict[str, Any]) -> Iterable[Tuple[int, Type[ return ( (0, ByzantiumVM), ) + elif network == 'Constantinople': + return ( + (0, ConstantinopleVM), + ) elif network == 'FrontierToHomesteadAt5': HomesteadVM = BaseHomesteadVM.configure(support_dao_fork=False) return ( diff --git a/tests/conftest.py b/tests/conftest.py index e298dc4d39..4c439532e7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,10 +23,13 @@ # Uncomment this to have logs from tests written to a file. This is useful for # debugging when you need to dump the VM output from test runs. """ +import datetime +import logging +import os +from eth.tools.logging import TRACE_LEVEL_NUM + @pytest.yield_fixture(autouse=True) def _file_logging(request): - import datetime - import os logger = logging.getLogger('eth') diff --git a/tests/json-fixtures/test_blockchain.py b/tests/json-fixtures/test_blockchain.py index 1aa902890a..f5f9c7d28c 100644 --- a/tests/json-fixtures/test_blockchain.py +++ b/tests/json-fixtures/test_blockchain.py @@ -84,8 +84,6 @@ def fixture(fixture_data): fixture_key, normalize_blockchain_fixtures, ) - if fixture['network'] == 'Constantinople': - pytest.skip('Constantinople VM rules not yet supported') return fixture From d2d119d47c21a074a41369fc8cecf4c425997670 Mon Sep 17 00:00:00 2001 From: Noel Maersk Date: Wed, 12 Dec 2018 01:52:04 +0200 Subject: [PATCH 5/5] tests: add more tests to INCORRECT_UPSTREAM_TESTS. One is existing `RevertInCreateInInit`, but now for Constantinople, not just Byzantium. The other is `RevertInCreateInInitCreate2`, which contains the same "synthhetic" state which can't be arrived at by regular means in the EVM. It's likely a copy-paste atavism. --- tests/json-fixtures/test_blockchain.py | 5 +++++ tests/json-fixtures/test_state.py | 1 + 2 files changed, 6 insertions(+) diff --git a/tests/json-fixtures/test_blockchain.py b/tests/json-fixtures/test_blockchain.py index f5f9c7d28c..5d03c8a3dc 100644 --- a/tests/json-fixtures/test_blockchain.py +++ b/tests/json-fixtures/test_blockchain.py @@ -45,6 +45,11 @@ # The result is in conflict with the yellow-paper: # * https://github.com/ethereum/py-evm/pull/1224#issuecomment-418800369 ('GeneralStateTests/stRevertTest/RevertInCreateInInit_d0g0v0.json', 'RevertInCreateInInit_d0g0v0_Byzantium'), # noqa: E501 + ('GeneralStateTests/stRevertTest/RevertInCreateInInit_d0g0v0.json', 'RevertInCreateInInit_d0g0v0_Constantinople'), # noqa: E501 + # The CREATE2 variant seems to have been derived from the one above - it, too, + # has a "synthetic" state, on which py-evm flips. + # * https://github.com/ethereum/py-evm/pull/1181#issuecomment-446330609 + ('GeneralStateTests/stCreate2/RevertInCreateInInitCreate2_d0g0v0.json', 'RevertInCreateInInitCreate2_d0g0v0_Constantinople'), # noqa: E501 } diff --git a/tests/json-fixtures/test_state.py b/tests/json-fixtures/test_state.py index a57198bb6f..18b246922b 100644 --- a/tests/json-fixtures/test_state.py +++ b/tests/json-fixtures/test_state.py @@ -146,6 +146,7 @@ def expand_fixtures_forks(all_fixtures): # 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), + ('stRevertTest/RevertInCreateInInit.json', 'RevertInCreateInInit', 'Constantinople', 0), }