Skip to content

Commit

Permalink
fix(tools): Fix state_tests filled json generation (#378)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
winsvega and marioevz authored Jan 19, 2024
1 parent 933508e commit c4317dd
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 38 deletions.
7 changes: 4 additions & 3 deletions src/ethereum_test_tools/common/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand Down Expand Up @@ -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


Expand Down
9 changes: 9 additions & 0 deletions src/ethereum_test_tools/spec/base/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion src/ethereum_test_tools/spec/state/state_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
45 changes: 21 additions & 24 deletions src/ethereum_test_tools/spec/state/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
),
)

Expand All @@ -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)


Expand All @@ -106,92 +115,80 @@ 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
to_json=True,
),
)
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
to_json=True,
),
)
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],
to_json=True,
),
)

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,
Expand Down
22 changes: 12 additions & 10 deletions src/ethereum_test_tools/tests/test_filler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
"""
Expand Down Expand Up @@ -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,
Expand All @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
]
}
}
}
Loading

0 comments on commit c4317dd

Please sign in to comment.