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
34 | @functools.total_ordering |
---|
class ForkCriteria:
BLOCK_NUMBER
48 | BLOCK_NUMBER: Final[int] = 0 |
---|
TIMESTAMP
55 | TIMESTAMP: Final[int] = 1 |
---|
UNSCHEDULED
62 | UNSCHEDULED: Final[int] = 2 |
---|
_internal
69 | _internal: Tuple[int, int] |
---|
__eq__
Equality for fork criteria.
def __eq__(self, other: object) -> bool:
72 | """ |
---|---|
73 | Equality for fork criteria. |
74 | """ |
75 | if isinstance(other, ForkCriteria): |
76 | return self._internal == other._internal |
77 | 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:
80 | """ |
---|---|
81 | Less-than comparison function, with earlier forks being less than later |
82 | forks. |
83 |
|
84 | All [`BLOCK_NUMBER`] forks come before [`TIMESTAMP`] forks, and all |
85 | scheduled forks come before [`UNSCHEDULED`] forks. |
86 |
|
87 | [`BLOCK_NUMBER`]: ref:ethereum.fork_criteria.ForkCriteria.BLOCK_NUMBER |
88 | [`TIMESTAMP`]: ref:ethereum.fork_criteria.ForkCriteria.TIMESTAMP |
89 | [`UNSCHEDULED`]: ref:ethereum.fork_criteria.ForkCriteria.UNSCHEDULED |
90 | """ |
91 | if isinstance(other, ForkCriteria): |
92 | return self._internal < other._internal |
93 | return NotImplemented |
__hash__
Compute a hash for this instance, so it can be stored in dictionaries.
def __hash__(self) -> int:
96 | """ |
---|---|
97 | Compute a hash for this instance, so it can be stored in dictionaries. |
98 | """ |
99 | 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.
101 | @abstractmethod |
---|
def check(self, block_number: Uint, timestamp: U256) -> bool:
103 | """ |
---|---|
104 | Check whether fork criteria have been met. |
105 |
|
106 | Returns `True` when the current block meets or exceeds the criteria, |
107 | and `False` otherwise. |
108 | """ |
109 | raise NotImplementedError() |
__repr__
String representation of this object.
111 | @abstractmethod |
---|
def __repr__(self) -> str:
113 | """ |
---|---|
114 | String representation of this object. |
115 | """ |
116 | raise NotImplementedError() |
ByBlockNumber
Forks that occur when a specific block number has been reached.
class ByBlockNumber:
block_number
124 | block_number: Uint |
---|
__init__
def __init__(self, block_number: SupportsInt):
130 | self._internal = (ForkCriteria.BLOCK_NUMBER, int(block_number)) |
---|---|
131 | 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.
def check(self, block_number: Uint, timestamp: U256) -> bool:
134 | """ |
---|---|
135 | Check whether the block number has been reached. |
136 |
|
137 | Returns `True` when the given `block_number` is equal to or greater |
138 | than [`block_number`], and `False` otherwise. |
139 |
|
140 | [`block_number`]: ref:ethereum.fork_criteria.ByBlockNumber.block_number |
141 | """ |
142 | return block_number >= self.block_number |
__repr__
String representation of this object.
def __repr__(self) -> str:
145 | """ |
---|---|
146 | String representation of this object. |
147 | """ |
148 | return f"ByBlockNumber({self.block_number})" |
ByTimestamp
Forks that occur when a specific timestamp has been reached.
class ByTimestamp:
timestamp
156 | timestamp: U256 |
---|
__init__
def __init__(self, timestamp: SupportsInt):
162 | self._internal = (ForkCriteria.TIMESTAMP, int(timestamp)) |
---|---|
163 | 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.
def check(self, block_number: Uint, timestamp: U256) -> bool:
166 | """ |
---|---|
167 | Check whether the timestamp has been reached. |
168 |
|
169 | Returns `True` when the given `timestamp` is equal to or greater than |
170 | [`timestamp`], and `False` otherwise. |
171 |
|
172 | [`timestamp`]: ref:ethereum.fork_criteria.ByTimestamp.timestamp |
173 | """ |
174 | return timestamp >= self.timestamp |
__repr__
String representation of this object.
def __repr__(self) -> str:
177 | """ |
---|---|
178 | String representation of this object. |
179 | """ |
180 | return f"ByTimestamp({self.timestamp})" |
Unscheduled
Forks that have not been scheduled.
class Unscheduled:
__init__
def __init__(self) -> None:
189 | self._internal = (ForkCriteria.UNSCHEDULED, 0) |
---|
check
Unscheduled forks never occur; always returns False
.
def check(self, block_number: Uint, timestamp: U256) -> Literal[False]:
192 | """ |
---|---|
193 | Unscheduled forks never occur; always returns `False`. |
194 | """ |
195 | return False |
__repr__
String representation of this object.
def __repr__(self) -> str:
198 | """ |
---|---|
199 | String representation of this object. |
200 | """ |
201 | return "Unscheduled()" |