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.

35
@functools.total_ordering
class ForkCriteria:

BLOCK_NUMBER

49
    BLOCK_NUMBER: Final[int] = 0

TIMESTAMP

56
    TIMESTAMP: Final[int] = 1

UNSCHEDULED

63
    UNSCHEDULED: Final[int] = 2

_internal

70
    _internal: Tuple[int, int]

__eq__

Equality for fork criteria.

def __eq__(self, ​​other: object) -> bool:
73
        """
74
        Equality for fork criteria.
75
        """
76
        if isinstance(other, ForkCriteria):
77
            return self._internal == other._internal
78
        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:
81
        """
82
        Less-than comparison function, with earlier forks being less than later
83
        forks.
84
85
        All [`BLOCK_NUMBER`] forks come before [`TIMESTAMP`] forks, and all
86
        scheduled forks come before [`UNSCHEDULED`] forks.
87
88
        [`BLOCK_NUMBER`]: ref:ethereum.fork_criteria.ForkCriteria.BLOCK_NUMBER
89
        [`TIMESTAMP`]: ref:ethereum.fork_criteria.ForkCriteria.TIMESTAMP
90
        [`UNSCHEDULED`]: ref:ethereum.fork_criteria.ForkCriteria.UNSCHEDULED
91
        """
92
        if isinstance(other, ForkCriteria):
93
            return self._internal < other._internal
94
        return NotImplemented

__hash__

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

def __hash__(self) -> int:
97
        """
98
        Compute a hash for this instance, so it can be stored in dictionaries.
99
        """
100
        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.

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

__repr__

String representation of this object.

112
    @abstractmethod
def __repr__(self) -> str:
114
        """
115
        String representation of this object.
116
        """
117
        raise NotImplementedError()

ByBlockNumber

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

class ByBlockNumber:

block_number

125
    block_number: Uint

__init__

def __init__(self, ​​block_number: SupportsInt):
131
        self._internal = (ForkCriteria.BLOCK_NUMBER, int(block_number))
132
        self.block_number = Uint(int(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.

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

__repr__

String representation of this object.

def __repr__(self) -> str:
147
        """
148
        String representation of this object.
149
        """
150
        return f"ByBlockNumber({self.block_number})"

ByTimestamp

Forks that occur when a specific timestamp has been reached.

class ByTimestamp:

timestamp

158
    timestamp: U256

__init__

def __init__(self, ​​timestamp: SupportsInt):
164
        self._internal = (ForkCriteria.TIMESTAMP, int(timestamp))
165
        self.timestamp = U256(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.

167
    @override
def check(self, ​​block_number: Uint, ​​timestamp: U256) -> bool:
169
        """
170
        Check whether the timestamp has been reached.
171
172
        Returns `True` when the given `timestamp` is equal to or greater than
173
        [`timestamp`], and `False` otherwise.
174
175
        [`timestamp`]: ref:ethereum.fork_criteria.ByTimestamp.timestamp
176
        """
177
        return timestamp >= self.timestamp

__repr__

String representation of this object.

def __repr__(self) -> str:
180
        """
181
        String representation of this object.
182
        """
183
        return f"ByTimestamp({self.timestamp})"

Unscheduled

Forks that have not been scheduled.

class Unscheduled:

__init__

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

check

Unscheduled forks never occur; always returns False.

194
    @override
def check(self, ​​block_number: Uint, ​​timestamp: U256) -> Literal[False]:
196
        """
197
        Unscheduled forks never occur; always returns `False`.
198
        """
199
        return False

__repr__

String representation of this object.

def __repr__(self) -> str:
202
        """
203
        String representation of this object.
204
        """
205
        return "Unscheduled()"