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

new(tests): EIP-7702 - Set EOA account code for one transaction (Devnet-1) #621

Merged
merged 23 commits into from
Jul 23, 2024
Merged
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
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