Skip to content
Closed
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
5 changes: 3 additions & 2 deletions .github/workflows/gh-pages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:

- name: Upload Pages Artifact
id: artifact
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
with:
path: .tox/docs

Expand All @@ -46,6 +46,7 @@ jobs:
permissions:
pages: write
id-token: write
actions: read

environment:
name: github-pages
Expand All @@ -54,4 +55,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion EIP_AUTHORS_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ Please refer the following tutorial for writing new EIP. It takes you through a

In addition to having a reference implementation, it is also very useful for the community and core development if the EIP author concieves and writes test vectors for the EIP. There is a very user friendly framework for writing ethereum tests in the `execution-spec-tests` repository. Please refer to the following guide for writing tests to your EIP.

[Writing Tests with `execution-spec-tests`](https://ethereum.github.io/execution-spec-tests/main/getting_started/quick_start/)
[Writing Tests with `execution-spec-tests`](https://ethereum.github.io/execution-spec-tests/getting_started/quick_start/)
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ python_requires = >=3.10
install_requires =
pycryptodome>=3,<4
coincurve>=20,<21
typing_extensions>=4
typing_extensions>=4.2
py_ecc @ git+https://github.com/petertdavies/py_ecc.git@127184f4c57b1812da959586d0fe8f43bb1a2389
ethereum-types>=0.2.1,<0.3
ethereum-rlp>=0.1.1,<0.2
Expand Down
10 changes: 7 additions & 3 deletions src/ethereum/arrow_glacier/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@

from ethereum.crypto.hash import Hash32, keccak256
from ethereum.ethash import dataset_size, generate_cache, hashimoto_light
from ethereum.exceptions import InvalidBlock, InvalidSenderError
from ethereum.exceptions import (
EthereumException,
InvalidBlock,
InvalidSenderError,
)

from . import vm
from .blocks import Block, Header, Log, Receipt
Expand Down Expand Up @@ -441,7 +445,7 @@ def check_transaction(

def make_receipt(
tx: Transaction,
error: Optional[Exception],
error: Optional[EthereumException],
cumulative_gas_used: Uint,
logs: Tuple[Log, ...],
) -> Union[Bytes, Receipt]:
Expand Down Expand Up @@ -748,7 +752,7 @@ def pay_rewards(

def process_transaction(
env: vm.Environment, tx: Transaction
) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
) -> Tuple[Uint, Tuple[Log, ...], Optional[EthereumException]]:
"""
Execute a transaction against the provided environment.

Expand Down
13 changes: 7 additions & 6 deletions src/ethereum/arrow_glacier/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from dataclasses import dataclass, field
from typing import Callable, Dict, List, Optional, Set, Tuple

from ethereum_types.bytes import Bytes
from ethereum_types.bytes import Bytes, Bytes32
from ethereum_types.frozen import modify
from ethereum_types.numeric import U256, Uint

Expand All @@ -36,12 +36,13 @@ class State:
_main_trie: Trie[Address, Optional[Account]] = field(
default_factory=lambda: Trie(secured=True, default=None)
)
_storage_tries: Dict[Address, Trie[Bytes, U256]] = field(
_storage_tries: Dict[Address, Trie[Bytes32, U256]] = field(
default_factory=dict
)
_snapshots: List[
Tuple[
Trie[Address, Optional[Account]], Dict[Address, Trie[Bytes, U256]]
Trie[Address, Optional[Account]],
Dict[Address, Trie[Bytes32, U256]],
]
] = field(default_factory=list)
created_accounts: Set[Address] = field(default_factory=set)
Expand Down Expand Up @@ -228,7 +229,7 @@ def mark_account_created(state: State, address: Address) -> None:
state.created_accounts.add(address)


def get_storage(state: State, address: Address, key: Bytes) -> U256:
def get_storage(state: State, address: Address, key: Bytes32) -> U256:
"""
Get a value at a storage key on an account. Returns `U256(0)` if the
storage key has not been set previously.
Expand Down Expand Up @@ -258,7 +259,7 @@ def get_storage(state: State, address: Address, key: Bytes) -> U256:


def set_storage(
state: State, address: Address, key: Bytes, value: U256
state: State, address: Address, key: Bytes32, value: U256
) -> None:
"""
Set a value at a storage key on an account. Setting to `U256(0)` deletes
Expand Down Expand Up @@ -599,7 +600,7 @@ def increase_balance(account: Account) -> None:
modify_state(state, address, increase_balance)


def get_storage_original(state: State, address: Address, key: Bytes) -> U256:
def get_storage_original(state: State, address: Address, key: Bytes32) -> U256:
"""
Get the original value in a storage slot i.e. the value before the current
transaction began. This function reads the value from the snapshots taken
Expand Down
4 changes: 4 additions & 0 deletions src/ethereum/arrow_glacier/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,14 @@ def recover_sender(chain_id: U64, tx: Transaction) -> Address:
signing_hash_155(tx, chain_id),
)
elif isinstance(tx, AccessListTransaction):
if tx.y_parity not in (U256(0), U256(1)):
raise InvalidSignatureError("bad y_parity")
public_key = secp256k1_recover(
r, s, tx.y_parity, signing_hash_2930(tx)
)
elif isinstance(tx, FeeMarketTransaction):
if tx.y_parity not in (U256(0), U256(1)):
raise InvalidSignatureError("bad y_parity")
public_key = secp256k1_recover(
r, s, tx.y_parity, signing_hash_1559(tx)
)
Expand Down
36 changes: 30 additions & 6 deletions src/ethereum/arrow_glacier/trie.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@
MutableMapping,
Optional,
Sequence,
Tuple,
TypeVar,
Union,
cast,
)

from ethereum_rlp import rlp
from ethereum_types.bytes import Bytes
from ethereum_types.frozen import slotted_freezable
from ethereum_types.numeric import U256, Uint
from typing_extensions import assert_type

from ethereum.crypto.hash import keccak256
from ethereum.london import trie as previous_trie
Expand Down Expand Up @@ -92,12 +95,32 @@ class ExtensionNode:
subnode: rlp.Extended


BranchSubnodes = Tuple[
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
rlp.Extended,
]


@slotted_freezable
@dataclass
class BranchNode:
"""Branch node in the Merkle Trie"""

subnodes: List[rlp.Extended]
subnodes: BranchSubnodes
value: rlp.Extended


Expand Down Expand Up @@ -137,7 +160,7 @@ def encode_internal_node(node: Optional[InternalNode]) -> rlp.Extended:
node.subnode,
)
elif isinstance(node, BranchNode):
unencoded = node.subnodes + [node.value]
unencoded = list(node.subnodes) + [node.value]
else:
raise AssertionError(f"Invalid internal node type {type(node)}!")

