Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""
EIP-7997: Deterministic Factory Predeploy.

Predeploy a minimal `CREATE2` factory at address `0x12` so deterministic
deployments are available across chains without bootstrapping transactions.

https://eips.ethereum.org/EIPS/eip-7997
"""

from typing import Mapping

from execution_testing.base_types import Address

from ....base_fork import BaseFork

DETERMINISTIC_FACTORY_PREDEPLOY_ADDRESS = 0x12
DETERMINISTIC_FACTORY_PREDEPLOY_BYTECODE = bytes.fromhex(
"60203610602f57"
"60003560203603806020600037600034f5"
"806026573d600060003e3d6000fd"
"5b60005260206000f3"
"5b60006000fd"
)


class EIP7997(BaseFork):
"""EIP-7997 class."""

@classmethod
def deterministic_factory_predeploy_address(cls) -> Address | None:
"""Return the EIP-7997 deterministic factory predeploy address."""
return Address(
DETERMINISTIC_FACTORY_PREDEPLOY_ADDRESS,
label="DETERMINISTIC_FACTORY_PREDEPLOY_ADDRESS",
)

@classmethod
def pre_allocation(cls) -> Mapping:
"""Pre-allocate the deterministic factory predeploy."""
return {
DETERMINISTIC_FACTORY_PREDEPLOY_ADDRESS: {
"nonce": 1,
"code": DETERMINISTIC_FACTORY_PREDEPLOY_BYTECODE,
}
} | super(EIP7997, cls).pre_allocation() # type: ignore

@classmethod
def pre_allocation_blockchain(cls) -> Mapping:
"""Pre-allocate the deterministic factory predeploy."""
return {
DETERMINISTIC_FACTORY_PREDEPLOY_ADDRESS: {
"nonce": 1,
"code": DETERMINISTIC_FACTORY_PREDEPLOY_BYTECODE,
}
} | super(EIP7997, cls).pre_allocation_blockchain() # type: ignore
5 changes: 4 additions & 1 deletion src/ethereum/forks/amsterdam/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"""
The Amsterdam fork ([EIP-7773]) includes block-level access lists.
The Amsterdam fork ([EIP-7773]) includes block-level access lists and the
deterministic ``CREATE2`` factory predeploy.

### Changes

- [EIP-7928: Block-Level Access Lists][EIP-7928]
- [EIP-7997: Deterministic Factory Predeploy][EIP-7997]

### Releases

[EIP-7773]: https://eips.ethereum.org/EIPS/eip-7773
[EIP-7928]: https://eips.ethereum.org/EIPS/eip-7928
[EIP-7997]: https://eips.ethereum.org/EIPS/eip-7997
"""

from ethereum.fork_criteria import ForkCriteria, Unscheduled
Expand Down
26 changes: 26 additions & 0 deletions src/ethereum/forks/amsterdam/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@
from ethereum.merkle_patricia_trie import root, trie_set
from ethereum.state import (
EMPTY_CODE_HASH,
Account,
Address,
BlockDiff,
State,
apply_changes_to_state,
set_account,
store_code,
)

from . import vm
Expand Down Expand Up @@ -126,6 +129,14 @@
HISTORY_STORAGE_ADDRESS = hex_to_address(
"0x0000F90827F1C53a10cb7A02335B175320002935"
)
DETERMINISTIC_FACTORY_ADDRESS = hex_to_address("0x12")
DETERMINISTIC_FACTORY_CODE = bytes.fromhex(
"60203610602f57"
"60003560203603806020600037600034f5"
"806026573d600060003e3d6000fd"
"5b60005260206000f3"
"5b60006000fd"
)
MAX_BLOCK_SIZE = 10_485_760
SAFETY_MARGIN = 2_097_152
MAX_RLP_BLOCK_SIZE = MAX_BLOCK_SIZE - SAFETY_MARGIN
Expand Down Expand Up @@ -169,6 +180,12 @@ def apply_fork(old: BlockChain) -> BlockChain:
is used to handle the irregularity. See the :ref:`DAO Fork <dao-fork>` for
an example.

EIP-7997 introduces a deterministic `CREATE2` factory at
[`DETERMINISTIC_FACTORY_ADDRESS`]. The factory bytecode is injected
directly into state at fork activation so the same factory address is
available across chains without relying on a one-shot deployment
transaction.

Parameters
----------
old :
Expand All @@ -179,7 +196,16 @@ def apply_fork(old: BlockChain) -> BlockChain:
new : `BlockChain`
Upgraded block chain object for this hard fork.

[`DETERMINISTIC_FACTORY_ADDRESS`]:
ref:ethereum.forks.amsterdam.fork.DETERMINISTIC_FACTORY_ADDRESS

"""
code_hash = store_code(old.state, DETERMINISTIC_FACTORY_CODE)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I did not know we had this functionality!

I'm not sure though how do we signal from the tests that a block is the first block in the fork?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marioevz I'm not sure what you mean by:

I'm not sure though how do we signal from the tests that a block is the first block in the fork?

Can you clarify? AFAIK, the tests don't call apply_fork, and AIUI, we'd have to test with a pre_alloc mutable as discussed below, for inherently not a great test. This is also highlighted in the codecov report since there is not a great way to test this method. Let me know if you see another way though! I'm happy to update.

set_account(
old.state,
DETERMINISTIC_FACTORY_ADDRESS,
Account(nonce=Uint(1), balance=U256(0), code_hash=code_hash),
)
return old


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for EIP-7997: Deterministic Factory Predeploy."""
31 changes: 31 additions & 0 deletions tests/amsterdam/eip7997_deterministic_factory_predeploy/spec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Reference spec for [EIP-7997: Deterministic Factory Predeploy](https://eips.ethereum.org/EIPS/eip-7997)."""

from dataclasses import dataclass


@dataclass(frozen=True)
class ReferenceSpec:
"""Reference specification."""

git_path: str
version: str


ref_spec_7997 = ReferenceSpec(
git_path="EIPS/eip-7997.md",
version="ec05b85e530a7ea97ea52a1f0312d88eb0eb1be2",
)


@dataclass(frozen=True)
class Spec:
"""Constants from EIP-7997."""

FACTORY_ADDRESS: int = 0x12
FACTORY_BYTECODE: bytes = bytes.fromhex(
"60203610602f57"
"60003560203603806020600037600034f5"
"806026573d600060003e3d6000fd"
"5b60005260206000f3"
"5b60006000fd"
)
Loading
Loading