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:
commit
3b7704a78f
|
@ -88,8 +88,8 @@ SLOTS_PER_EPOCH: 32
|
||||||
MIN_SEED_LOOKAHEAD: 1
|
MIN_SEED_LOOKAHEAD: 1
|
||||||
# 2**2 (= 4) epochs 25.6 minutes
|
# 2**2 (= 4) epochs 25.6 minutes
|
||||||
MAX_SEED_LOOKAHEAD: 4
|
MAX_SEED_LOOKAHEAD: 4
|
||||||
# 2**10 (= 1,024) slots ~1.7 hours
|
# 2**5 (= 32) epochs ~3.4 hours
|
||||||
SLOTS_PER_ETH1_VOTING_PERIOD: 1024
|
EPOCHS_PER_ETH1_VOTING_PERIOD: 32
|
||||||
# 2**13 (= 8,192) slots ~13 hours
|
# 2**13 (= 8,192) slots ~13 hours
|
||||||
SLOTS_PER_HISTORICAL_ROOT: 8192
|
SLOTS_PER_HISTORICAL_ROOT: 8192
|
||||||
# 2**8 (= 256) epochs ~27 hours
|
# 2**8 (= 256) epochs ~27 hours
|
||||||
|
|
|
@ -89,7 +89,7 @@ MIN_SEED_LOOKAHEAD: 1
|
||||||
# 2**2 (= 4) epochs
|
# 2**2 (= 4) epochs
|
||||||
MAX_SEED_LOOKAHEAD: 4
|
MAX_SEED_LOOKAHEAD: 4
|
||||||
# [customized] higher frequency new deposits from eth1 for testing
|
# [customized] higher frequency new deposits from eth1 for testing
|
||||||
SLOTS_PER_ETH1_VOTING_PERIOD: 16
|
EPOCHS_PER_ETH1_VOTING_PERIOD: 2
|
||||||
# [customized] smaller state
|
# [customized] smaller state
|
||||||
SLOTS_PER_HISTORICAL_ROOT: 64
|
SLOTS_PER_HISTORICAL_ROOT: 64
|
||||||
# 2**8 (= 256) epochs
|
# 2**8 (= 256) epochs
|
||||||
|
|
|
@ -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 |
|
| `MIN_SEED_LOOKAHEAD` | `2**0` (= 1) | epochs | 6.4 minutes |
|
||||||
| `MAX_SEED_LOOKAHEAD` | `2**2` (= 4) | epochs | 25.6 minutes |
|
| `MAX_SEED_LOOKAHEAD` | `2**2` (= 4) | epochs | 25.6 minutes |
|
||||||
| `MIN_EPOCHS_TO_INACTIVITY_PENALTY` | `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 |
|
| `SLOTS_PER_HISTORICAL_ROOT` | `2**13` (= 8,192) | slots | ~27 hours |
|
||||||
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours |
|
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours |
|
||||||
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
|
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
|
||||||
|
@ -484,7 +484,7 @@ class BeaconState(Container):
|
||||||
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
|
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
|
||||||
# Eth1
|
# Eth1
|
||||||
eth1_data: Eth1Data
|
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
|
eth1_deposit_index: uint64
|
||||||
# Registry
|
# Registry
|
||||||
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
|
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
|
||||||
|
@ -1411,7 +1411,7 @@ def process_final_updates(state: BeaconState) -> None:
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
next_epoch = Epoch(current_epoch + 1)
|
next_epoch = Epoch(current_epoch + 1)
|
||||||
# Reset eth1 data votes
|
# 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 = []
|
state.eth1_data_votes = []
|
||||||
# Update effective balances with hysteresis
|
# Update effective balances with hysteresis
|
||||||
for index, validator in enumerate(state.validators):
|
for index, validator in enumerate(state.validators):
|
||||||
|
@ -1487,7 +1487,7 @@ def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||||
```python
|
```python
|
||||||
def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
|
def process_eth1_data(state: BeaconState, body: BeaconBlockBody) -> None:
|
||||||
state.eth1_data_votes.append(body.eth1_data)
|
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
|
state.eth1_data = body.eth1_data
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ To submit a deposit:
|
||||||
|
|
||||||
### Process 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
|
### Validator index
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ def compute_time_at_slot(state: BeaconState, slot: Slot) -> uint64:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def voting_period_start_time(state: BeaconState) -> uint64:
|
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)
|
return compute_time_at_slot(state, eth1_voting_period_start_slot)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ class BeaconState(Container):
|
||||||
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
|
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
|
||||||
# Eth1
|
# Eth1
|
||||||
eth1_data: Eth1Data
|
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
|
eth1_deposit_index: uint64
|
||||||
# Registry
|
# Registry
|
||||||
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
|
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
|
||||||
|
|
|
@ -11,7 +11,7 @@ def run_process_final_updates(spec, state):
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_eth1_vote_no_reset(spec, state):
|
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
|
# skip ahead to the end of the epoch
|
||||||
state.slot = spec.SLOTS_PER_EPOCH - 1
|
state.slot = spec.SLOTS_PER_EPOCH - 1
|
||||||
for i in range(state.slot + 1): # add a vote for each skipped slot.
|
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
|
@spec_state_test
|
||||||
def test_eth1_vote_reset(spec, state):
|
def test_eth1_vote_reset(spec, state):
|
||||||
# skip ahead to the end of the voting period
|
# 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.
|
for i in range(state.slot + 1): # add a vote for each skipped slot.
|
||||||
state.eth1_data_votes.append(
|
state.eth1_data_votes.append(
|
||||||
spec.Eth1Data(deposit_root=b'\xaa' * 32,
|
spec.Eth1Data(deposit_root=b'\xaa' * 32,
|
||||||
|
|
|
@ -486,10 +486,12 @@ def test_historical_batch(spec, state):
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_eth1_data_votes_consensus(spec, state):
|
def test_eth1_data_votes_consensus(spec, state):
|
||||||
# Don't run when it will take very, very long to simulate. Minimal configuration suffices.
|
# 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
|
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)
|
state_transition_and_sign_block(spec, state, offset_block)
|
||||||
yield 'pre', state
|
yield 'pre', state
|
||||||
|
|
||||||
|
@ -499,14 +501,14 @@ def test_eth1_data_votes_consensus(spec, state):
|
||||||
|
|
||||||
blocks = []
|
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)
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
# wait for over 50% for A, then start voting B
|
# 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)
|
signed_block = state_transition_and_sign_block(spec, state, block)
|
||||||
blocks.append(signed_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
|
assert state.eth1_data.block_hash == a
|
||||||
|
|
||||||
# transition to next eth1 voting period
|
# transition to next eth1 voting period
|
||||||
|
@ -519,7 +521,7 @@ def test_eth1_data_votes_consensus(spec, state):
|
||||||
yield 'post', state
|
yield 'post', state
|
||||||
|
|
||||||
assert state.eth1_data.block_hash == a
|
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 len(state.eth1_data_votes) == 1
|
||||||
assert state.eth1_data_votes[0].block_hash == c
|
assert state.eth1_data_votes[0].block_hash == c
|
||||||
|
|
||||||
|
@ -528,12 +530,14 @@ def test_eth1_data_votes_consensus(spec, state):
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_eth1_data_votes_no_consensus(spec, state):
|
def test_eth1_data_votes_no_consensus(spec, state):
|
||||||
# Don't run when it will take very, very long to simulate. Minimal configuration suffices.
|
# 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
|
return
|
||||||
|
|
||||||
|
voting_period_slots = spec.EPOCHS_PER_ETH1_VOTING_PERIOD * spec.SLOTS_PER_EPOCH
|
||||||
|
|
||||||
pre_eth1_hash = state.eth1_data.block_hash
|
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)
|
state_transition_and_sign_block(spec, state, offset_block)
|
||||||
yield 'pre', state
|
yield 'pre', state
|
||||||
|
|
||||||
|
@ -542,14 +546,14 @@ def test_eth1_data_votes_no_consensus(spec, state):
|
||||||
|
|
||||||
blocks = []
|
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)
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
# wait for precisely 50% for A, then start voting B for other 50%
|
# 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)
|
signed_block = state_transition_and_sign_block(spec, state, block)
|
||||||
blocks.append(signed_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
|
assert state.eth1_data.block_hash == pre_eth1_hash
|
||||||
|
|
||||||
yield 'blocks', blocks
|
yield 'blocks', blocks
|
||||||
|
|
Loading…
Reference in New Issue