Skip to content

Commit

Permalink
new(tests): EIP-7702 - Set EOA account code for one transaction (Devn…
Browse files Browse the repository at this point in the history
…et-1) (#621)

* feat(fw): Add type-4 transaction and authorization tuple type

* new(tests): Add EIP-7702 folder, first test

* tests: create contract

* new(tests): more 7702 tests

* new(tests): EIP-7702

* new(tests): EIP-7702

* typo

* fix(fw): minor refactor

* new(tests): parametrize sanity test with and without balance

* fix(tests): fixes

* fix(fw): nonce field in the auth tuple

* fix(tests): fix some of the tests

* fix(tests): test fixes and skips

* fix(test): skip

* fix(specs): output the authorization list to the fixture

* nit

* more tests

* fix(fw): State test type-4 fix

* fix(fw): Transaction type checks

* fix(fixtures): Fixture transaciton type-4 test

* fix(base_types): Storage methods

* fix(tests): storage method usage

* changelog
  • Loading branch information
marioevz authored Jul 23, 2024
1 parent b85cff5 commit 1e1e3cf
Show file tree
Hide file tree
Showing 11 changed files with 1,216 additions and 22 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- ✨ Add tests for subcontainer kind validation from [EIP-7620: EOF Contract Creation](https://eips.ethereum.org/EIPS/eip-7620) for the cases with deeply nested containers and non-first code sections ([#676](https://github.com/ethereum/execution-spec-tests/pull/676)).
- ✨ Add tests for runtime stack overflow at CALLF instruction from [EIP-4750: EOF - Functions](https://eips.ethereum.org/EIPS/eip-4750) ([#678](https://github.com/ethereum/execution-spec-tests/pull/678)).
- ✨ Add tests for runtime stack overflow at JUMPF instruction from [EIP-6206: EOF - JUMPF and non-returning functions](https://eips.ethereum.org/EIPS/eip-6206) ([#690](https://github.com/ethereum/execution-spec-tests/pull/690)).
- ✨ Add tests for Devnet-1 version of [EIP-7702: Set EOA account code](https://eips.ethereum.org/EIPS/eip-7702) ([#621](https://github.com/ethereum/execution-spec-tests/pull/621))

### 🛠️ Framework

Expand Down
29 changes: 24 additions & 5 deletions src/ethereum_test_base_types/composite_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
Base composite types for Ethereum test cases.
"""
from dataclasses import dataclass
from itertools import count
from typing import Any, ClassVar, Dict, Iterator, SupportsBytes, Type, TypeAlias
from typing import Any, ClassVar, Dict, SupportsBytes, Type, TypeAlias

from pydantic import Field, RootModel, TypeAdapter
from pydantic import Field, PrivateAttr, RootModel, TypeAdapter

from .base_types import Address, Bytes, Hash, HashInt, HexNumber, ZeroPaddedHexNumber
from .conversions import BytesConvertible, NumberConvertible
Expand All @@ -24,7 +23,7 @@ class Storage(RootModel[Dict[StorageKeyValueType, StorageKeyValueType]]):

root: Dict[StorageKeyValueType, StorageKeyValueType] = Field(default_factory=dict)

_current_slot: Iterator[int] = count(0)
_current_slot: int = PrivateAttr(0)

StorageDictType: ClassVar[TypeAlias] = Dict[
str | int | bytes | SupportsBytes, str | int | bytes | SupportsBytes
Expand Down Expand Up @@ -161,10 +160,23 @@ def __bool__(self) -> bool:
"""Returns True if the storage is not empty"""
return any(v for v in self.root.values())

def __add__(self, other: "Storage") -> "Storage":
"""
Returns a new storage that is the sum of two storages.
"""
return Storage({**self.root, **other.root})

def keys(self) -> set[StorageKeyValueType]:
"""Returns the keys of the storage"""
return set(self.root.keys())

def set_next_slot(self, slot: int) -> "Storage":
"""
Sets the next slot to be used by `store_next`.
"""
self._current_slot = slot
return self

def store_next(
self, value: StorageKeyValueTypeConvertible | StorageKeyValueType | bool
) -> StorageKeyValueType:
Expand All @@ -174,10 +186,17 @@ def store_next(
Increments the key counter so the next time this function is called,
the next key is used.
"""
slot = StorageKeyValueTypeAdapter.validate_python(next(self._current_slot))
slot = StorageKeyValueTypeAdapter.validate_python(self._current_slot)
self._current_slot += 1
self[slot] = StorageKeyValueTypeAdapter.validate_python(value)
return slot

def peek_slot(self) -> int:
"""
Peeks the next slot that will be used by `store_next`.
"""
return self._current_slot

def contains(self, other: "Storage") -> bool:
"""
Returns True if self contains all keys with equal value as
Expand Down
20 changes: 20 additions & 0 deletions src/ethereum_test_fixtures/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from ethereum_test_exceptions import EngineAPIError, ExceptionInstanceOrList
from ethereum_test_forks import Fork
from ethereum_test_types.types import (
AuthorizationTupleGeneric,
ConsolidationRequest,
ConsolidationRequestGeneric,
DepositRequest,
Expand Down Expand Up @@ -321,11 +322,30 @@ def from_fixture_header(
return new_payload


class FixtureAuthorizationTuple(AuthorizationTupleGeneric[ZeroPaddedHexNumber]):
"""
Authorization tuple for fixture transactions.
"""

signer: Address | None = None

@classmethod
def from_authorization_tuple(
cls, auth_tuple: AuthorizationTupleGeneric
) -> "FixtureAuthorizationTuple":
"""
Returns a FixtureAuthorizationTuple from an AuthorizationTuple.
"""
return cls(**auth_tuple.model_dump())


class FixtureTransaction(TransactionFixtureConverter, TransactionGeneric[ZeroPaddedHexNumber]):
"""
Representation of an Ethereum transaction within a test Fixture.
"""

authorization_list: List[FixtureAuthorizationTuple] | None = None

@classmethod
def from_transaction(cls, tx: Transaction) -> "FixtureTransaction":
"""
Expand Down
19 changes: 19 additions & 0 deletions src/ethereum_test_fixtures/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from ethereum_test_exceptions import TransactionExceptionInstanceOrList
from ethereum_test_types.types import (
AccessList,
AuthorizationTupleGeneric,
CamelModel,
EnvironmentGeneric,
Transaction,
Expand All @@ -28,6 +29,23 @@ class FixtureEnvironment(EnvironmentGeneric[ZeroPaddedHexNumber]):
prev_randao: Hash | None = Field(None, alias="currentRandom") # type: ignore


class FixtureAuthorizationTuple(AuthorizationTupleGeneric[ZeroPaddedHexNumber]):
"""
Authorization tuple for fixture transactions.
"""

signer: Address | None = None

@classmethod
def from_authorization_tuple(
cls, auth_tuple: AuthorizationTupleGeneric
) -> "FixtureAuthorizationTuple":
"""
Returns a FixtureAuthorizationTuple from an AuthorizationTuple.
"""
return cls(**auth_tuple.model_dump())


class FixtureTransaction(TransactionFixtureConverter):
"""
Type used to describe a transaction in a state test.
Expand All @@ -42,6 +60,7 @@ class FixtureTransaction(TransactionFixtureConverter):
value: List[ZeroPaddedHexNumber]
data: List[Bytes]
access_lists: List[List[AccessList]] | None = None
authorization_list: List[FixtureAuthorizationTuple] | None = None
max_fee_per_blob_gas: ZeroPaddedHexNumber | None = None
blob_versioned_hashes: Sequence[Hash] | None = None
sender: Address | None = None
Expand Down
48 changes: 48 additions & 0 deletions src/ethereum_test_fixtures/tests/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
Bytes,
Hash,
HeaderNonce,
TestPrivateKey,
ZeroPaddedHexNumber,
to_json,
)
from ethereum_test_exceptions import BlockException, EngineAPIError, TransactionException
from ethereum_test_forks import Prague
from ethereum_test_types import (
EOA,
AccessList,
AuthorizationTuple,
ConsolidationRequest,
DepositRequest,
Requests,
Expand Down Expand Up @@ -178,6 +181,51 @@
},
id="fixture_transaction_type_3_default_values",
),
pytest.param(
True,
FixtureTransaction.from_transaction(
Transaction(
ty=4,
max_fee_per_gas=7,
authorization_list=[
AuthorizationTuple(
chain_id=1,
address=2,
nonce=[3],
signer=EOA(key=TestPrivateKey),
)
],
).with_signature_and_sender()
),
{
"type": "0x04",
"chainId": "0x01",
"nonce": "0x00",
"to": "0x00000000000000000000000000000000000000aa",
"value": "0x00",
"data": "0x",
"gasLimit": "0x5208",
"maxPriorityFeePerGas": "0x00",
"maxFeePerGas": "0x07",
"accessList": [],
"authorizationList": [
{
"chainId": "0x01",
"address": Address(2).hex(),
"nonce": ["0x03"],
"v": "0x00",
"r": "0x796b0a59fe796b5aab79259988f4b18bb7966dc9aa0a01d226859057f539d8f6",
"s": "0x7456ad9b8b4e157d8a150ae7d568bb93e668bf1d5970756f7fe7b7f2472235fe",
"signer": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
}
],
"v": "0x01",
"r": "0xb9f3ad929ffdb846cbe357fa25e6ab93cc6e10e76da170a12baf03f8a34ba141",
"s": "0x04992060cfa252f5ac18ac1ccb340a821497d50812a225646094d2ad08b8eeaa",
"sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
},
id="fixture_transaction_type_4",
),
pytest.param(
True,
FixtureTransaction.from_transaction(
Expand Down
2 changes: 2 additions & 0 deletions src/ethereum_test_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
EOA,
AccessList,
Alloc,
AuthorizationTuple,
ConsolidationRequest,
DepositRequest,
Environment,
Expand Down Expand Up @@ -82,6 +83,7 @@
"Account",
"Address",
"Alloc",
"AuthorizationTuple",
"BaseFixture",
"BaseTest",
"Block",
Expand Down
2 changes: 2 additions & 0 deletions src/ethereum_test_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
AccessList,
Account,
Alloc,
AuthorizationTuple,
CamelModel,
ConsolidationRequest,
DepositRequest,
Expand All @@ -34,6 +35,7 @@
"AccessList",
"Account",
"Alloc",
"AuthorizationTuple",
"CamelModel",
"ConsolidationRequest",
"DepositRequest",
Expand Down
Loading

0 comments on commit 1e1e3cf

Please sign in to comment.