Skip to content

Commit

Permalink
forks: Implement fork operators, remove is_fork (#367)
Browse files Browse the repository at this point in the history
* ethereum_test_forks: implement fork operators, remove `is_fork`

* changelog
  • Loading branch information
marioevz authored Dec 21, 2023
1 parent 23fe412 commit 19a02ec
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 28 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- ✨ Add a `--single-fixture-per-file` flag to generate one fixture JSON file per test case ([#331](https://github.com/ethereum/execution-spec-tests/pull/331)).
- 🔀 Rename test fixtures names to match the corresponding pytest node ID as generated using `fill` ([#342](https://github.com/ethereum/execution-spec-tests/pull/342)).
- 💥 Replace "=" with "_" in pytest node ids and test fixture names ([#342](https://github.com/ethereum/execution-spec-tests/pull/342)).
- ✨ Fork objects used to write tests can now be compared using the `>`, `>=`, `<`, `<=` operators, to check for a fork being newer than, newer than or equal, older than, older than or equal, respectively when compared against other fork ([#367](https://github.com/ethereum/execution-spec-tests/pull/367))

### 🔧 EVM Tools

Expand Down
2 changes: 0 additions & 2 deletions src/ethereum_test_forks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
get_development_forks,
get_forks,
get_transition_forks,
is_fork,
transition_fork_from_to,
transition_fork_to,
)
Expand Down Expand Up @@ -64,7 +63,6 @@
"get_deployed_forks",
"get_development_forks",
"get_forks",
"is_fork",
"transition_fork_from_to",
"transition_fork_to",
]
24 changes: 24 additions & 0 deletions src/ethereum_test_forks/base_fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,30 @@ def __repr__(cls) -> str:
"""
return cls.name()

def __gt__(cls, other: "BaseForkMeta") -> bool:
"""
Compare if a fork is newer than some other fork.
"""
return cls != other and other.__subclasscheck__(cls)

def __ge__(cls, other: "BaseForkMeta") -> bool:
"""
Compare if a fork is newer than or equal to some other fork.
"""
return other.__subclasscheck__(cls)

def __lt__(cls, other: "BaseForkMeta") -> bool:
"""
Compare if a fork is older than some other fork.
"""
return cls != other and cls.__subclasscheck__(other)

def __le__(cls, other: "BaseForkMeta") -> bool:
"""
Compare if a fork is older than or equal to some other fork.
"""
return cls.__subclasscheck__(other)


class BaseFork(ABC, metaclass=BaseForkMeta):
"""
Expand Down
15 changes: 0 additions & 15 deletions src/ethereum_test_forks/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,3 @@ def forks_from(fork: Fork, deployed_only: bool = True) -> List[Fork]:
else:
latest_fork = get_forks()[-1]
return forks_from_until(fork, latest_fork)


def is_fork(fork: Fork, which: Fork) -> bool:
"""
Returns `True` if `fork` is `which` or beyond, `False otherwise.
"""
prev_fork = fork

while prev_fork != BaseFork:
if prev_fork == which:
return True

prev_fork = prev_fork.__base__

return False
36 changes: 32 additions & 4 deletions src/ethereum_test_forks/tests/test_forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
get_deployed_forks,
get_development_forks,
get_forks,
is_fork,
transition_fork_from_to,
transition_fork_to,
)
Expand Down Expand Up @@ -94,9 +93,38 @@ def test_forks():
assert cast(Fork, MergeToShanghaiAtTime15k).header_withdrawals_required(0, 15_000) is True
assert cast(Fork, MergeToShanghaiAtTime15k).header_withdrawals_required() is True

assert is_fork(Berlin, Berlin) is True
assert is_fork(London, Berlin) is True
assert is_fork(Berlin, Merge) is False
# Test fork comparison
assert Merge > Berlin
assert not Berlin > Merge
assert Berlin < Merge
assert not Merge < Berlin

assert Merge >= Berlin
assert not Berlin >= Merge
assert Berlin <= Merge
assert not Merge <= Berlin

assert London > Berlin
assert not Berlin > London
assert Berlin < London
assert not London < Berlin

assert London >= Berlin
assert not Berlin >= London
assert Berlin <= London
assert not London <= Berlin

assert Berlin >= Berlin
assert Berlin <= Berlin
assert not Berlin > Berlin
assert not Berlin < Berlin

fork = Berlin
assert fork >= Berlin
assert fork <= Berlin
assert not fork > Berlin
assert not fork < Berlin
assert fork == Berlin


def test_get_forks(): # noqa: D103
Expand Down
4 changes: 2 additions & 2 deletions tests/berlin/eip2930_access_list/test_acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from ethereum_test_forks import Fork, London, is_fork
from ethereum_test_forks import Fork, London
from ethereum_test_tools import AccessList, Account, Environment
from ethereum_test_tools import Opcodes as Op
from ethereum_test_tools import StateTestFiller, Transaction
Expand Down Expand Up @@ -60,7 +60,7 @@ def test_access_list(state_test: StateTestFiller, fork: Fork):
nonce=1,
),
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": Account(
balance=0x1BC16D674EC80000 if is_fork(fork, London) else 0x1BC16D674ECB26CE,
balance=0x1BC16D674EC80000 if fork >= London else 0x1BC16D674ECB26CE,
),
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": Account(
balance=0x2CD931,
Expand Down
4 changes: 2 additions & 2 deletions tests/cancun/eip6780_selfdestruct/test_selfdestruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import pytest
from ethereum.crypto.hash import keccak256

from ethereum_test_forks import Cancun, Fork, is_fork
from ethereum_test_forks import Cancun, Fork
from ethereum_test_tools import (
Account,
Block,
Expand Down Expand Up @@ -50,7 +50,7 @@
@pytest.fixture
def eip_enabled(fork: Fork) -> bool:
"""Whether the EIP is enabled or not."""
return is_fork(fork, SELFDESTRUCT_ENABLE_FORK)
return fork >= SELFDESTRUCT_ENABLE_FORK


@pytest.fixture
Expand Down
6 changes: 3 additions & 3 deletions tests/shanghai/eip3651_warm_coinbase/test_warm_coinbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import pytest

from ethereum_test_forks import Shanghai, is_fork
from ethereum_test_forks import Shanghai
from ethereum_test_tools import (
Account,
CodeGasMeasure,
Expand Down Expand Up @@ -117,7 +117,7 @@ def test_warm_coinbase_call_out_of_gas(

post = {}

if use_sufficient_gas and is_fork(fork=fork, which=Shanghai):
if use_sufficient_gas and fork >= Shanghai:
post[caller_address] = Account(
storage={
# On shanghai and beyond, calls with only 100 gas to
Expand Down Expand Up @@ -244,7 +244,7 @@ def test_warm_coinbase_gas_usage(state_test, fork, opcode, code_gas_measure):
measure_address: Account(code=code_gas_measure, balance=1000000000000000000000),
}

if is_fork(fork, Shanghai):
if fork >= Shanghai:
expected_gas = GAS_REQUIRED_CALL_WARM_ACCOUNT # Warm account access cost after EIP-3651
else:
expected_gas = 2600 # Cold account access cost before EIP-3651
Expand Down
1 change: 1 addition & 0 deletions whitelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ stExample
str
streetsidesoftware
subcall
subclasscheck
subdirectories
subdirectory
subgraph
Expand Down

0 comments on commit 19a02ec

Please sign in to comment.