Merge pull request #1649 from ethereum/eth1-voting-period-in-epochs

Eth1 voting period in epochs [updated for configs/phase1/tests compat.]
This commit is contained in:
Danny Ryan 2020-03-10 13:24:03 -06:00 committed by GitHub
commit 3b7704a78f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 27 additions and 23 deletions

View File

@ -88,8 +88,8 @@ SLOTS_PER_EPOCH: 32
MIN_SEED_LOOKAHEAD: 1
# 2**2 (= 4) epochs 25.6 minutes
MAX_SEED_LOOKAHEAD: 4
# 2**10 (= 1,024) slots ~1.7 hours
SLOTS_PER_ETH1_VOTING_PERIOD: 1024
# 2**5 (= 32) epochs ~3.4 hours
EPOCHS_PER_ETH1_VOTING_PERIOD: 32
# 2**13 (= 8,192) slots ~13 hours
SLOTS_PER_HISTORICAL_ROOT: 8192
# 2**8 (= 256) epochs ~27 hours

View File

@ -89,7 +89,7 @@ MIN_SEED_LOOKAHEAD: 1
# 2**2 (= 4) epochs
MAX_SEED_LOOKAHEAD: 4
# [customized] higher frequency new deposits from eth1 for testing
SLOTS_PER_ETH1_VOTING_PERIOD: 16
EPOCHS_PER_ETH1_VOTING_PERIOD: 2
# [customized] smaller state
SLOTS_PER_HISTORICAL_ROOT: 64
# 2**8 (= 256) epochs

View File

@ -218,7 +218,7 @@ The following values are (non-configurable) constants used throughout the specif
| `MIN_SEED_LOOKAHEAD` | `2**0` (= 1) | epochs | 6.4 minutes |
| `MAX_SEED_LOOKAHEAD` | `2**2` (= 4) | epochs | 25.6 minutes |
| `MIN_EPOCHS_TO_INACTIVITY_PENALTY` | `2**2` (= 4) | epochs | 25.6 minutes |
| `SLOTS_PER_ETH1_VOTING_PERIOD` | `2**10` (= 1,024) | slots | ~3.4 hours |
| `EPOCHS_PER_ETH1_VOTING_PERIOD` | `2**5` (= 32) | epochs | ~3.4 hours |
| `SLOTS_PER_HISTORICAL_ROOT` | `2**13` (= 8,192) | slots | ~27 hours |
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours |
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
@ -484,7 +484,7 @@ class BeaconState(Container):
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
# Eth1
eth1_data: Eth1Data
eth1_data_votes: List[Eth1Data, SLOTS_PER_ETH1_VOTING_PERIOD]
eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH]
eth1_deposit_index: uint64
# Registry
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
@ -1411,7 +1411,7 @@ def process_final_updates(state: BeaconState) -> None:
current_epoch = get_current_epoch(state)
next_epoch = Epoch(current_epoch + 1)
# Reset eth1 data votes
if (state.slot + 1) % SLOTS_PER_ETH1_VOTING_PERIOD == 0:
if next_epoch % EPOCHS_PER_ETH1_VOTING_PERIOD == 0:
state.eth1_data_votes = []
# Update effective balances with hysteresis
for index, validator in enumerate(state.validators):
@ -1487,7 +1487,7 @@ def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
```python
def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
state.eth1_data_votes.append(body.eth1_data)
if state.eth1_data_votes.count(body.eth1_data) * 2 > SLOTS_PER_ETH1_VOTING_PERIOD:
if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
state.eth1_data = body.eth1_data
```

View File

@ -129,7 +129,7 @@ To submit a deposit:
### Process deposit
Deposits cannot be processed into the beacon chain until the Eth1 block in which they were deposited or any of its descendants is added to the beacon chain `state.eth1_data`. This takes _a minimum_ of `ETH1_FOLLOW_DISTANCE` Eth1 blocks (~4 hours) plus `SLOTS_PER_ETH1_VOTING_PERIOD` slots (~3.4 hours). Once the requisite Eth1 data is added, the deposit will normally be added to a beacon chain block and processed into the `state.validators` within an epoch or two. The validator is then in a queue to be activated.
Deposits cannot be processed into the beacon chain until the Eth1 block in which they were deposited or any of its descendants is added to the beacon chain `state.eth1_data`. This takes _a minimum_ of `ETH1_FOLLOW_DISTANCE` Eth1 blocks (~4 hours) plus `EPOCHS_PER_ETH1_VOTING_PERIOD` epochs (~3.4 hours). Once the requisite Eth1 data is added, the deposit will normally be added to a beacon chain block and processed into the `state.validators` within an epoch or two. The validator is then in a queue to be activated.
### Validator index
@ -269,7 +269,7 @@ def compute_time_at_slot(state: BeaconState, slot: Slot) -> uint64:
```python
def voting_period_start_time(state: BeaconState) -> uint64:
eth1_voting_period_start_slot = Slot(state.slot - state.slot % SLOTS_PER_ETH1_VOTING_PERIOD)
eth1_voting_period_start_slot = Slot(state.slot - state.slot % (EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH))
return compute_time_at_slot(state, eth1_voting_period_start_slot)
```

View File

