From c4317dd53a2d61c62380212b93206a7b230ba830 Mon Sep 17 00:00:00 2001 From: winsvega Date: Sat, 20 Jan 2024 00:39:06 +0100 Subject: [PATCH] fix(tools): Fix state_tests filled json generation (#378) * fix state test generation * tx.with_signature_and_sender_and_private_key * previousHash only in state tests fixture * add parameter to `with_signature_and_sender` * revert excessBlobGas, beacon root * remove unused defaults, add `null` `to` as empty string * Add state test filler tests * Add abstract method to BaseFixture --------- Co-authored-by: Mario Vega --- src/ethereum_test_tools/common/types.py | 7 ++- .../spec/base/base_test.py | 9 +++ .../spec/state/state_test.py | 2 +- src/ethereum_test_tools/spec/state/types.py | 45 +++++++------- src/ethereum_test_tools/tests/test_filler.py | 22 +++---- ... => chainid_istanbul_blockchain_test.json} | 0 ...on => chainid_london_blockchain_test.json} | 0 ...> chainid_paris_blockchain_test_hive.json} | 0 .../chainid_paris_state_test.json | 58 +++++++++++++++++++ ...hainid_shanghai_blockchain_test_hive.json} | 0 .../chainid_shanghai_state_test.json | 58 +++++++++++++++++++ 11 files changed, 163 insertions(+), 38 deletions(-) rename src/ethereum_test_tools/tests/test_fixtures/{chainid_istanbul_filled.json => chainid_istanbul_blockchain_test.json} (100%) rename src/ethereum_test_tools/tests/test_fixtures/{chainid_london_filled.json => chainid_london_blockchain_test.json} (100%) rename src/ethereum_test_tools/tests/test_fixtures/{chainid_paris_filled_hive.json => chainid_paris_blockchain_test_hive.json} (100%) create mode 100644 src/ethereum_test_tools/tests/test_fixtures/chainid_paris_state_test.json rename src/ethereum_test_tools/tests/test_fixtures/{chainid_shanghai_filled_hive.json => chainid_shanghai_blockchain_test_hive.json} (100%) create mode 100644 src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_state_test.json diff --git a/src/ethereum_test_tools/common/types.py b/src/ethereum_test_tools/common/types.py index f7bf798077..7d79c45cf3 100644 --- a/src/ethereum_test_tools/common/types.py +++ b/src/ethereum_test_tools/common/types.py @@ -1671,7 +1671,7 @@ def signature_bytes(self) -> bytes: + bytes([v]) ) - def with_signature_and_sender(self) -> "Transaction": + def with_signature_and_sender(self, *, keep_secret_key: bool = False) -> "Transaction": """ Returns a signed version of the transaction using the private key. """ @@ -1714,8 +1714,9 @@ def with_signature_and_sender(self) -> "Transaction": else: # not protected tx.v += 27 - # Remove the secret key because otherwise we might attempt to sign again (?) - tx.secret_key = None + # Remove the secret key if requested + if not keep_secret_key: + tx.secret_key = None return tx diff --git a/src/ethereum_test_tools/spec/base/base_test.py b/src/ethereum_test_tools/spec/base/base_test.py index 98fee32e9c..641aeb2638 100644 --- a/src/ethereum_test_tools/spec/base/base_test.py +++ b/src/ethereum_test_tools/spec/base/base_test.py @@ -95,10 +95,19 @@ def fill_info( """ Fill the info field for this fixture """ + if "comment" not in self.info: + self.info["comment"] = "`execution-spec-tests` generated test" self.info["filling-transition-tool"] = t8n.version() if ref_spec is not None: ref_spec.write_info(self.info) + @abstractmethod + def to_json(self) -> Dict[str, Any]: + """ + Convert to JSON. + """ + pass + @classmethod @abstractmethod def format(cls) -> FixtureFormats: diff --git a/src/ethereum_test_tools/spec/state/state_test.py b/src/ethereum_test_tools/spec/state/state_test.py index 378c902a83..4308bdf686 100644 --- a/src/ethereum_test_tools/spec/state/state_test.py +++ b/src/ethereum_test_tools/spec/state/state_test.py @@ -126,7 +126,7 @@ def make_state_test_fixture( Create a fixture from the state test definition. """ env = self.env.set_fork_requirements(fork) - tx = self.tx.with_signature_and_sender() + tx = self.tx.with_signature_and_sender(keep_secret_key=True) pre_alloc = Alloc.merge( Alloc( fork.pre_allocation(block_number=env.number, timestamp=Number(env.timestamp)), diff --git a/src/ethereum_test_tools/spec/state/types.py b/src/ethereum_test_tools/spec/state/types.py index 1ce55bcf17..458ab20a8f 100644 --- a/src/ethereum_test_tools/spec/state/types.py +++ b/src/ethereum_test_tools/spec/state/types.py @@ -12,14 +12,12 @@ from ...common.json import JSONEncoder, field, to_json from ...common.types import ( AccessList, - AddrAA, Address, Alloc, Bytes, Environment, Hash, HexNumber, - Number, NumberConvertible, Transaction, ZeroPaddedHexNumber, @@ -44,49 +42,56 @@ class FixtureEnvironment: default=100000000000000000, json_encoder=JSONEncoder.Field( name="currentGasLimit", - cast_type=Number, + cast_type=ZeroPaddedHexNumber, ), ) number: NumberConvertible = field( default=1, json_encoder=JSONEncoder.Field( name="currentNumber", - cast_type=Number, + cast_type=ZeroPaddedHexNumber, ), ) timestamp: NumberConvertible = field( default=1000, json_encoder=JSONEncoder.Field( name="currentTimestamp", - cast_type=Number, + cast_type=ZeroPaddedHexNumber, ), ) prev_randao: Optional[NumberConvertible] = field( default=None, json_encoder=JSONEncoder.Field( name="currentRandom", - cast_type=Number, + cast_type=Hash, ), ) difficulty: Optional[NumberConvertible] = field( default=None, json_encoder=JSONEncoder.Field( name="currentDifficulty", - cast_type=Number, + cast_type=ZeroPaddedHexNumber, ), ) base_fee: Optional[NumberConvertible] = field( default=None, json_encoder=JSONEncoder.Field( name="currentBaseFee", - cast_type=Number, + cast_type=ZeroPaddedHexNumber, ), ) excess_blob_gas: Optional[NumberConvertible] = field( default=None, json_encoder=JSONEncoder.Field( name="currentExcessBlobGas", - cast_type=Number, + cast_type=ZeroPaddedHexNumber, + ), + ) + previous_hash: Optional[FixedSizeBytesConvertible] = field( + default="0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + json_encoder=JSONEncoder.Field( + name="previousHash", + cast_type=Hash, ), ) @@ -95,7 +100,11 @@ def from_env(cls, env: Environment) -> "FixtureEnvironment": """ Returns a FixtureEnvironment from an Environment. """ - kwargs = {field.name: getattr(env, field.name) for field in fields(cls)} + kwargs = { + field.name: getattr(env, field.name) + for field in fields(cls) + if field.name != "previous_hash" # define this field for state tests only + } return cls(**kwargs) @@ -106,34 +115,29 @@ class FixtureTransaction: """ nonce: int = field( - default=0, json_encoder=JSONEncoder.Field( cast_type=ZeroPaddedHexNumber, ), ) gas_price: Optional[int] = field( - default=None, json_encoder=JSONEncoder.Field( name="gasPrice", cast_type=ZeroPaddedHexNumber, ), ) max_priority_fee_per_gas: Optional[int] = field( - default=None, json_encoder=JSONEncoder.Field( name="maxPriorityFeePerGas", cast_type=HexNumber, ), ) max_fee_per_gas: Optional[int] = field( - default=None, json_encoder=JSONEncoder.Field( name="maxFeePerGas", cast_type=HexNumber, ), ) gas_limit: int = field( - default=21000, json_encoder=JSONEncoder.Field( name="gasLimit", cast_type=lambda x: [ZeroPaddedHexNumber(x)], # Converted to list @@ -141,27 +145,24 @@ class FixtureTransaction: ), ) to: Optional[FixedSizeBytesConvertible] = field( - default=AddrAA, json_encoder=JSONEncoder.Field( + default_value_skip_cast="", # Empty string for None cast_type=Address, ), ) value: int = field( - default=0, json_encoder=JSONEncoder.Field( cast_type=lambda x: [ZeroPaddedHexNumber(x)], # Converted to list to_json=True, ), ) data: BytesConvertible = field( - default_factory=bytes, json_encoder=JSONEncoder.Field( cast_type=lambda x: [Bytes(x)], to_json=True, ), ) access_list: Optional[List[AccessList]] = field( - default=None, json_encoder=JSONEncoder.Field( name="accessLists", cast_type=lambda x: [x], # Converted to list of lists @@ -169,14 +170,12 @@ class FixtureTransaction: ), ) max_fee_per_blob_gas: Optional[int] = field( - default=None, json_encoder=JSONEncoder.Field( name="maxFeePerBlobGas", cast_type=HexNumber, ), ) blob_versioned_hashes: Optional[Sequence[FixedSizeBytesConvertible]] = field( - default=None, json_encoder=JSONEncoder.Field( name="blobVersionedHashes", cast_type=lambda x: [Hash(k) for k in x], @@ -184,14 +183,12 @@ class FixtureTransaction: ), ) - sender: Optional[FixedSizeBytesConvertible] = field( - default=None, + sender: FixedSizeBytesConvertible = field( json_encoder=JSONEncoder.Field( cast_type=Address, ), ) secret_key: Optional[FixedSizeBytesConvertible] = field( - default=None, json_encoder=JSONEncoder.Field( name="secretKey", cast_type=Hash, diff --git a/src/ethereum_test_tools/tests/test_filler.py b/src/ethereum_test_tools/tests/test_filler.py index 640200c892..3b845833ea 100644 --- a/src/ethereum_test_tools/tests/test_filler.py +++ b/src/ethereum_test_tools/tests/test_filler.py @@ -92,15 +92,20 @@ def test_make_genesis(fork: Fork, hash: bytes): # noqa: D103 @pytest.mark.parametrize( - "fork,check_hive,expected_json_file", + "fork,fixture_format", [ - (Istanbul, False, "chainid_istanbul_filled.json"), - (London, False, "chainid_london_filled.json"), - (Paris, True, "chainid_paris_filled_hive.json"), - (Shanghai, True, "chainid_shanghai_filled_hive.json"), + (Istanbul, FixtureFormats.BLOCKCHAIN_TEST), + (London, FixtureFormats.BLOCKCHAIN_TEST), + (Paris, FixtureFormats.BLOCKCHAIN_TEST_HIVE), + (Shanghai, FixtureFormats.BLOCKCHAIN_TEST_HIVE), + (Paris, FixtureFormats.STATE_TEST), + (Shanghai, FixtureFormats.STATE_TEST), ], ) -def test_fill_state_test(fork: Fork, expected_json_file: str, check_hive: bool): +def test_fill_state_test( + fork: Fork, + fixture_format: FixtureFormats, +): """ Test `ethereum_test.filler.fill_fixtures` with `StateTest`. """ @@ -134,9 +139,6 @@ def test_fill_state_test(fork: Fork, expected_json_file: str, check_hive: bool): } t8n = GethTransitionTool() - fixture_format = ( - FixtureFormats.BLOCKCHAIN_TEST_HIVE if check_hive else FixtureFormats.BLOCKCHAIN_TEST - ) generated_fixture = StateTest( env=env, pre=pre, @@ -149,11 +151,11 @@ def test_fill_state_test(fork: Fork, expected_json_file: str, check_hive: bool): fork=fork, ) assert generated_fixture.format() == fixture_format - assert isinstance(generated_fixture, BlockchainFixtureCommon) fixture = { f"000/my_chain_id_test/{fork}": generated_fixture.to_json(), } + expected_json_file = f"chainid_{fork.name().lower()}_{fixture_format.value}.json" with open( os.path.join( "src", diff --git a/src/ethereum_test_tools/tests/test_fixtures/chainid_istanbul_filled.json b/src/ethereum_test_tools/tests/test_fixtures/chainid_istanbul_blockchain_test.json similarity index 100% rename from src/ethereum_test_tools/tests/test_fixtures/chainid_istanbul_filled.json rename to src/ethereum_test_tools/tests/test_fixtures/chainid_istanbul_blockchain_test.json diff --git a/src/ethereum_test_tools/tests/test_fixtures/chainid_london_filled.json b/src/ethereum_test_tools/tests/test_fixtures/chainid_london_blockchain_test.json similarity index 100% rename from src/ethereum_test_tools/tests/test_fixtures/chainid_london_filled.json rename to src/ethereum_test_tools/tests/test_fixtures/chainid_london_blockchain_test.json diff --git a/src/ethereum_test_tools/tests/test_fixtures/chainid_paris_filled_hive.json b/src/ethereum_test_tools/tests/test_fixtures/chainid_paris_blockchain_test_hive.json similarity index 100% rename from src/ethereum_test_tools/tests/test_fixtures/chainid_paris_filled_hive.json rename to src/ethereum_test_tools/tests/test_fixtures/chainid_paris_blockchain_test_hive.json diff --git a/src/ethereum_test_tools/tests/test_fixtures/chainid_paris_state_test.json b/src/ethereum_test_tools/tests/test_fixtures/chainid_paris_state_test.json new file mode 100644 index 0000000000..1bfbccb74b --- /dev/null +++ b/src/ethereum_test_tools/tests/test_fixtures/chainid_paris_state_test.json @@ -0,0 +1,58 @@ +{ + "000/my_chain_id_test/Paris": { + "env": { + "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentGasLimit": "0x02540be400", + "currentNumber": "0x01", + "currentTimestamp": "0x03e8", + "currentRandom": "0x0000000000000000000000000000000000000000000000000000000000000000", + "currentDifficulty": "0x00", + "currentBaseFee": "0x07", + "previousHash": "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre": { + "0x1000000000000000000000000000000000000000": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x4660015500", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + } + }, + "transaction": { + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": [ + "0x05f5e100" + ], + "to": "0x1000000000000000000000000000000000000000", + "value": [ + "0x00" + ], + "data": [ + "0x" + ], + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + }, + "post": { + "Merge": [ + { + "hash": "0x19919608275963e6e20a1191996f5b19db8208dd8df54097cfd2b9cb14f682b6", + "logs": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "txbytes": "0xf861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b", + "indexes": { + "data": 0, + "gas": 0, + "value": 0 + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_filled_hive.json b/src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_blockchain_test_hive.json similarity index 100% rename from src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_filled_hive.json rename to src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_blockchain_test_hive.json diff --git a/src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_state_test.json b/src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_state_test.json new file mode 100644 index 0000000000..f2ddc1996e --- /dev/null +++ b/src/ethereum_test_tools/tests/test_fixtures/chainid_shanghai_state_test.json @@ -0,0 +1,58 @@ +{ + "000/my_chain_id_test/Shanghai": { + "env": { + "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentGasLimit": "0x02540be400", + "currentNumber": "0x01", + "currentTimestamp": "0x03e8", + "currentRandom": "0x0000000000000000000000000000000000000000000000000000000000000000", + "currentDifficulty": "0x00", + "currentBaseFee": "0x07", + "previousHash": "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre": { + "0x1000000000000000000000000000000000000000": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x4660015500", + "storage": {} + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "nonce": "0x00", + "balance": "0x3635c9adc5dea00000", + "code": "0x", + "storage": {} + } + }, + "transaction": { + "nonce": "0x00", + "gasPrice": "0x0a", + "gasLimit": [ + "0x05f5e100" + ], + "to": "0x1000000000000000000000000000000000000000", + "value": [ + "0x00" + ], + "data": [ + "0x" + ], + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + }, + "post": { + "Shanghai": [ + { + "hash": "0x19919608275963e6e20a1191996f5b19db8208dd8df54097cfd2b9cb14f682b6", + "logs": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "txbytes": "0xf861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b", + "indexes": { + "data": 0, + "gas": 0, + "value": 0 + } + } + ] + } + } +} \ No newline at end of file