Skip to content

Commit

Permalink
Merge branch 'main' into docs/update-github-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
danceratopz committed Sep 30, 2024
2 parents 24b0a69 + 8fe1c23 commit c7dce1b
Show file tree
Hide file tree
Showing 21 changed files with 109 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .github/actions/setup-uv/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ runs:
- name: Install UV
shell: bash
run: |
UV_VERSION="0.4.2"
UV_VERSION="0.4.17"
echo "Installing UV version $UV_VERSION..."
curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh
15 changes: 8 additions & 7 deletions .github/workflows/tox_verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ jobs:
strategy:
matrix:
include:
- os: ubuntu-24.04
python: "3.10"
evm-type: "stable"
tox-cmd: "uvx --with=tox-uv tox" # run-parallel --parallel-no-spinner" # TODO: disable parallelisation for uv testing
- os: ubuntu-24.04
# Temporarily disable
# - os: ubuntu-latest
# python: "3.10"
# evm-type: "stable"
# tox-cmd: "uvx --with=tox-uv tox" # run-parallel --parallel-no-spinner" # TODO: disable parallelisation for uv testing
- os: ubuntu-latest
python: "3.12"
evm-type: "stable"
tox-cmd: "uvx --with=tox-uv tox" # run-parallel --parallel-no-spinner"
# Disabled due to unavailable evm implementation for devnet-1
# - os: ubuntu-24.04
# - os: ubuntu-latest
# python: '3.11'
# evm-type: 'develop'
# tox-cmd: 'tox -e tests-develop'
# Disabled to not be gated by evmone implementation
# - os: ubuntu-24.04
# - os: ubuntu-latest
# python: '3.11'
# evm-type: 'eip7692'
# tox-cmd: 'tox -e tests-eip7692'
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- 🐞 Fix `Conditional` code generator in EOF mode ([#821](https://github.com/ethereum/execution-spec-tests/pull/821))
- 🔀 `ethereum_test_rpc` library has been created with what was previously `ethereum_test_tools.rpc` ([#822](https://github.com/ethereum/execution-spec-tests/pull/822))
- ✨ Add `Wei` type to `ethereum_test_base_types` which allows parsing wei amounts from strings like "1 ether", "1000 wei", "10**2 gwei", etc ([#825](https://github.com/ethereum/execution-spec-tests/pull/825))
- 🔀 Replace `ethereum.base_types` with `ethereum-types` ([#850](https://github.com/ethereum/execution-spec-tests/pull/850))

### 🔧 EVM Tools

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ dependencies = [
"rich>=13.7.0,<14",
"solc-select>=1.0.4,<2",
"filelock>=3.15.1,<4",
"ethereum-types>=0.2.1,<0.3",
]

[project.urls]
Expand Down
4 changes: 2 additions & 2 deletions src/ethereum_test_base_types/base_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ def or_none(cls, input: "Bytes | BytesConvertible | None") -> "Bytes | None":
return input
return cls(input)

def keccak256(self) -> "Bytes":
def keccak256(self) -> "Hash":
"""
Return the keccak256 hash of the opcode byte representation.
"""
k = keccak.new(digest_bits=256)
return Bytes(k.update(bytes(self)).digest())
return Hash(k.update(bytes(self)).digest())


S = TypeVar("S", bound="FixedSizeHexNumber")
Expand Down
5 changes: 2 additions & 3 deletions src/ethereum_test_fixtures/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
from typing import Annotated, Any, ClassVar, List, Literal, Tuple, Union, get_args, get_type_hints

from ethereum import rlp as eth_rlp
from ethereum.base_types import Uint
from ethereum.crypto.hash import keccak256
from ethereum_types.numeric import Uint
from pydantic import AliasChoices, Field, PlainSerializer, computed_field

from ethereum_test_base_types import (
Expand Down Expand Up @@ -182,7 +181,7 @@ def block_hash(self) -> Hash:
"""
Compute the RLP of the header
"""
return Hash(keccak256(self.rlp))
return self.rlp.keccak256()


class FixtureExecutionPayload(CamelModel):
Expand Down
15 changes: 5 additions & 10 deletions src/ethereum_test_fixtures/tests/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,7 @@
"excessBlobGas": hex(18),
"blockHash": "0xd90115b7fde329f64335763a446af150ab67e639281dccdb07a007d18bb80211",
"transactions": [
"0x"
+ Transaction(
Transaction(
to=0x1234,
data=b"\x01\x00",
access_list=[
Expand Down Expand Up @@ -735,8 +734,7 @@
"0x8eca4747db6a4b272018f2850e4208b863989ce9971bb1907467ae2204950695"
),
"transactions": [
"0x"
+ Transaction(
Transaction(
to=0x1234,
data=b"\x01\x00",
access_list=[
Expand Down Expand Up @@ -914,8 +912,7 @@
"0x78a4bf2520248e0b403d343c32b6746a43da1ebcf3cc8de14b959bc9f461fe76"
),
"transactions": [
"0x"
+ Transaction(
Transaction(
to=0x1234,
data=b"\x01\x00",
access_list=[
Expand Down Expand Up @@ -1082,8 +1079,7 @@ def test_json_deserialization(
"blockHash": "0xd90115b7fde329f64335763a446af1"
"50ab67e639281dccdb07a007d18bb80211",
"transactions": [
"0x"
+ Transaction(
Transaction(
to=0x1234,
data=b"\x01\x00",
access_list=[
Expand Down Expand Up @@ -1193,8 +1189,7 @@ def test_json_deserialization(
"blockHash": "0xd90115b7fde329f64335763a446af1"
"50ab67e639281dccdb07a007d18bb80211",
"transactions": [
"0x"
+ Transaction(
Transaction(
to=0x1234,
data=b"\x01\x00",
access_list=[
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 @@ -56,6 +56,7 @@
copy_opcode_cost,
cost_memory_bytes,
eip_2028_transaction_data_cost,
keccak256,
)
from ethereum_test_vm import (
Bytecode,
Expand Down Expand Up @@ -151,5 +152,6 @@
"eip_2028_transaction_data_cost",
"eip_2028_transaction_data_cost",
"extend_with_defaults",
"keccak256",
"vm",
)
2 changes: 2 additions & 0 deletions src/ethereum_test_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
Transaction,
Withdrawal,
WithdrawalRequest,
keccak256,
)

__all__ = (
Expand Down Expand Up @@ -64,5 +65,6 @@
"copy_opcode_cost",
"cost_memory_bytes",
"eip_2028_transaction_data_cost",
"keccak256",
"to_json",
)
9 changes: 5 additions & 4 deletions src/ethereum_test_types/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from dataclasses import MISSING, dataclass, fields
from typing import List, SupportsBytes

from ethereum.crypto.hash import keccak256
from ethereum.rlp import encode

from ethereum_test_base_types.base_types import Address, Bytes, Hash
Expand Down Expand Up @@ -48,7 +47,7 @@ def compute_create_address(
if nonce is None:
nonce = 0
nonce_bytes = bytes() if nonce == 0 else nonce.to_bytes(length=1, byteorder="big")
hash = keccak256(encode([address, nonce_bytes]))
hash = Bytes(encode([address, nonce_bytes])).keccak256()
return Address(hash[-20:])
if opcode == Op.CREATE2:
return compute_create2_address(address, salt, initcode)
Expand All @@ -62,7 +61,7 @@ def compute_create2_address(
Compute address of the resulting contract created using the `CREATE2`
opcode.
"""
hash = keccak256(b"\xff" + Address(address) + Hash(salt) + keccak256(Bytes(initcode)))
hash = Bytes(b"\xff" + Address(address) + Hash(salt) + Bytes(initcode).keccak256()).keccak256()
return Address(hash[-20:])


Expand Down Expand Up @@ -100,7 +99,9 @@ def compute_eofcreate_address(
"""
Compute address of the resulting contract created using the `EOFCREATE` opcode.
"""
hash = keccak256(b"\xff" + Address(address) + Hash(salt) + keccak256(Bytes(init_container)))
hash = Bytes(
b"\xff" + Address(address) + Hash(salt) + Bytes(init_container).keccak256()
).keccak256()
return Address(hash[-20:])


Expand Down
2 changes: 1 addition & 1 deletion src/ethereum_test_types/tests/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,4 @@ def test_transaction_signing(
assert signature == expected_signature
assert tx.sender is not None
assert tx.sender.hex() == expected_sender
assert ("0x" + tx.rlp.hex()) == expected_serialized
assert (tx.rlp.hex()) == expected_serialized
53 changes: 31 additions & 22 deletions src/ethereum_test_types/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@

from coincurve.keys import PrivateKey, PublicKey
from ethereum import rlp as eth_rlp
from ethereum.base_types import U256, Uint
from ethereum.crypto.hash import keccak256
from ethereum.frontier.fork_types import Account as FrontierAccount
from ethereum.frontier.fork_types import Address as FrontierAddress
from ethereum.frontier.state import State, set_account, set_storage, state_root
from ethereum_types.numeric import U256, Uint
from pydantic import (
BaseModel,
ConfigDict,
Expand Down Expand Up @@ -50,6 +49,13 @@
from ethereum_test_vm import EVMCodeType


def keccak256(data: bytes) -> Hash:
"""
Calculates the keccak256 hash of the given data.
"""
return Bytes(data).keccak256()


# Sentinel classes
class Removable:
"""
Expand Down Expand Up @@ -494,16 +500,19 @@ def to_list(self) -> List[Any]:
]

@cached_property
def signing_bytes(self) -> bytes:
def signing_bytes(self) -> Bytes:
"""
Returns the data to be signed.
"""
return int.to_bytes(self.magic, length=1, byteorder="big") + eth_rlp.encode(
[
Uint(self.chain_id),
self.address,
Uint(self.nonce),
]
return Bytes(
int.to_bytes(self.magic, length=1, byteorder="big")
+ eth_rlp.encode(
[
Uint(self.chain_id),
self.address,
Uint(self.nonce),
]
)
)

def signature(self, private_key: Hash) -> Tuple[int, int, int]:
Expand Down Expand Up @@ -552,7 +561,7 @@ def model_post_init(self, __context: Any) -> None:
+ bytes([self.v])
)
public_key = PublicKey.from_signature_and_message(
signature_bytes, keccak256(self.signing_bytes), hasher=None
signature_bytes, self.signing_bytes.keccak256(), hasher=None
)
self.signer = EOA(
address=Address(keccak256(public_key.format(compressed=False)[1:])[32 - 20 :])
Expand Down Expand Up @@ -668,7 +677,7 @@ class Transaction(TransactionGeneric[HexNumber], TransactionTransitionToolConver
error: List[TransactionException] | TransactionException | None = Field(None, exclude=True)

protected: bool = Field(True, exclude=True)
rlp_override: bytes | None = Field(None, exclude=True)
rlp_override: Bytes | None = Field(None, exclude=True)

wrapped_blob_transaction: bool = Field(False, exclude=True)
blobs: Sequence[Bytes] | None = Field(None, exclude=True)
Expand Down Expand Up @@ -788,7 +797,7 @@ def with_signature_and_sender(self, *, keep_secret_key: bool = False) -> "Transa
return self

public_key = PublicKey.from_signature_and_message(
self.signature_bytes, keccak256(self.signing_bytes), hasher=None
self.signature_bytes, self.signing_bytes.keccak256(), hasher=None
)
updated_values["sender"] = Address(
keccak256(public_key.format(compressed=False)[1:])[32 - 20 :]
Expand All @@ -799,7 +808,7 @@ def with_signature_and_sender(self, *, keep_secret_key: bool = False) -> "Transa
raise ValueError("secret_key must be set to sign a transaction")

# Get the signing bytes
signing_hash = keccak256(self.signing_bytes)
signing_hash = self.signing_bytes.keccak256()

# Sign the bytes
signature_bytes = PrivateKey(secret=self.secret_key).sign_recoverable(
Expand Down Expand Up @@ -984,38 +993,38 @@ def payload_body(self) -> List[Any]:
return signing_envelope + [Uint(self.v), Uint(self.r), Uint(self.s)]

@cached_property
def rlp(self) -> bytes:
def rlp(self) -> Bytes:
"""
Returns bytes of the serialized representation of the transaction,
which is almost always RLP encoding.
"""
if self.rlp_override is not None:
return self.rlp_override
if self.ty > 0:
return bytes([self.ty]) + eth_rlp.encode(self.payload_body)
return Bytes(bytes([self.ty]) + eth_rlp.encode(self.payload_body))
else:
return eth_rlp.encode(self.payload_body)
return Bytes(eth_rlp.encode(self.payload_body))

@cached_property
def hash(self) -> Hash:
"""
Returns hash of the transaction.
"""
return Hash(keccak256(self.rlp))
return self.rlp.keccak256()

@cached_property
def signing_bytes(self) -> bytes:
def signing_bytes(self) -> Bytes:
"""
Returns the serialized bytes of the transaction used for signing.
"""
return (
return Bytes(
bytes([self.ty]) + eth_rlp.encode(self.signing_envelope)
if self.ty > 0
else eth_rlp.encode(self.signing_envelope)
)

@cached_property
def signature_bytes(self) -> bytes:
def signature_bytes(self) -> Bytes:
"""
Returns the serialized bytes of the transaction signature.
"""
Expand All @@ -1027,7 +1036,7 @@ def signature_bytes(self) -> bytes:
v -= 35 + (self.chain_id * 2)
else:
v -= 27
return (
return Bytes(
self.r.to_bytes(32, byteorder="big")
+ self.s.to_bytes(32, byteorder="big")
+ bytes([v])
Expand Down Expand Up @@ -1074,7 +1083,7 @@ def created_contract(self) -> Address:
)
if self.sender is None:
raise ValueError("sender address is None")
hash = keccak256(eth_rlp.encode([self.sender, nonce_bytes]))
hash = Bytes(eth_rlp.encode([self.sender, nonce_bytes])).keccak256()
return Address(hash[-20:])


Expand Down
6 changes: 3 additions & 3 deletions src/ethereum_test_vm/bytecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
from typing import SupportsBytes

from ethereum.crypto.hash import keccak256
from ethereum_test_base_types import Bytes, Hash


class Bytecode:
Expand Down Expand Up @@ -216,8 +216,8 @@ def hex(self) -> str:
"""
return bytes(self).hex()

def keccak256(self) -> bytes:
def keccak256(self) -> Hash:
"""
Return the keccak256 hash of the opcode byte representation.
"""
return keccak256(self._bytes_)
return Bytes(self._bytes_).keccak256()
Loading

0 comments on commit c7dce1b

Please sign in to comment.