@ -254,7 +254,7 @@ class BeaconState(Container):
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
# Eth1
eth1_data: Eth1Data
eth1_data_votes: List[Eth1Data, SLOTS_PER_ETH1_VOTING_PERIOD]
eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH]
eth1_deposit_index: uint64
# Registry
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]

View File

@ -11,7 +11,7 @@ def run_process_final_updates(spec, state):
@with_all_phases
@spec_state_test
def test_eth1_vote_no_reset(spec, state):
assert spec.SLOTS_PER_ETH1_VOTING_PERIOD > spec.SLOTS_PER_EPOCH
assert spec.EPOCHS_PER_ETH1_VOTING_PERIOD > 1
# skip ahead to the end of the epoch
state.slot = spec.SLOTS_PER_EPOCH - 1
for i in range(state.slot + 1): # add a vote for each skipped slot.
@ -29,7 +29,7 @@ def test_eth1_vote_no_reset(spec, state):
@spec_state_test
def test_eth1_vote_reset(spec, state):
# skip ahead to the end of the voting period
state.slot = spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1
state.slot = (spec.EPOCHS_PER_ETH1_VOTING_PERIOD * spec.SLOTS_PER_EPOCH) - 1
for i in range(state.slot + 1): # add a vote for each skipped slot.
state.eth1_data_votes.append(
spec.Eth1Data(deposit_root=b'\xaa' * 32,

View File

@ -486,10 +486,12 @@ def test_historical_batch(spec, state):
@spec_state_test
def test_eth1_data_votes_consensus(spec, state):
# Don't run when it will take very, very long to simulate. Minimal configuration suffices.
if spec.SLOTS_PER_ETH1_VOTING_PERIOD > 16:
if spec.EPOCHS_PER_ETH1_VOTING_PERIOD > 2:
return
offset_block = build_empty_block(spec, state, slot=spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1)
voting_period_slots = spec.EPOCHS_PER_ETH1_VOTING_PERIOD * spec.SLOTS_PER_EPOCH
offset_block = build_empty_block(spec, state, slot=voting_period_slots - 1)
state_transition_and_sign_block(spec, state, offset_block)
yield 'pre', state
@ -499,14 +501,14 @@ def test_eth1_data_votes_consensus(spec, state):
blocks = []
for i in range(0, spec.SLOTS_PER_ETH1_VOTING_PERIOD):
for i in range(0, voting_period_slots):
block = build_empty_block_for_next_slot(spec, state)
# wait for over 50% for A, then start voting B
block.body.eth1_data.block_hash = b if i * 2 > spec.SLOTS_PER_ETH1_VOTING_PERIOD else a
block.body.eth1_data.block_hash = b if i * 2 > voting_period_slots else a
signed_block = state_transition_and_sign_block(spec, state, block)
blocks.append(signed_block)
assert len(state.eth1_data_votes) == spec.SLOTS_PER_ETH1_VOTING_PERIOD
assert len(state.eth1_data_votes) == voting_period_slots
assert state.eth1_data.block_hash == a
# transition to next eth1 voting period
@ -519,7 +521,7 @@ def test_eth1_data_votes_consensus(spec, state):
yield 'post', state
assert state.eth1_data.block_hash == a
assert state.slot % spec.SLOTS_PER_ETH1_VOTING_PERIOD == 0
assert state.slot % voting_period_slots == 0
assert len(state.eth1_data_votes) == 1
assert state.eth1_data_votes[0].block_hash == c
@ -528,12 +530,14 @@ def test_eth1_data_votes_consensus(spec, state):
@spec_state_test
def test_eth1_data_votes_no_consensus(spec, state):
# Don't run when it will take very, very long to simulate. Minimal configuration suffices.
if spec.SLOTS_PER_ETH1_VOTING_PERIOD > 16:
if spec.EPOCHS_PER_ETH1_VOTING_PERIOD > 2:
return
voting_period_slots = spec.EPOCHS_PER_ETH1_VOTING_PERIOD * spec.SLOTS_PER_EPOCH
pre_eth1_hash = state.eth1_data.block_hash
offset_block = build_empty_block(spec, state, slot=spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1)
offset_block = build_empty_block(spec, state, slot=voting_period_slots - 1)
state_transition_and_sign_block(spec, state, offset_block)
yield 'pre', state
@ -542,14 +546,14 @@ def test_eth1_data_votes_no_consensus(spec, state):
blocks = []
for i in range(0, spec.SLOTS_PER_ETH1_VOTING_PERIOD):
for i in range(0, voting_period_slots):
block = build_empty_block_for_next_slot(spec, state)
# wait for precisely 50% for A, then start voting B for other 50%
block.body.eth1_data.block_hash = b if i * 2 >= spec.SLOTS_PER_ETH1_VOTING_PERIOD else a
block.body.eth1_data.block_hash = b if i * 2 >= voting_period_slots else a
signed_block = state_transition_and_sign_block(spec, state, block)
blocks.append(signed_block)
assert len(state.eth1_data_votes) == spec.SLOTS_PER_ETH1_VOTING_PERIOD
assert len(state.eth1_data_votes) == voting_period_slots
assert state.eth1_data.block_hash == pre_eth1_hash
yield 'blocks', blocks