ethereum.fork_criteria

Activation criteria for forks.

Most generally, a fork is a divergence in a blockchain resulting in multiple tips. Most forks are short lived, and can be caused by networking issues or the behavior of block creators. These short-lived forks resolve themselves according to the rules of the protocol, eventually settling back to a single tip of the chain.

A second class of forks are intentionally created by changing the rules of the protocol, and never resolve back to a single tip. Older software will continue to follow the original fork, while updated software will create and follow a new fork.

For these intentional forks to succeed, all participants need to agree on exactly when to switch rules. The agreed upon criteria are represented by subclasses of ForkCriteria, like ByBlockNumber and ByTimestamp. The special type of Unscheduled is used for forks in active development that do not yet have a scheduled deployment.

ForkCriteria

Abstract base class for conditions specifying when a fork activates.

Subclasses override the comparison methods (__eq__ and __lt__) to provide an ordering for forks, and override check to determine whether a particular block meets the activation criteria.

32
@functools.total_ordering
class ForkCriteria:

BLOCK_NUMBER

46
    BLOCK_NUMBER: Final[int] = 0

TIMESTAMP

53
    TIMESTAMP: Final[int] = 1

UNSCHEDULED

60
    UNSCHEDULED: Final[int] = 2

_internal

67
    _internal: Tuple[int, int]

__eq__

Equality for fork criteria.

def __eq__(self, ​​other: object) -> bool:
70
        """
71
        Equality for fork criteria.
72
        """
73
        if isinstance(other, ForkCriteria):
74
            return self._internal == other._internal
75
        return NotImplemented

__lt__

Less-than comparison function, with earlier forks being less than later forks.

All BLOCK_NUMBER forks come before TIMESTAMP forks, and all scheduled forks come before UNSCHEDULED forks.

def __lt__(self, ​​other: object) -> bool:
78
        """
79
        Less-than comparison function, with earlier forks being less than later
80
        forks.
81
82
        All [`BLOCK_NUMBER`] forks come before [`TIMESTAMP`] forks, and all
83
        scheduled forks come before [`UNSCHEDULED`] forks.
84
85
        [`BLOCK_NUMBER`]: ref:ethereum.fork_criteria.ForkCriteria.BLOCK_NUMBER
86
        [`TIMESTAMP`]: ref:ethereum.fork_criteria.ForkCriteria.TIMESTAMP
87
        [`UNSCHEDULED`]: ref:ethereum.fork_criteria.ForkCriteria.UNSCHEDULED
88
        """
89
        if isinstance(other, ForkCriteria):
90
            return self._internal < other._internal
91
        return NotImplemented

__hash__

Compute a hash for this instance, so it can be stored in dictionaries.

def __hash__(self) -> int:
94
        """
95
        Compute a hash for this instance, so it can be stored in dictionaries.
96
        """
97
        return hash(self._internal)

check

Check whether fork criteria have been met.

Returns True when the current block meets or exceeds the criteria, and False otherwise.

99
    @abstractmethod
def check(self, ​​block_number: int, ​​timestamp: int) -> bool:
101
        """
102
        Check whether fork criteria have been met.
103
104
        Returns `True` when the current block meets or exceeds the criteria,
105
        and `False` otherwise.
106
        """
107
        raise NotImplementedError()

__repr__

String representation of this object.

109
    @abstractmethod
def __repr__(self) -> str:
111
        """
112
        String representation of this object.
113
        """
114
        raise NotImplementedError()

ByBlockNumber

Forks that occur when a specific block number has been reached.

class ByBlockNumber:

block_number

122
    block_number: int

__init__

def __init__(self, ​​block_number: int):
128
        self._internal = (ForkCriteria.BLOCK_NUMBER, block_number)
129
        self.block_number = block_number

check

Check whether the block number has been reached.

Returns True when the given block_number is equal to or greater than block_number, and False otherwise.

def check(self, ​​block_number: int, ​​timestamp: int) -> bool:
132
        """
133
        Check whether the block number has been reached.
134
135
        Returns `True` when the given `block_number` is equal to or greater
136
        than [`block_number`], and `False` otherwise.
137
138
        [`block_number`]: ref:ethereum.fork_criteria.ByBlockNumber.block_number
139
        """
140
        return block_number >= self.block_number

__repr__

String representation of this object.

def __repr__(self) -> str:
143
        """
144
        String representation of this object.
145
        """
146
        return f"ByBlockNumber({self.block_number})"

ByTimestamp

Forks that occur when a specific timestamp has been reached.

class ByTimestamp:

timestamp

154
    timestamp: int

__init__

def __init__(self, ​​timestamp: int):
160
        self._internal = (ForkCriteria.TIMESTAMP, timestamp)
161
        self.timestamp = timestamp

check

Check whether the timestamp has been reached.

Returns True when the given timestamp is equal to or greater than timestamp, and False otherwise.

def check(self, ​​block_number: int, ​​timestamp: int) -> bool:
164
        """
165
        Check whether the timestamp has been reached.
166
167
        Returns `True` when the given `timestamp` is equal to or greater than
168
        [`timestamp`], and `False` otherwise.
169
170
        [`timestamp`]: ref:ethereum.fork_criteria.ByTimestamp.timestamp
171
        """
172
        return timestamp >= self.timestamp

__repr__

String representation of this object.

def __repr__(self) -> str:
175
        """
176
        String representation of this object.
177
        """
178
        return f"ByTimestamp({self.timestamp})"

Unscheduled

Forks that have not been scheduled.

class Unscheduled:

__init__

def __init__(self) -> None:
187
        self._internal = (ForkCriteria.UNSCHEDULED, 0)

check

Unscheduled forks never occur; always returns False.

def check(self, ​​block_number: int, ​​timestamp: int) -> bool:
190
        """
191
        Unscheduled forks never occur; always returns `False`.
192
        """
193
        return False

__repr__

String representation of this object.

def __repr__(self) -> str:
196
        """
197
        String representation of this object.
198
        """
199
        return "Unscheduled()"