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
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()" |