Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
37203e6
prague initial commit
gurukamath Apr 23, 2024
755c770
changes for prague
gurukamath Apr 23, 2024
5fe9651
Remove ensure from prague
SamWilsn May 1, 2024
a27b82b
implement eip-2935
gurukamath Apr 29, 2024
f95dd71
Implement EIP-7685
gurukamath May 2, 2024
20b7e0e
Implement EIP-6110
gurukamath May 3, 2024
ffa22a1
post-review updates
gurukamath May 4, 2024
31323a1
disable optimized tests
gurukamath May 13, 2024
ce42278
Sort prague instructions (#942)
SamWilsn Jun 17, 2024
bbe560e
Implement EIP-7002
gurukamath May 14, 2024
4d77a31
update the t8n tool for EIP-7002
gurukamath May 14, 2024
53b9014
backport changes to cancun
gurukamath May 14, 2024
ad13814
refactor based on review comments
gurukamath May 22, 2024
a2d9865
Withdrawal length constant
gurukamath Jun 18, 2024
08c68c3
Fix flake8 issues
SamWilsn Jun 19, 2024
4581b39
Port #973 to prague
SamWilsn Jul 3, 2024
90ce8d4
update EIP-2935 to latest spec
gurukamath Jun 11, 2024
e46144d
Port #968 to prague
SamWilsn Aug 13, 2024
5bec7f1
Implement bls12 381 G1 Addition
gurukamath May 15, 2024
976966f
implement G1 multiplication
gurukamath May 15, 2024
ccddda9
implement G1 msm
gurukamath May 16, 2024
cba0ce3
implement g2 add, mul and msm
gurukamath May 16, 2024
dcd2413
refactor
gurukamath May 16, 2024
3e4b256
add pairing pre-compile
gurukamath May 17, 2024
34a4a3d
update bls12 281 tests for prague
gurukamath May 23, 2024
eae9ba4
add BLS12_MAP_FP2_TO_G2 pre-compile
gurukamath May 30, 2024
8385a51
remove dependence on eth2spec
gurukamath Jun 10, 2024
992e009
Add G1 hash to curve precompile
petertdavies Jul 18, 2024
54384a9
post-review update 1
gurukamath Aug 2, 2024
6d8a5e0
update history storage address
gurukamath Aug 19, 2024
41bf7b1
Implement EIP-7251
gurukamath Aug 19, 2024
b8822f3
re-factor requests
gurukamath Aug 19, 2024
2b16bea
update t8n tool to process consolidation requests
gurukamath Aug 19, 2024
05b90ff
support test filling with t8n
gurukamath Aug 19, 2024
d73b13f
post-review updates 2
gurukamath Aug 20, 2024
18145e8
port updates to EIP-2935
gurukamath Aug 20, 2024
f26ffd7
run latest test suite
gurukamath Aug 20, 2024
4392d7c
post-review updates
gurukamath Aug 28, 2024
218ce91
Merge pull request #991 from gurukamath/eips/prague/eip-7251
gurukamath Aug 29, 2024
55637aa
port changes from #991
gurukamath Aug 19, 2024
1e88605
update to latest test suite
gurukamath Aug 29, 2024
8638491
Merge branch 'forks/prague' into eips/prague/eip-2537
gurukamath Aug 29, 2024
f66766d
mark slow tests
gurukamath Aug 30, 2024
a6f5eae
Merge pull request #956 from ethereum/eips/prague/eip-2537
gurukamath Aug 31, 2024
6544a4e
Update EIP-2935
gurukamath Sep 9, 2024
81616a4
Use correct constant in `t8n/__init__.py`
petertdavies Sep 9, 2024
16a5b20
Merge pull request #1001 from gurukamath/eips/prague/eip-2935-1
petertdavies Sep 9, 2024
2bb8498
Merge pull request #1003 from ethereum/master
petertdavies Sep 11, 2024
c8df873
update genesis for prague
gurukamath Sep 19, 2024
2624730
add checks to signature recovery
gurukamath Sep 19, 2024
05e7756
update error handling
gurukamath Sep 19, 2024
10125b1
Merge pull request #1011 from gurukamath/sig-recovery-checks
gurukamath Sep 19, 2024
47c5a6b
Implement EIP-7702
gurukamath Sep 8, 2024
188c9aa
add signature checks in authorization
gurukamath Sep 19, 2024
d53bf9a
Merge pull request #1000 from ethereum/eips/prague/eip-7702
petertdavies Sep 19, 2024
cca9183
Minor Prague t8n fixes
petertdavies Sep 19, 2024
7b15c68
Implement EIP-7610
gurukamath Sep 7, 2024
65f9ff7
Merge pull request #999 from gurukamath/eip-7610
gurukamath Sep 25, 2024
2875a73
Merge pull request #1013 from petertdavies/minor-prague-t8n-fixes
petertdavies Sep 25, 2024
0248192
make requests opaque
gurukamath Sep 27, 2024
a58ab4a
requests as bytes
gurukamath Sep 30, 2024
8a91398
update requests per pectra-devnet4 spec
gurukamath Oct 16, 2024
9fe369a
implement 7702 updates
gurukamath Oct 18, 2024
af31289
post review updates
gurukamath Oct 22, 2024
a95b7aa
Merge pull request #1016 from gurukamath/update-requests
petertdavies Oct 24, 2024
b9b7f63
Extract t8n arguments from daemon query string
SamWilsn Nov 6, 2024
5278aa0
Merge pull request #1039 from SamWilsn/prague-query-string
petertdavies Nov 21, 2024
4e18716
Remove request type byte in T8N
petertdavies Nov 22, 2024
34f100d
style: fix black
danceratopz Nov 25, 2024
6e3cb10
chore: fix mypy; requests is a list
danceratopz Nov 25, 2024
5e35d1d
Merge pull request #2 from danceratopz/fix-t8n-requests-tox
petertdavies Nov 25, 2024
1ea4a8d
Merge pull request #1040 from petertdavies/fix-t8n-requests
petertdavies Nov 25, 2024
8e37d2f
refactor Env for prague and cancun
gurukamath Dec 12, 2024
36365a5
change env to block_env
gurukamath Dec 13, 2024
c4cb645
create transaction scoped environment
gurukamath Dec 13, 2024
10f3a27
update-t8n
gurukamath Dec 15, 2024
c0bd64c
port changes to prague
gurukamath Dec 16, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:

- name: Run Tox (CPython)
if: "${{ !startsWith(matrix.py, 'pypy') }}"
run: tox -e static,optimized,py3
run: tox -e static,py3

- name: Run Tox (PyPy)
if: "${{ startsWith(matrix.py, 'pypy') }}"
Expand Down
8 changes: 7 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ packages =
ethereum/cancun/vm
ethereum/cancun/vm/instructions
ethereum/cancun/vm/precompiled_contracts
ethereum/prague
ethereum/prague/utils
ethereum/prague/vm
ethereum/prague/vm/instructions
ethereum/prague/vm/precompiled_contracts
ethereum/prague/vm/precompiled_contracts/bls12_381


package_dir =
Expand All @@ -114,7 +120,7 @@ install_requires =
pycryptodome>=3,<4
coincurve>=20,<21
typing_extensions>=4
eth2spec @ git+https://github.com/ethereum/consensus-specs.git@d08a91cad5a8657e57750b7cfe3ac2178b3d9c0c
py_ecc @ git+https://github.com/petertdavies/py_ecc.git@127184f4c57b1812da959586d0fe8f43bb1a2389

[options.package_data]
ethereum =
Expand Down
37 changes: 21 additions & 16 deletions src/ethereum/arrow_glacier/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from typing import List, Optional, Set, Tuple, Union

from ethereum.base_types import Bytes0
from ethereum.crypto import InvalidSignature
from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.ethash import dataset_size, generate_cache, hashimoto_light
Expand Down Expand Up @@ -417,6 +418,7 @@ def check_transaction(
"""
if tx.gas > gas_available:
raise InvalidBlock

sender_address = recover_sender(chain_id, tx)

if isinstance(tx, FeeMarketTransaction):
Expand Down Expand Up @@ -958,26 +960,29 @@ def recover_sender(chain_id: U64, tx: Transaction) -> Address:
if 0 >= s or s > SECP256K1N // 2:
raise InvalidBlock

if isinstance(tx, LegacyTransaction):
v = tx.v
if v == 27 or v == 28:
try:
if isinstance(tx, LegacyTransaction):
v = tx.v
if v == 27 or v == 28:
public_key = secp256k1_recover(
r, s, v - 27, signing_hash_pre155(tx)
)
else:
if v != 35 + chain_id * 2 and v != 36 + chain_id * 2:
raise InvalidBlock
public_key = secp256k1_recover(
r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
)
elif isinstance(tx, AccessListTransaction):
public_key = secp256k1_recover(
r, s, v - 27, signing_hash_pre155(tx)
r, s, tx.y_parity, signing_hash_2930(tx)
)
else:
if v != 35 + chain_id * 2 and v != 36 + chain_id * 2:
raise InvalidBlock
elif isinstance(tx, FeeMarketTransaction):
public_key = secp256k1_recover(
r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
r, s, tx.y_parity, signing_hash_1559(tx)
)
elif isinstance(tx, AccessListTransaction):
public_key = secp256k1_recover(
r, s, tx.y_parity, signing_hash_2930(tx)
)
elif isinstance(tx, FeeMarketTransaction):
public_key = secp256k1_recover(
r, s, tx.y_parity, signing_hash_1559(tx)
)
except InvalidSignature as e:
raise InvalidBlock from e

return Address(keccak256(public_key)[12:32])

Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/arrow_glacier/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,13 +362,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/arrow_glacier/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -88,7 +89,9 @@ def generic_create(
push(evm.stack, U256(0))
return

if account_has_code_or_nonce(evm.env.state, contract_address):
if account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
return
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/arrow_glacier/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -107,7 +108,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
Implementation of the ECRECOVER precompiled contract.
"""
from ethereum.base_types import U256
from ethereum.crypto import InvalidSignature
from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.utils.byte import left_pad_zero_bytes
Expand Down Expand Up @@ -52,7 +53,7 @@ def ecrecover(evm: Evm) -> None:

try:
public_key = secp256k1_recover(r, s, v - 27, message_hash)
except ValueError:
except InvalidSignature:
# unable to extract public key
return

Expand Down
57 changes: 57 additions & 0 deletions src/ethereum/base_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,41 @@ def to_signed(self) -> int:
U256.MAX_VALUE = int.__new__(U256, (2**256) - 1)


class U8(FixedUint):
"""
Unsigned positive integer, which can represent `0` to `2 ** 8 - 1`,
inclusive.
"""

MAX_VALUE: ClassVar["U8"]
"""
Largest value that can be represented by this integer type.
"""

__slots__ = ()

@classmethod
def from_le_bytes(cls: Type, buffer: "Bytes1") -> "U8":
"""
Converts a sequence of bytes into an arbitrarily sized unsigned integer
from its little endian representation.
"""
if len(buffer) > 1:
raise ValueError()

return cls(int.from_bytes(buffer, "little"))

def to_le_bytes(self) -> "Bytes1":
"""
Converts this fixed sized unsigned integer into its little endian
representation, with exactly 1 byte.
"""
return Bytes1(self.to_bytes(1, "little"))


U8.MAX_VALUE = int.__new__(U8, (2**8) - 1)


class U32(FixedUint):
"""
Unsigned positive integer, which can represent `0` to `2 ** 32 - 1`,
Expand Down Expand Up @@ -848,6 +883,17 @@ class Bytes0(FixedBytes):
"""


class Bytes1(FixedBytes):
"""
Byte array of exactly a single byte.
"""

LENGTH = 1
"""
Number of bytes in each instance of this class.
"""


class Bytes4(FixedBytes):
"""
Byte array of exactly four elements.
Expand Down Expand Up @@ -911,6 +957,17 @@ class Bytes64(FixedBytes):
"""


class Bytes96(FixedBytes):
"""
Byte array of exactly 96 elements.
"""

LENGTH = 96
"""
Number of bytes in each instance of this class.
"""


class Bytes256(FixedBytes):
"""
Byte array of exactly 256 elements.
Expand Down
33 changes: 19 additions & 14 deletions src/ethereum/berlin/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from typing import List, Optional, Set, Tuple, Union

from ethereum.base_types import Bytes0
from ethereum.crypto import InvalidSignature
from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.ethash import dataset_size, generate_cache, hashimoto_light
Expand Down Expand Up @@ -335,6 +336,7 @@ def check_transaction(
"""
if tx.gas > gas_available:
raise InvalidBlock

sender_address = recover_sender(chain_id, tx)

return sender_address
Expand Down Expand Up @@ -839,22 +841,25 @@ def recover_sender(chain_id: U64, tx: Transaction) -> Address:
if 0 >= s or s > SECP256K1N // 2:
raise InvalidBlock

if isinstance(tx, LegacyTransaction):
v = tx.v
if v == 27 or v == 28:
try:
if isinstance(tx, LegacyTransaction):
v = tx.v
if v == 27 or v == 28:
public_key = secp256k1_recover(
r, s, v - 27, signing_hash_pre155(tx)
)
else:
if v != 35 + chain_id * 2 and v != 36 + chain_id * 2:
raise InvalidBlock
public_key = secp256k1_recover(
r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
)
elif isinstance(tx, AccessListTransaction):
public_key = secp256k1_recover(
r, s, v - 27, signing_hash_pre155(tx)
r, s, tx.y_parity, signing_hash_2930(tx)
)
else:
if v != 35 + chain_id * 2 and v != 36 + chain_id * 2:
raise InvalidBlock
public_key = secp256k1_recover(
r, s, v - 35 - chain_id * 2, signing_hash_155(tx, chain_id)
)
elif isinstance(tx, AccessListTransaction):
public_key = secp256k1_recover(
r, s, tx.y_parity, signing_hash_2930(tx)
)
except InvalidSignature as e:
raise InvalidBlock from e

return Address(keccak256(public_key)[12:32])

Expand Down
21 changes: 20 additions & 1 deletion src/ethereum/berlin/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,13 +362,32 @@ def account_has_code_or_nonce(state: State, address: Address) -> bool:
Returns
-------
has_code_or_nonce : `bool`
True if if an account has non zero nonce or non empty code,
True if the account has non zero nonce or non empty code,
False otherwise.
"""
account = get_account(state, address)
return account.nonce != Uint(0) or account.code != b""


def account_has_storage(state: State, address: Address) -> bool:
"""
Checks if an account has storage.

Parameters
----------
state:
The state
address:
Address of the account that needs to be checked.

Returns
-------
has_storage : `bool`
True if the account has storage, False otherwise.
"""
return address in state._storage_tries


def is_account_empty(state: State, address: Address) -> bool:
"""
Checks if an account has zero nonce, empty code and zero balance.
Expand Down
5 changes: 4 additions & 1 deletion src/ethereum/berlin/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ...state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
get_account,
increment_nonce,
is_account_alive,
Expand Down Expand Up @@ -89,7 +90,9 @@ def generic_create(
push(evm.stack, U256(0))
return

if account_has_code_or_nonce(evm.env.state, contract_address):
if account_has_code_or_nonce(
evm.env.state, contract_address
) or account_has_storage(evm.env.state, contract_address):
increment_nonce(evm.env.state, evm.message.current_target)
push(evm.stack, U256(0))
return
Expand Down
3 changes: 2 additions & 1 deletion src/ethereum/berlin/vm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ..state import (
account_exists_and_is_empty,
account_has_code_or_nonce,
account_has_storage,
begin_transaction,
commit_transaction,
destroy_storage,
Expand Down Expand Up @@ -106,7 +107,7 @@ def process_message_call(
if message.target == Bytes0(b""):
is_collision = account_has_code_or_nonce(
env.state, message.current_target
)
) or account_has_storage(env.state, message.current_target)
if is_collision:
return MessageCallOutput(
Uint(0), U256(0), tuple(), set(), set(), AddressCollision()
Expand Down
Loading