Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable state tests for Constantinople #1181

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion eth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()))


Expand Down
5 changes: 5 additions & 0 deletions eth/tools/fixtures/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
BaseVM,
)
from eth.vm.forks import (
ConstantinopleVM,
ByzantiumVM,
TangerineWhistleVM,
FrontierVM,
Expand Down Expand Up @@ -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 (
Expand Down
33 changes: 26 additions & 7 deletions eth/vm/logic/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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())


Expand Down Expand Up @@ -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)
Copy link
Contributor

@veox veox Dec 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should a check for collisions be made first?..

EDIT: E.g., same as on line 010b840#diff-8b72e7215cd1bf65062b0a7071e3ded0R175

EDIT2: Seems like no; at least a naiive copy-paste didn't help here.


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())
2 changes: 1 addition & 1 deletion fixtures
Submodule fixtures updated 1040 files
7 changes: 5 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down
7 changes: 5 additions & 2 deletions tests/json-fixtures/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}


Expand Down Expand Up @@ -84,8 +89,6 @@ def fixture(fixture_data):
fixture_key,
normalize_blockchain_fixtures,
)
if fixture['network'] == 'Constantinople':
pytest.skip('Constantinople VM rules not yet supported')
return fixture


Expand Down
14 changes: 13 additions & 1 deletion tests/json-fixtures/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -144,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),
}


Expand Down Expand Up @@ -245,6 +248,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',
Expand All @@ -271,6 +278,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
Expand All @@ -287,7 +299,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:
Expand Down
5 changes: 4 additions & 1 deletion tests/json-fixtures/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down