add genesis_validators_root to beaconstate and utilize in sig domain separation as well as fork separation
This commit is contained in:
parent
37b1fed8ff
commit
7e04989e29
4
setup.py
4
setup.py
|
@ -95,7 +95,7 @@ from dataclasses import (
|
||||||
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
||||||
from eth2spec.utils.ssz.ssz_typing import (
|
from eth2spec.utils.ssz.ssz_typing import (
|
||||||
View, boolean, Container, List, Vector, uint64,
|
View, boolean, Container, List, Vector, uint64,
|
||||||
Bytes1, Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
|
Bytes1, Bytes4, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
|
||||||
)
|
)
|
||||||
from eth2spec.utils import bls
|
from eth2spec.utils import bls
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ from dataclasses import (
|
||||||
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
||||||
from eth2spec.utils.ssz.ssz_typing import (
|
from eth2spec.utils.ssz.ssz_typing import (
|
||||||
View, boolean, Container, List, Vector, uint64, uint8, bit,
|
View, boolean, Container, List, Vector, uint64, uint8, bit,
|
||||||
ByteList, Bytes1, Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
|
ByteList, Bytes1, Bytes4, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
|
||||||
)
|
)
|
||||||
from eth2spec.utils import bls
|
from eth2spec.utils import bls
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ We define the following Python custom types for type hinting and readability:
|
||||||
| `Root` | `Bytes32` | a Merkle root |
|
| `Root` | `Bytes32` | a Merkle root |
|
||||||
| `Version` | `Bytes4` | a fork version number |
|
| `Version` | `Bytes4` | a fork version number |
|
||||||
| `DomainType` | `Bytes4` | a domain type |
|
| `DomainType` | `Bytes4` | a domain type |
|
||||||
| `Domain` | `Bytes8` | a signature domain |
|
| `Domain` | `Bytes32` | a signature domain |
|
||||||
| `BLSPubkey` | `Bytes48` | a BLS12-381 public key |
|
| `BLSPubkey` | `Bytes48` | a BLS12-381 public key |
|
||||||
| `BLSSignature` | `Bytes96` | a BLS12-381 signature |
|
| `BLSSignature` | `Bytes96` | a BLS12-381 signature |
|
||||||
|
|
||||||
|
@ -473,6 +473,7 @@ class BeaconBlock(Container):
|
||||||
class BeaconState(Container):
|
class BeaconState(Container):
|
||||||
# Versioning
|
# Versioning
|
||||||
genesis_time: uint64
|
genesis_time: uint64
|
||||||
|
genesis_validators_root: Root
|
||||||
slot: Slot
|
slot: Slot
|
||||||
fork: Fork
|
fork: Fork
|
||||||
# History
|
# History
|
||||||
|
@ -795,13 +796,15 @@ def compute_activation_exit_epoch(epoch: Epoch) -> Epoch:
|
||||||
#### `compute_domain`
|
#### `compute_domain`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def compute_domain(domain_type: DomainType, fork_version: Optional[Version]=None) -> Domain:
|
def compute_domain(domain_type: DomainType, fork_version: Optional[Version]=None, genesis_root: Root=None) -> Domain:
|
||||||
"""
|
"""
|
||||||
Return the domain for the ``domain_type`` and ``fork_version``.
|
Return the domain for the ``domain_type`` and ``fork_version``.
|
||||||
"""
|
"""
|
||||||
if fork_version is None:
|
if fork_version is None:
|
||||||
fork_version = GENESIS_FORK_VERSION
|
fork_version = GENESIS_FORK_VERSION
|
||||||
return Domain(domain_type + fork_version)
|
if genesis_root is None:
|
||||||
|
genesis_root = Root()
|
||||||
|
return Domain(domain_type + fork_version + genesis_root[:24])
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `compute_signing_root`
|
#### `compute_signing_root`
|
||||||
|
@ -977,7 +980,7 @@ def get_domain(state: BeaconState, domain_type: DomainType, epoch: Epoch=None) -
|
||||||
"""
|
"""
|
||||||
epoch = get_current_epoch(state) if epoch is None else epoch
|
epoch = get_current_epoch(state) if epoch is None else epoch
|
||||||
fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
|
fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
|
||||||
return compute_domain(domain_type, fork_version)
|
return compute_domain(domain_type, fork_version, state.genesis_validators_root)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_indexed_attestation`
|
#### `get_indexed_attestation`
|
||||||
|
@ -1122,6 +1125,9 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
|
||||||
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
||||||
validator.activation_epoch = GENESIS_EPOCH
|
validator.activation_epoch = GENESIS_EPOCH
|
||||||
|
|
||||||
|
# Set genesis validators root for domain separation and chain versioning
|
||||||
|
state.genesis_validators_root = hash_tree_root(state.validators)
|
||||||
|
|
||||||
return state
|
return state
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -615,23 +615,37 @@ ENRs MUST carry a generic `eth2` key with an 16-byte value of the node's current
|
||||||
|:-------------|:--------------------|
|
|:-------------|:--------------------|
|
||||||
| `eth2` | SSZ `ENRForkID` |
|
| `eth2` | SSZ `ENRForkID` |
|
||||||
|
|
||||||
Specifically, the value of the `eth2` key MUST be the following SSZ encoded object (`ENRForkID`), where
|
First we define `current_fork` as the following SSZ encoded object
|
||||||
|
|
||||||
```
|
```
|
||||||
(
|
(
|
||||||
current_fork_version: Fork
|
current_fork_version: Version
|
||||||
next_fork_version: Fork
|
genesis_validators_root: Root
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
* `current_fork_version` is the fork version at the node's current epoch defined by the wall-clock time (not necessarily the epoch to which the node is sync)
|
||||||
|
* `genesis_validators_root` is the static `Root` found in `state.genesis_validators_root`
|
||||||
|
|
||||||
|
Specifically, the value of the `eth2` key MUST be the following SSZ encoded object (`ENRForkID`)
|
||||||
|
|
||||||
|
```
|
||||||
|
(
|
||||||
|
current_fork_digest: Bytes4
|
||||||
|
next_fork_version: Version
|
||||||
next_fork_epoch: Epoch
|
next_fork_epoch: Epoch
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
where the fields of `ENRForkID` are defined as
|
where the fields of `ENRForkID` are defined as
|
||||||
|
|
||||||
* `current_fork_version` is the fork version at the node's current epoch defined by the wall-clock time (not necessarily the epoch to which the node is sync)
|
* `current_fork_digest` is `hash_tree_root(current_fork)[:4]`
|
||||||
* `next_fork_version` is the fork version corresponding to the next planned hard fork at a future epoch. If no future fork is planned, set `next_fork_version = current_fork_version` to signal this fact
|
* `next_fork_version` is the fork version corresponding to the next planned hard fork at a future epoch. If no future fork is planned, set `next_fork_version = current_fork_version` to signal this fact
|
||||||
* `next_fork_epoch` is the epoch at which the next fork is planned and the `current_fork_version` will be updated. If no future fork is planned, set `next_fork_epoch = FAR_FUTURE_EPOCH` to signal this fact
|
* `next_fork_epoch` is the epoch at which the next fork is planned and the `current_fork_version` will be updated. If no future fork is planned, set `next_fork_epoch = FAR_FUTURE_EPOCH` to signal this fact
|
||||||
|
|
||||||
Clients SHOULD connect to peers with `current_fork_version`, `next_fork_version`, and `next_fork_epoch` that match local values.
|
Clients SHOULD connect to peers with `current_fork_digest`, `next_fork_version`, and `next_fork_epoch` that match local values.
|
||||||
|
|
||||||
Clients MAY connect to peers with the same `current_fork_version` but a different `next_fork_version`/`next_fork_epoch`. Unless `ENRForkID` is manually updated to matching prior to the earlier `next_fork_epoch` of the two clients, these type of connecting clients will be unable to successfully interact starting at the earlier `next_fork_epoch`.
|
Clients MAY connect to peers with the same `current_fork_version` but a different `next_fork_version`/`next_fork_epoch`. Unless `ENRForkID` is manually updated to matching prior to the earlier `next_fork_epoch` of the two clients, these type of connecting clients will be unable to successfully interact starting at the earlier `next_fork_epoch`.
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,7 @@ Note that aside from the new additions, `Validator` and `PendingAttestation` hav
|
||||||
class BeaconState(Container):
|
class BeaconState(Container):
|
||||||
# Versioning
|
# Versioning
|
||||||
genesis_time: uint64
|
genesis_time: uint64
|
||||||
|
genesis_validators_root: Root
|
||||||
slot: Slot
|
slot: Slot
|
||||||
fork: Fork
|
fork: Fork
|
||||||
# History
|
# History
|
||||||
|
|
|
@ -43,4 +43,7 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
|
||||||
validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
|
validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
|
||||||
validator.activation_epoch = spec.GENESIS_EPOCH
|
validator.activation_epoch = spec.GENESIS_EPOCH
|
||||||
|
|
||||||
|
# Set genesis validators root for domain separation and chain versioning
|
||||||
|
state.genesis_validators_root = spec.hash_tree_root(state.validators)
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
Loading…
Reference in New Issue