diff --git a/.circleci/config.yml b/.circleci/config.yml index a6e7b123a0..019f13f087 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -84,6 +84,12 @@ jobs: - image: circleci/python:3.5 environment: TOXENV: py35-native-blockchain-homestead + py35-native-blockchain-petersburg: + <<: *common + docker: + - image: circleci/python:3.5 + environment: + TOXENV: py35-native-blockchain-petersburg py35-native-blockchain-tangerine_whistle: <<: *common docker: @@ -157,6 +163,12 @@ jobs: - image: circleci/python:3.6 environment: TOXENV: py36-native-blockchain-homestead + py36-native-blockchain-petersburg: + <<: *common + docker: + - image: circleci/python:3.6 + environment: + TOXENV: py36-native-blockchain-petersburg py36-native-blockchain-tangerine_whistle: <<: *common docker: @@ -219,6 +231,7 @@ workflows: - py36-native-blockchain-constantinople - py36-native-blockchain-frontier - py36-native-blockchain-homestead + - py36-native-blockchain-petersburg - py36-native-blockchain-tangerine_whistle - py36-native-blockchain-spurious_dragon - py36-native-blockchain-transition @@ -232,6 +245,7 @@ workflows: - py35-native-blockchain-constantinople - py35-native-blockchain-frontier - py35-native-blockchain-homestead + - py35-native-blockchain-petersburg - py35-native-blockchain-tangerine_whistle - py35-native-blockchain-spurious_dragon - py35-native-blockchain-transition diff --git a/docs/release_notes/index.rst b/docs/release_notes/index.rst index eb1dd7778a..c093edffff 100644 --- a/docs/release_notes/index.rst +++ b/docs/release_notes/index.rst @@ -1,6 +1,12 @@ Release notes ============= +Unreleased (latest source) +-------------------------- + +- `#1719 `_: Implement and activate Petersburg fork (aka Constantinople fixed) + + 0.2.0-alpha.40 -------------- diff --git a/eth/chains/mainnet/__init__.py b/eth/chains/mainnet/__init__.py index 65246a7a30..76705e6964 100644 --- a/eth/chains/mainnet/__init__.py +++ b/eth/chains/mainnet/__init__.py @@ -13,7 +13,7 @@ from .constants import ( MAINNET_CHAIN_ID, BYZANTIUM_MAINNET_BLOCK, - CONSTANTINOPLE_MAINNET_BLOCK, + PETERSBURG_MAINNET_BLOCK, TANGERINE_WHISTLE_MAINNET_BLOCK, HOMESTEAD_MAINNET_BLOCK, SPURIOUS_DRAGON_MAINNET_BLOCK, @@ -29,9 +29,9 @@ from eth.vm.base import BaseVM # noqa: F401 from eth.vm.forks import ( ByzantiumVM, - ConstantinopleVM, FrontierVM, HomesteadVM, + PetersburgVM, SpuriousDragonVM, TangerineWhistleVM, ) @@ -80,7 +80,7 @@ class MainnetHomesteadVM(MainnetDAOValidatorVM): TANGERINE_WHISTLE_MAINNET_BLOCK, SPURIOUS_DRAGON_MAINNET_BLOCK, BYZANTIUM_MAINNET_BLOCK, - CONSTANTINOPLE_MAINNET_BLOCK, + PETERSBURG_MAINNET_BLOCK, ) MAINNET_VMS = ( FrontierVM, @@ -88,7 +88,7 @@ class MainnetHomesteadVM(MainnetDAOValidatorVM): TangerineWhistleVM, SpuriousDragonVM, ByzantiumVM, - ConstantinopleVM, + PetersburgVM, ) MAINNET_VM_CONFIGURATION = tuple(zip(MAINNET_FORK_BLOCKS, MAINNET_VMS)) diff --git a/eth/chains/mainnet/constants.py b/eth/chains/mainnet/constants.py index 933d12cd5d..669d895ca9 100644 --- a/eth/chains/mainnet/constants.py +++ b/eth/chains/mainnet/constants.py @@ -39,6 +39,6 @@ BYZANTIUM_MAINNET_BLOCK = BlockNumber(4370000) # -# Constantinople Block +# Petersburg Block # -CONSTANTINOPLE_MAINNET_BLOCK = BlockNumber(9876543210) +PETERSBURG_MAINNET_BLOCK = BlockNumber(7280000) diff --git a/eth/chains/ropsten/__init__.py b/eth/chains/ropsten/__init__.py index b07110b15a..bc376bcfe9 100644 --- a/eth/chains/ropsten/__init__.py +++ b/eth/chains/ropsten/__init__.py @@ -4,6 +4,7 @@ from .constants import ( BYZANTIUM_ROPSTEN_BLOCK, CONSTANTINOPLE_ROPSTEN_BLOCK, + PETERSBURG_ROPSTEN_BLOCK, ROPSTEN_CHAIN_ID, SPURIOUS_DRAGON_ROPSTEN_BLOCK, TANGERINE_WHISTLE_ROPSTEN_BLOCK, @@ -16,6 +17,7 @@ from eth.vm.forks import ( ByzantiumVM, ConstantinopleVM, + PetersburgVM, SpuriousDragonVM, TangerineWhistleVM, ) @@ -27,6 +29,7 @@ (SPURIOUS_DRAGON_ROPSTEN_BLOCK, SpuriousDragonVM), (BYZANTIUM_ROPSTEN_BLOCK, ByzantiumVM), (CONSTANTINOPLE_ROPSTEN_BLOCK, ConstantinopleVM), + (PETERSBURG_ROPSTEN_BLOCK, PetersburgVM), ) diff --git a/eth/chains/ropsten/constants.py b/eth/chains/ropsten/constants.py index dc6ffb4d66..9aac781416 100644 --- a/eth/chains/ropsten/constants.py +++ b/eth/chains/ropsten/constants.py @@ -40,3 +40,9 @@ # Constantinople # CONSTANTINOPLE_ROPSTEN_BLOCK = BlockNumber(4230000) + + +# +# Petersburg +# +PETERSBURG_ROPSTEN_BLOCK = BlockNumber(4939394) diff --git a/eth/tools/builder/chain/builders.py b/eth/tools/builder/chain/builders.py index de91deb213..bdda19d423 100644 --- a/eth/tools/builder/chain/builders.py +++ b/eth/tools/builder/chain/builders.py @@ -70,6 +70,7 @@ SpuriousDragonVM, ByzantiumVM, ConstantinopleVM, + PetersburgVM, ) @@ -225,7 +226,7 @@ def dao_fork_at(dao_fork_block_number: BlockNumber, spurious_dragon_at = fork_at(SpuriousDragonVM) byzantium_at = fork_at(ByzantiumVM) constantinople_at = fork_at(ConstantinopleVM) - +petersburg_at = fork_at(PetersburgVM) GENESIS_DEFAULTS = ( ('difficulty', 1), diff --git a/eth/tools/fixtures/helpers.py b/eth/tools/fixtures/helpers.py index 6acc48dac0..e9969502c4 100644 --- a/eth/tools/fixtures/helpers.py +++ b/eth/tools/fixtures/helpers.py @@ -43,6 +43,7 @@ BaseVM, ) from eth.vm.forks import ( + PetersburgVM, ConstantinopleVM, ByzantiumVM, TangerineWhistleVM, @@ -131,6 +132,10 @@ def chain_vm_configuration(fixture: Dict[str, Any]) -> Iterable[Tuple[int, Type[ return ( (0, ConstantinopleVM), ) + elif network == 'ConstantinopleFix': + return ( + (0, PetersburgVM), + ) elif network == 'FrontierToHomesteadAt5': HomesteadVM = BaseHomesteadVM.configure(support_dao_fork=False) return ( diff --git a/eth/vm/forks/__init__.py b/eth/vm/forks/__init__.py index 6332c13014..fcf57a8efe 100644 --- a/eth/vm/forks/__init__.py +++ b/eth/vm/forks/__init__.py @@ -16,3 +16,6 @@ from .constantinople import ( # noqa: F401 ConstantinopleVM, ) +from .petersburg import ( # noqa: F401 + PetersburgVM, +) diff --git a/eth/vm/forks/constantinople/computation.py b/eth/vm/forks/constantinople/computation.py index d4a3e1df0a..6938282470 100644 --- a/eth/vm/forks/constantinople/computation.py +++ b/eth/vm/forks/constantinople/computation.py @@ -1,7 +1,3 @@ -from eth_utils.toolz import ( - merge, -) - from eth.vm.forks.byzantium.computation import ( BYZANTIUM_PRECOMPILES ) @@ -15,12 +11,7 @@ from .opcodes import CONSTANTINOPLE_OPCODES -CONSTANTINOPLE_PRECOMPILES = merge( - BYZANTIUM_PRECOMPILES, - { - # TODO: add new precompiles - }, -) +CONSTANTINOPLE_PRECOMPILES = BYZANTIUM_PRECOMPILES class ConstantinopleComputation(ByzantiumComputation): diff --git a/eth/vm/forks/petersburg/__init__.py b/eth/vm/forks/petersburg/__init__.py new file mode 100644 index 0000000000..4ccb99fa76 --- /dev/null +++ b/eth/vm/forks/petersburg/__init__.py @@ -0,0 +1,38 @@ +from typing import ( # noqa: F401 + Type, +) + +from eth.rlp.blocks import BaseBlock # noqa: F401 +from eth.vm.forks.byzantium import ( + ByzantiumVM, + get_uncle_reward, +) +from eth.vm.state import BaseState # noqa: F401 + +from .blocks import PetersburgBlock +from .constants import EIP1234_BLOCK_REWARD +from .headers import ( + compute_petersburg_difficulty, + configure_petersburg_header, + create_petersburg_header_from_parent, +) +from .state import PetersburgState + + +class PetersburgVM(ByzantiumVM): + # fork name + fork = 'petersburg' + + # classes + block_class = PetersburgBlock # type: Type[BaseBlock] + _state_class = PetersburgState # type: Type[BaseState] + + # Methods + create_header_from_parent = staticmethod(create_petersburg_header_from_parent) # type: ignore # noqa: E501 + compute_difficulty = staticmethod(compute_petersburg_difficulty) # type: ignore + configure_header = configure_petersburg_header + get_uncle_reward = staticmethod(get_uncle_reward(EIP1234_BLOCK_REWARD)) + + @staticmethod + def get_block_reward() -> int: + return EIP1234_BLOCK_REWARD diff --git a/eth/vm/forks/petersburg/blocks.py b/eth/vm/forks/petersburg/blocks.py new file mode 100644 index 0000000000..cbd20eb92c --- /dev/null +++ b/eth/vm/forks/petersburg/blocks.py @@ -0,0 +1,22 @@ +from rlp.sedes import ( + CountableList, +) +from eth.rlp.headers import ( + BlockHeader, +) +from eth.vm.forks.byzantium.blocks import ( + ByzantiumBlock, +) + +from .transactions import ( + PetersburgTransaction, +) + + +class PetersburgBlock(ByzantiumBlock): + transaction_class = PetersburgTransaction + fields = [ + ('header', BlockHeader), + ('transactions', CountableList(transaction_class)), + ('uncles', CountableList(BlockHeader)) + ] diff --git a/eth/vm/forks/petersburg/computation.py b/eth/vm/forks/petersburg/computation.py new file mode 100644 index 0000000000..f555cfc8d6 --- /dev/null +++ b/eth/vm/forks/petersburg/computation.py @@ -0,0 +1,20 @@ +from eth.vm.forks.byzantium.computation import ( + BYZANTIUM_PRECOMPILES +) +from eth.vm.forks.byzantium.computation import ( + ByzantiumComputation +) + +from .opcodes import PETERSBURG_OPCODES + +PETERSBURG_PRECOMPILES = BYZANTIUM_PRECOMPILES + + +class PetersburgComputation(ByzantiumComputation): + """ + A class for all execution computations in the ``Petersburg`` fork. + Inherits from :class:`~eth.vm.forks.byzantium.computation.ByzantiumComputation` + """ + # Override + opcodes = PETERSBURG_OPCODES + _precompiles = PETERSBURG_PRECOMPILES diff --git a/eth/vm/forks/petersburg/constants.py b/eth/vm/forks/petersburg/constants.py new file mode 100644 index 0000000000..0ba9138d13 --- /dev/null +++ b/eth/vm/forks/petersburg/constants.py @@ -0,0 +1,6 @@ +from eth_utils import denoms + + +GAS_EXTCODEHASH_EIP1052 = 400 + +EIP1234_BLOCK_REWARD = 2 * denoms.ether diff --git a/eth/vm/forks/petersburg/headers.py b/eth/vm/forks/petersburg/headers.py new file mode 100644 index 0000000000..dbd88fad81 --- /dev/null +++ b/eth/vm/forks/petersburg/headers.py @@ -0,0 +1,13 @@ +from eth.vm.forks.byzantium.headers import ( + configure_header, + create_header_from_parent, + compute_difficulty, +) + + +compute_petersburg_difficulty = compute_difficulty(5000000) + +create_petersburg_header_from_parent = create_header_from_parent( + compute_petersburg_difficulty +) +configure_petersburg_header = configure_header(compute_petersburg_difficulty) diff --git a/eth/vm/forks/petersburg/opcodes.py b/eth/vm/forks/petersburg/opcodes.py new file mode 100644 index 0000000000..b591eab9c6 --- /dev/null +++ b/eth/vm/forks/petersburg/opcodes.py @@ -0,0 +1,60 @@ +import copy +from eth_utils.toolz import ( + merge +) + +from eth import ( + constants +) +from eth.vm import ( + mnemonics, + opcode_values, +) +from eth.vm.forks.byzantium.opcodes import ( + BYZANTIUM_OPCODES, +) +from eth.vm.forks.petersburg.constants import ( + GAS_EXTCODEHASH_EIP1052 +) +from eth.vm.logic import ( + arithmetic, + context, + system, +) +from eth.vm.opcode import ( + as_opcode +) + + +UPDATED_OPCODES = { + opcode_values.SHL: as_opcode( + logic_fn=arithmetic.shl, + mnemonic=mnemonics.SHL, + gas_cost=constants.GAS_VERYLOW, + ), + opcode_values.SHR: as_opcode( + logic_fn=arithmetic.shr, + mnemonic=mnemonics.SHR, + gas_cost=constants.GAS_VERYLOW, + ), + opcode_values.SAR: as_opcode( + logic_fn=arithmetic.sar, + mnemonic=mnemonics.SAR, + gas_cost=constants.GAS_VERYLOW, + ), + opcode_values.EXTCODEHASH: as_opcode( + logic_fn=context.extcodehash, + mnemonic=mnemonics.EXTCODEHASH, + gas_cost=GAS_EXTCODEHASH_EIP1052, + ), + opcode_values.CREATE2: system.Create2.configure( + __name__='opcode:CREATE2', + mnemonic=mnemonics.CREATE2, + gas_cost=constants.GAS_CREATE, + )(), +} + +PETERSBURG_OPCODES = merge( + copy.deepcopy(BYZANTIUM_OPCODES), + UPDATED_OPCODES, +) diff --git a/eth/vm/forks/petersburg/state.py b/eth/vm/forks/petersburg/state.py new file mode 100644 index 0000000000..476e457083 --- /dev/null +++ b/eth/vm/forks/petersburg/state.py @@ -0,0 +1,9 @@ +from eth.vm.forks.byzantium.state import ( + ByzantiumState +) + +from .computation import PetersburgComputation + + +class PetersburgState(ByzantiumState): + computation_class = PetersburgComputation diff --git a/eth/vm/forks/petersburg/transactions.py b/eth/vm/forks/petersburg/transactions.py new file mode 100644 index 0000000000..58a292fc21 --- /dev/null +++ b/eth/vm/forks/petersburg/transactions.py @@ -0,0 +1,42 @@ +from eth_keys.datatypes import PrivateKey +from eth_typing import Address + +from eth.vm.forks.byzantium.transactions import ( + ByzantiumTransaction, + ByzantiumUnsignedTransaction, +) + +from eth._utils.transactions import ( + create_transaction_signature, +) + + +class PetersburgTransaction(ByzantiumTransaction): + @classmethod + def create_unsigned_transaction(cls, + *, + nonce: int, + gas_price: int, + gas: int, + to: Address, + value: int, + data: bytes) -> 'PetersburgUnsignedTransaction': + return PetersburgUnsignedTransaction(nonce, gas_price, gas, to, value, data) + + +class PetersburgUnsignedTransaction(ByzantiumUnsignedTransaction): + def as_signed_transaction(self, + private_key: PrivateKey, + chain_id: int=None) -> PetersburgTransaction: + v, r, s = create_transaction_signature(self, private_key, chain_id=chain_id) + return PetersburgTransaction( + nonce=self.nonce, + gas_price=self.gas_price, + gas=self.gas, + to=self.to, + value=self.value, + data=self.data, + v=v, + r=r, + s=s, + ) diff --git a/eth/vm/forks/spurious_dragon/_utils.py b/eth/vm/forks/spurious_dragon/_utils.py index e6174b99f8..6a00b8f4a1 100644 --- a/eth/vm/forks/spurious_dragon/_utils.py +++ b/eth/vm/forks/spurious_dragon/_utils.py @@ -17,15 +17,18 @@ @to_set def collect_touched_accounts(computation: BaseComputation) -> Iterable[bytes]: """ - Collect all of the accounts that *may* need to be deleted based on EIP161: + Collect all of the accounts that *may* need to be deleted based on + `EIP-161 `_. - https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md + Checking whether they *do* need to be deleted happens in the caller. - also see: https://github.com/ethereum/EIPs/issues/716 + See also: https://github.com/ethereum/EIPs/issues/716 """ + # collect the coinbase account if it was touched via zero-fee transfer if computation.is_origin_computation and computation.transaction_context.gas_price == 0: yield computation.state.coinbase + # collect those explicitly marked for deletion ("beneficiary" is of SELFDESTRUCT) for beneficiary in sorted(set(computation.accounts_to_delete.values())): if computation.is_error and computation.is_origin_computation: # Special case to account for geth+parity bug @@ -36,6 +39,7 @@ def collect_touched_accounts(computation: BaseComputation) -> Iterable[bytes]: else: yield beneficiary + # collect account directly addressed if computation.msg.to != constants.CREATE_CONTRACT_ADDRESS: if computation.is_error and computation.is_origin_computation: # Special case to account for geth+parity bug @@ -45,6 +49,7 @@ def collect_touched_accounts(computation: BaseComputation) -> Iterable[bytes]: else: yield computation.msg.to - if not computation.is_origin_computation or not computation.is_error: + # recurse into nested computations if this one was successful + if not computation.is_error: for child in computation.children: yield from collect_touched_accounts(child) diff --git a/fixtures b/fixtures index 725dbc73a5..6b85703b56 160000 --- a/fixtures +++ b/fixtures @@ -1 +1 @@ -Subproject commit 725dbc73a54649e22a00330bd0f4d6699a5060e5 +Subproject commit 6b85703b568f4456582a00665d8a3e5c3b20b484 diff --git a/tests/conftest.py b/tests/conftest.py index 829ec62f83..711bf18ae6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,3 @@ -# from eth._utils.logging import DEBUG2_LEVEL_NUM - import pytest from eth_utils import ( @@ -22,6 +20,7 @@ SpuriousDragonVM, ByzantiumVM, ConstantinopleVM, + PetersburgVM, ) @@ -31,7 +30,7 @@ import datetime import logging import os -from eth.tools.logging import TRACE_LEVEL_NUM +from eth.tools.logging import DEBUG2_LEVEL_NUM @pytest.yield_fixture(autouse=True) def _file_logging(request): @@ -73,6 +72,7 @@ def _file_logging(request): SpuriousDragonVM, ByzantiumVM, ConstantinopleVM, + PetersburgVM, ]) def VM(request): return request.param diff --git a/tests/core/chain-object/test_contract_call.py b/tests/core/chain-object/test_contract_call.py index 7753f1c084..8e056a2856 100644 --- a/tests/core/chain-object/test_contract_call.py +++ b/tests/core/chain-object/test_contract_call.py @@ -26,6 +26,7 @@ SpuriousDragonVM, ByzantiumVM, ConstantinopleVM, + PetersburgVM, ) @@ -202,6 +203,16 @@ def test_get_transaction_result( 'useLotsOfGas()', OutOfGas, ), + ( + PetersburgVM, + 'doRevert()', + Revert, + ), + ( + PetersburgVM, + 'useLotsOfGas()', + OutOfGas, + ), ), ) def test_get_transaction_result_revert( diff --git a/tests/core/tester/test_generate_vm_configuration.py b/tests/core/tester/test_generate_vm_configuration.py index d19bccb7cc..57ef011a5f 100644 --- a/tests/core/tester/test_generate_vm_configuration.py +++ b/tests/core/tester/test_generate_vm_configuration.py @@ -9,13 +9,14 @@ class Forks(enum.Enum): - Custom = -1 - Frontier = 0 - Homestead = 1 - TangerineWhistle = 2 - SpuriousDragon = 3 - Byzantium = 4 - Constantinople = 5 + Custom = 'CustomFrontier' + Frontier = 'Frontier' + Homestead = 'Homestead' + TangerineWhistle = 'TangerineWhistle' + SpuriousDragon = 'SpuriousDragon' + Byzantium = 'Byzantium' + Constantinople = 'Constantinople' + Petersburg = 'Petersburg' class CustomFrontierVM(FrontierVM): @@ -28,7 +29,7 @@ class CustomFrontierVM(FrontierVM): ( tuple(), {}, - ((0, Forks.Constantinople),), + ((0, Forks.Petersburg),), ), ( ((0, 'tangerine-whistle'), (1, 'spurious-dragon')), @@ -109,6 +110,23 @@ class CustomFrontierVM(FrontierVM): (3, Forks.Byzantium), ), ), + ( + ( + (0, 'frontier'), + (1, 'homestead'), + (2, 'tangerine-whistle'), + (3, 'byzantium'), + (5, 'petersburg') + ), + {}, + ( + (0, Forks.Frontier), + (1, Forks.Homestead), + (2, Forks.TangerineWhistle), + (3, Forks.Byzantium), + (5, Forks.Petersburg), + ), + ), ), ) def test_generate_vm_configuration(args, kwargs, expected): @@ -121,10 +139,9 @@ def test_generate_vm_configuration(args, kwargs, expected): assert left_block == right_block - if right_vm == Forks.Frontier: - assert 'Frontier' in left_vm.__name__ - elif right_vm == Forks.Homestead: - assert 'Homestead' in left_vm.__name__ + assert right_vm.value in left_vm.__name__ + + if right_vm == Forks.Homestead: dao_start_block = kwargs.get('dao_start_block') if dao_start_block is False: assert left_vm.support_dao_fork is False @@ -134,15 +151,3 @@ def test_generate_vm_configuration(args, kwargs, expected): else: assert left_vm.support_dao_fork is True assert left_vm.get_dao_fork_block_number() == dao_start_block - elif right_vm == Forks.TangerineWhistle: - assert 'TangerineWhistle' in left_vm.__name__ - elif right_vm == Forks.SpuriousDragon: - assert 'SpuriousDragon' in left_vm.__name__ - elif right_vm == Forks.Byzantium: - assert 'Byzantium' in left_vm.__name__ - elif right_vm == Forks.Constantinople: - assert 'Constantinople' in left_vm.__name__ - elif right_vm == Forks.Custom: - assert 'CustomFrontier' in left_vm.__name__ - else: - assert False, "Invariant" diff --git a/tests/json-fixtures/test_blockchain.py b/tests/json-fixtures/test_blockchain.py index b7dd65a262..d12b97e2e0 100644 --- a/tests/json-fixtures/test_blockchain.py +++ b/tests/json-fixtures/test_blockchain.py @@ -144,10 +144,14 @@ # * 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 + ('GeneralStateTests/stRevertTest/RevertInCreateInInit_d0g0v0.json', 'RevertInCreateInInit_d0g0v0_ConstantinopleFix'), # 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 + ('GeneralStateTests/stCreate2/RevertInCreateInInitCreate2_d0g0v0.json', 'RevertInCreateInInitCreate2_d0g0v0_ConstantinopleFix'), # noqa: E501 + # All four variants have been specifically added to test a collision type # like the above; therefore, they fail in the same manner. # * https://github.com/ethereum/py-evm/pull/1579#issuecomment-446591118 @@ -155,6 +159,9 @@ ('GeneralStateTests/stSStoreTest/InitCollision_d1g0v0.json', 'InitCollision_d1g0v0_Constantinople'), # noqa: E501 ('GeneralStateTests/stSStoreTest/InitCollision_d2g0v0.json', 'InitCollision_d2g0v0_Constantinople'), # noqa: E501 ('GeneralStateTests/stSStoreTest/InitCollision_d3g0v0.json', 'InitCollision_d3g0v0_Constantinople'), # noqa: E501 + ('GeneralStateTests/stSStoreTest/InitCollision_d0g0v0.json', 'InitCollision_d0g0v0_ConstantinopleFix'), # noqa: E501 + ('GeneralStateTests/stSStoreTest/InitCollision_d1g0v0.json', 'InitCollision_d1g0v0_ConstantinopleFix'), # noqa: E501 + ('GeneralStateTests/stSStoreTest/InitCollision_d3g0v0.json', 'InitCollision_d3g0v0_ConstantinopleFix'), # noqa: E501 } diff --git a/tests/json-fixtures/test_transactions.py b/tests/json-fixtures/test_transactions.py index 3051bb2cdc..11968cb4a1 100644 --- a/tests/json-fixtures/test_transactions.py +++ b/tests/json-fixtures/test_transactions.py @@ -31,6 +31,9 @@ from eth.vm.forks.constantinople.transactions import ( ConstantinopleTransaction ) +from eth.vm.forks.petersburg.transactions import ( + PetersburgTransaction +) from eth_typing.enums import ( ForkName @@ -96,6 +99,8 @@ def fixture_transaction_class(fixture_data): return ByzantiumTransaction elif fork_name == ForkName.Constantinople: return ConstantinopleTransaction + elif fork_name == "Petersburg": + return PetersburgTransaction elif fork_name == ForkName.Metropolis: pytest.skip("Metropolis Transaction class has not been implemented") else: diff --git a/tox.ini b/tox.ini index 368c93cb9b..982ff1e586 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist= py{35,36}-{core,database,transactions,vm} py{36}-{benchmark} - py{35,36}-native-blockchain-{frontier,homestead,tangerine_whistle,spurious_dragon,byzantium,constantinople,metropolis,transition} + py{35,36}-native-blockchain-{frontier,homestead,tangerine_whistle,spurious_dragon,byzantium,constantinople,petersburg,metropolis,transition} py37-{core} py{35,36}-lint py36-docs @@ -28,6 +28,7 @@ commands= native-blockchain-spurious_dragon: 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-petersburg: pytest {posargs:tests/json-fixtures/test_blockchain.py --fork ConstantinopleFix} 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}