Expand Down Expand Up @@ -458,10 +481,11 @@ def patricialize(
else:
branches[key[level]][key] = obj[key]

subnodes = tuple(
encode_internal_node(patricialize(branches[k], level + Uint(1)))
for k in range(16)
)
return BranchNode(
[
encode_internal_node(patricialize(branches[k], level + Uint(1)))
for k in range(16)
],
cast(BranchSubnodes, assert_type(subnodes, Tuple[rlp.Extended, ...])),
value,
)
3 changes: 2 additions & 1 deletion src/ethereum/arrow_glacier/vm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from ethereum_types.numeric import U64, U256, Uint

from ethereum.crypto.hash import Hash32
from ethereum.exceptions import EthereumException

from ..blocks import Log
from ..fork_types import Address
Expand Down Expand Up @@ -91,7 +92,7 @@ class Evm:
accounts_to_delete: Set[Address]
touched_accounts: Set[Address]
return_data: Bytes
error: Optional[Exception]
error: Optional[EthereumException]
accessed_addresses: Set[Address]
accessed_storage_keys: Set[Tuple[Address, Bytes32]]

Expand Down
8 changes: 5 additions & 3 deletions src/ethereum/arrow_glacier/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

A straightforward interpreter that executes EVM code.
"""

from dataclasses import dataclass
from typing import Iterable, Optional, Set, Tuple
from typing import Optional, Set, Tuple

from ethereum_types.bytes import Bytes0
from ethereum_types.numeric import U256, Uint, ulen

from ethereum.exceptions import EthereumException
from ethereum.trace import (
EvmStop,
OpEnd,
Expand Down Expand Up @@ -83,8 +85,8 @@ class MessageCallOutput:
refund_counter: U256
logs: Tuple[Log, ...]
accounts_to_delete: Set[Address]
touched_accounts: Iterable[Address]
error: Optional[Exception]
touched_accounts: Set[Address]
error: Optional[EthereumException]


def process_message_call(
Expand Down
10 changes: 7 additions & 3 deletions src/ethereum/berlin/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@

from ethereum.crypto.hash import Hash32, keccak256
from ethereum.ethash import dataset_size, generate_cache, hashimoto_light
from ethereum.exceptions import InvalidBlock, InvalidSenderError
from ethereum.exceptions import (
EthereumException,
InvalidBlock,
InvalidSenderError,
)

from . import vm
from .blocks import Block, Header, Log, Receipt
Expand Down Expand Up @@ -343,7 +347,7 @@ def check_transaction(

def make_receipt(
tx: Transaction,
error: Optional[Exception],
error: Optional[EthereumException],
cumulative_gas_used: Uint,
logs: Tuple[Log, ...],
) -> Union[Bytes, Receipt]:
Expand Down Expand Up @@ -642,7 +646,7 @@ def pay_rewards(

def process_transaction(
env: vm.Environment, tx: Transaction
) -> Tuple[Uint, Tuple[Log, ...], Optional[Exception]]:
) -> Tuple[Uint, Tuple[Log, ...], Optional[EthereumException]]:
"""
Execute a transaction against the provided environment.

Expand Down
13 changes: 7 additions & 6 deletions src/ethereum/berlin/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from dataclasses import dataclass, field
from typing import Callable, Dict, List, Optional, Set, Tuple

from ethereum_types.bytes import Bytes
from ethereum_types.bytes import Bytes, Bytes32
from ethereum_types.frozen import modify
from ethereum_types.numeric import U256, Uint

Expand All @@ -36,12 +36,13 @@ class State:
_main_trie: Trie[Address, Optional[Account]] = field(
default_factory=lambda: Trie(secured=True, default=None)
)
_storage_tries: Dict[Address, Trie[Bytes, U256]] = field(
_storage_tries: Dict[Address, Trie[Bytes32, U256]] = field(
default_factory=dict
)
_snapshots: List[
Tuple[
Trie[Address, Optional[Account]], Dict[Address, Trie[Bytes, U256]]
Trie[Address, Optional[Account]],
Dict[Address, Trie[Bytes32, U256]],
]
] = field(default_factory=list)
created_accounts: Set[Address] = field(default_factory=set)
Expand Down Expand Up @@ -228,7 +229,7 @@ def mark_account_created(state: State, address: Address) -> None:
state.created_accounts.add(address)


def get_storage(state: State, address: Address, key: Bytes) -> U256:
def get_storage(state: State, address: Address, key: Bytes32) -> U256:
"""
Get a value at a storage key on an account. Returns `U256(0)` if the
storage key has not been set previously.
Expand Down Expand Up @@ -258,7 +259,7 @@ def get_storage(state: State, address: Address, key: Bytes) -> U256:


def set_storage(
state: State, address: Address, key: Bytes, value: U256
state: State, address: Address, key: Bytes32, value: U256
) -> None:
"""
Set a value at a storage key on an account. Setting to `U256(0)` deletes
Expand Down Expand Up @@ -599,7 +600,7 @@ def increase_balance(account: Account) -> None:
modify_state(state, address, increase_balance)


def get_storage_original(state: State, address: Address, key: Bytes) -> U256:
def get_storage_original(state: State, address: Address, key: Bytes32) -> U256:
"""
Get the original value in a storage slot i.e. the value before the current
transaction began. This function reads the value from the snapshots taken
Expand Down
2 changes: 2 additions & 0 deletions src/ethereum/berlin/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ def recover_sender(chain_id: U64, tx: Transaction) -> Address:
signing_hash_155(tx, chain_id),
)
elif isinstance(tx, AccessListTransaction):
if tx.y_parity not in (U256(0), U256(1)):
raise InvalidSignatureError("bad y_parity")
public_key = secp256k1_recover(
r, s, tx.y_parity, signing_hash_2930(tx)
)
Expand Down
Loading