add genesis_validators_root to beaconstate and utilize in sig domain separation as well as fork separation

This commit is contained in:
Danny Ryan 2020-03-05 09:21:32 -07:00
parent 37b1fed8ff
commit 7e04989e29
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
5 changed files with 35 additions and 11 deletions

View File

@ -95,7 +95,7 @@ from dataclasses import (
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
from eth2spec.utils.ssz.ssz_typing import (
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
@ -117,7 +117,7 @@ from dataclasses import (
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
from eth2spec.utils.ssz.ssz_typing import (
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

View File

@ -149,7 +149,7 @@ We define the following Python custom types for type hinting and readability:
| `Root` | `Bytes32` | a Merkle root |
| `Version` | `Bytes4` | a fork version number |
| `DomainType` | `Bytes4` | a domain type |
| `Domain` | `Bytes8` | a signature domain |
| `Domain` | `Bytes32` | a signature domain |
| `BLSPubkey` | `Bytes48` | a BLS12-381 public key |
| `BLSSignature` | `Bytes96` | a BLS12-381 signature |
@ -473,6 +473,7 @@ class BeaconBlock(Container):
class BeaconState(Container):
# Versioning
genesis_time: uint64
genesis_validators_root: Root
slot: Slot
fork: Fork
# History
@ -795,13 +796,15 @@ def compute_activation_exit_epoch(epoch: Epoch) -> Epoch:
#### `compute_domain`
```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``.
"""
if fork_version is None:
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`
@ -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
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`
@ -1122,6 +1125,9 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
validator.activation_eligibility_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
```

View File

@ -615,23 +615,37 @@ ENRs MUST carry a generic `eth2` key with an 16-byte value of the node's current
|:-------------|:--------------------|
| `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
next_fork_version: Fork
current_fork_version: Version
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
)
```
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_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`.

View File

@ -244,6 +244,7 @@ Note that aside from the new additions, `Validator` and `PendingAttestation` hav
class BeaconState(Container):
# Versioning
genesis_time: uint64
genesis_validators_root: Root
slot: Slot
fork: Fork
# History

View File

@ -43,4 +43,7 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
validator.activation_eligibility_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