Refactor
1. Rename the current `get_genesis_beacon_state(...)` to `initialize_beacon_state_from_eth1(...)` 2. Extract `is_valid_genesis_state(state: BeaconState) -> bool` from `initialize_beacon_state_from_eth1(...)`
This commit is contained in:
parent
03a243e96c
commit
47cdae4292
|
@ -1092,24 +1092,25 @@ def slash_validator(state: BeaconState,
|
||||||
|
|
||||||
### Genesis state
|
### Genesis state
|
||||||
|
|
||||||
Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 block, call `get_genesis_beacon_state(eth1_block_hash, eth1_timestamp, deposits)` where:
|
Before the Ethereum 2.0 genesis has been triggered, and for every Ethereum 1.0 block, call `initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)` where:
|
||||||
|
|
||||||
* `eth1_block_hash` is the hash of the Ethereum 1.0 block
|
* `eth1_block_hash` is the hash of the Ethereum 1.0 block
|
||||||
* `eth1_timestamp` is the Unix timestamp corresponding to `eth1_block_hash`
|
* `eth1_timestamp` is the Unix timestamp corresponding to `eth1_block_hash`
|
||||||
* `deposits` is the sequence of all deposits, ordered chronologically, up to the block with hash `eth1_block_hash`
|
* `deposits` is the sequence of all deposits, ordered chronologically, up to the block with hash `eth1_block_hash`
|
||||||
|
|
||||||
The genesis state `genesis_state` is the return value of the first call to `get_genesis_beacon_state` that does not trigger an `assert`.
|
The genesis state `genesis_state` is the return value of calling `initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)` only if `is_valid_genesis_state(genesis_state) is True`.
|
||||||
|
|
||||||
*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary.
|
*Note*: The two constants `MIN_GENESIS_TIME` and `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` have yet to be agreed upon by the community, and can be updated as necessary.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState:
|
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash,
|
||||||
|
eth1_timestamp: uint64,
|
||||||
|
deposits: Sequence[Deposit]) -> BeaconState:
|
||||||
state = BeaconState(
|
state = BeaconState(
|
||||||
genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY,
|
genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY,
|
||||||
eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)),
|
eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)),
|
||||||
latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())),
|
latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())),
|
||||||
)
|
)
|
||||||
assert state.genesis_time >= MIN_GENESIS_TIME
|
|
||||||
|
|
||||||
# Process deposits
|
# Process deposits
|
||||||
leaves = list(map(lambda deposit: deposit.data, deposits))
|
leaves = list(map(lambda deposit: deposit.data, deposits))
|
||||||
|
@ -1124,7 +1125,6 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, depo
|
||||||
if state.balances[index] >= MAX_EFFECTIVE_BALANCE:
|
if state.balances[index] >= MAX_EFFECTIVE_BALANCE:
|
||||||
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
||||||
validator.activation_epoch = GENESIS_EPOCH
|
validator.activation_epoch = GENESIS_EPOCH
|
||||||
assert len(get_active_validator_indices(state, GENESIS_EPOCH)) >= MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
|
||||||
|
|
||||||
# Populate active_index_roots
|
# Populate active_index_roots
|
||||||
genesis_active_index_root = hash_tree_root(
|
genesis_active_index_root = hash_tree_root(
|
||||||
|
@ -1136,6 +1136,16 @@ def get_genesis_beacon_state(eth1_block_hash: Hash, eth1_timestamp: uint64, depo
|
||||||
return state
|
return state
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
def is_valid_genesis_state(state: BeaconState) -> bool:
|
||||||
|
if state.genesis_time < MIN_GENESIS_TIME:
|
||||||
|
return False
|
||||||
|
elif len(get_active_validator_indices(state, GENESIS_EPOCH)) < MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
```
|
||||||
|
|
||||||
### Genesis block
|
### Genesis block
|
||||||
|
|
||||||
Let `genesis_block = BeaconBlock(state_root=hash_tree_root(genesis_state))`.
|
Let `genesis_block = BeaconBlock(state_root=hash_tree_root(genesis_state))`.
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
from eth2spec.test.context import with_phases, spectest_with_bls_switch
|
|
||||||
from eth2spec.test.helpers.deposits import (
|
|
||||||
prepare_genesis_deposits,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@with_phases(['phase0'])
|
|
||||||
@spectest_with_bls_switch
|
|
||||||
def test_get_genesis_beacon_state_success(spec):
|
|
||||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
|
||||||
deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
|
||||||
|
|
||||||
eth1_block_hash = b'\x12' * 32
|
|
||||||
eth1_timestamp = spec.MIN_GENESIS_TIME
|
|
||||||
|
|
||||||
yield "eth1_block_hash", eth1_block_hash
|
|
||||||
yield "eth1_timestamp", eth1_timestamp
|
|
||||||
yield "deposits", deposits
|
|
||||||
genesis_state = spec.get_genesis_beacon_state(
|
|
||||||
eth1_block_hash,
|
|
||||||
eth1_timestamp,
|
|
||||||
deposits,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert genesis_state.genesis_time == eth1_timestamp - eth1_timestamp % spec.SECONDS_PER_DAY + 2 * spec.SECONDS_PER_DAY
|
|
||||||
assert len(genesis_state.validators) == deposit_count
|
|
||||||
assert genesis_state.eth1_data.deposit_root == deposit_root
|
|
||||||
assert genesis_state.eth1_data.deposit_count == deposit_count
|
|
||||||
assert genesis_state.eth1_data.block_hash == eth1_block_hash
|
|
||||||
|
|
||||||
yield "state", genesis_state
|
|
|
@ -1,52 +0,0 @@
|
||||||
from eth2spec.test.context import with_phases, spectest_with_bls_switch
|
|
||||||
from eth2spec.test.helpers.deposits import (
|
|
||||||
prepare_genesis_deposits,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@with_phases(['phase0'])
|
|
||||||
@spectest_with_bls_switch
|
|
||||||
def test_is_genesis_trigger_false(spec):
|
|
||||||
deposit_count = 2
|
|
||||||
genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
|
||||||
genesis_time = 1546300800
|
|
||||||
|
|
||||||
yield "deposits", genesis_deposits
|
|
||||||
yield "time", genesis_time
|
|
||||||
|
|
||||||
is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time)
|
|
||||||
assert is_triggered is False
|
|
||||||
|
|
||||||
yield "is_triggered", is_triggered
|
|
||||||
|
|
||||||
|
|
||||||
@with_phases(['phase0'])
|
|
||||||
@spectest_with_bls_switch
|
|
||||||
def test_is_genesis_trigger_true(spec):
|
|
||||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
|
||||||
genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
|
||||||
SECONDS_PER_DAY = 86400
|
|
||||||
genesis_time = 1578009600 - 2 * SECONDS_PER_DAY
|
|
||||||
|
|
||||||
yield "deposits", genesis_deposits
|
|
||||||
yield "time", genesis_time
|
|
||||||
|
|
||||||
is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time)
|
|
||||||
assert is_triggered is True
|
|
||||||
|
|
||||||
yield "is_triggered", is_triggered
|
|
||||||
|
|
||||||
|
|
||||||
@with_phases(['phase0'])
|
|
||||||
@spectest_with_bls_switch
|
|
||||||
def test_is_genesis_trigger_not_enough_balance(spec):
|
|
||||||
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
|
||||||
genesis_deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE - 1)
|
|
||||||
genesis_time = 1546300800
|
|
||||||
yield "deposits", genesis_deposits
|
|
||||||
yield "time", genesis_time
|
|
||||||
|
|
||||||
is_triggered = spec.is_genesis_trigger(genesis_deposits, genesis_time)
|
|
||||||
assert is_triggered is False
|
|
||||||
|
|
||||||
yield "is_triggered", is_triggered
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
from eth2spec.test.context import spectest_with_bls_switch, with_phases
|
||||||
|
from eth2spec.test.helpers.deposits import (
|
||||||
|
prepare_genesis_deposits,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_valid_beacon_state(spec):
|
||||||
|
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||||
|
deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
||||||
|
|
||||||
|
eth1_block_hash = b'\x12' * 32
|
||||||
|
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||||
|
return spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_initialize_beacon_state_from_eth1(spec):
|
||||||
|
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||||
|
deposits, deposit_root = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
||||||
|
|
||||||
|
eth1_block_hash = b'\x12' * 32
|
||||||
|
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||||
|
|
||||||
|
yield 'eth1_block_hash', eth1_block_hash
|
||||||
|
yield 'eth1_timestamp', eth1_timestamp
|
||||||
|
yield 'deposits', deposits
|
||||||
|
|
||||||
|
# initialize beacon_state
|
||||||
|
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||||
|
|
||||||
|
assert state.genesis_time == eth1_timestamp - eth1_timestamp % spec.SECONDS_PER_DAY + 2 * spec.SECONDS_PER_DAY
|
||||||
|
assert len(state.validators) == deposit_count
|
||||||
|
assert state.eth1_data.deposit_root == deposit_root
|
||||||
|
assert state.eth1_data.deposit_count == deposit_count
|
||||||
|
assert state.eth1_data.block_hash == eth1_block_hash
|
||||||
|
|
||||||
|
# yield state
|
||||||
|
yield 'state', state
|
|
@ -0,0 +1,86 @@
|
||||||
|
from eth2spec.test.context import spectest_with_bls_switch, with_phases
|
||||||
|
from eth2spec.test.helpers.deposits import (
|
||||||
|
prepare_genesis_deposits,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_valid_beacon_state(spec):
|
||||||
|
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||||
|
deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
||||||
|
|
||||||
|
eth1_block_hash = b'\x12' * 32
|
||||||
|
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||||
|
return spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||||
|
|
||||||
|
|
||||||
|
def run_is_valid_genesis_state(spec, state, valid=True):
|
||||||
|
"""
|
||||||
|
Run ``is_valid_genesis_state``, yielding:
|
||||||
|
- state ('state')
|
||||||
|
- is_valid ('is_valid')
|
||||||
|
If ``valid == False``, run expecting ``AssertionError``
|
||||||
|
"""
|
||||||
|
yield state
|
||||||
|
is_valid = spec.is_valid_genesis_state(state)
|
||||||
|
yield 'is_valid', is_valid
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_is_valid_genesis_state_true(spec):
|
||||||
|
state = create_valid_beacon_state(spec)
|
||||||
|
|
||||||
|
yield from run_is_valid_genesis_state(spec, state, valid=True)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_is_valid_genesis_state_false_invalid_timestamp(spec):
|
||||||
|
state = create_valid_beacon_state(spec)
|
||||||
|
state.genesis_time = spec.MIN_GENESIS_TIME - 1
|
||||||
|
|
||||||
|
yield from run_is_valid_genesis_state(spec, state, valid=True)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_is_valid_genesis_state_true_more_balance(spec):
|
||||||
|
state = create_valid_beacon_state(spec)
|
||||||
|
state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE + 1
|
||||||
|
|
||||||
|
yield from run_is_valid_genesis_state(spec, state, valid=True)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_is_valid_genesis_state_false_not_enough_balance(spec):
|
||||||
|
state = create_valid_beacon_state(spec)
|
||||||
|
state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE - 1
|
||||||
|
|
||||||
|
yield from run_is_valid_genesis_state(spec, state, valid=False)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_is_valid_genesis_state_true_one_more_validator(spec):
|
||||||
|
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT + 1
|
||||||
|
deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
||||||
|
|
||||||
|
eth1_block_hash = b'\x12' * 32
|
||||||
|
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||||
|
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||||
|
|
||||||
|
yield from run_is_valid_genesis_state(spec, state, valid=True)
|
||||||
|
|
||||||
|
|
||||||
|
@with_phases(['phase0'])
|
||||||
|
@spectest_with_bls_switch
|
||||||
|
def test_is_valid_genesis_state_flase_not_enough_validator(spec):
|
||||||
|
deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT - 1
|
||||||
|
deposits, _ = prepare_genesis_deposits(spec, deposit_count, spec.MAX_EFFECTIVE_BALANCE)
|
||||||
|
|
||||||
|
eth1_block_hash = b'\x12' * 32
|
||||||
|
eth1_timestamp = spec.MIN_GENESIS_TIME
|
||||||
|
state = spec.initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)
|
||||||
|
|
||||||
|
yield from run_is_valid_genesis_state(spec, state, valid=False)
|
Loading…
Reference in New Issue