A few more cleanups
This commit is contained in:
parent
58c864ddf4
commit
94404a5856
|
@ -81,9 +81,9 @@
|
||||||
- [`get_block_root_at_slot`](#get_block_root_at_slot)
|
- [`get_block_root_at_slot`](#get_block_root_at_slot)
|
||||||
- [`get_randao_mix`](#get_randao_mix)
|
- [`get_randao_mix`](#get_randao_mix)
|
||||||
- [`get_active_validator_indices`](#get_active_validator_indices)
|
- [`get_active_validator_indices`](#get_active_validator_indices)
|
||||||
- [`get_churn_limit`](#get_churn_limit)
|
- [`get_validator_churn_limit`](#get_validator_churn_limit)
|
||||||
- [`get_committee_count`](#get_committee_count)
|
|
||||||
- [`get_seed`](#get_seed)
|
- [`get_seed`](#get_seed)
|
||||||
|
- [`get_committee_count`](#get_committee_count)
|
||||||
- [`get_crosslink_committee`](#get_crosslink_committee)
|
- [`get_crosslink_committee`](#get_crosslink_committee)
|
||||||
- [`get_start_shard`](#get_start_shard)
|
- [`get_start_shard`](#get_start_shard)
|
||||||
- [`get_shard_delta`](#get_shard_delta)
|
- [`get_shard_delta`](#get_shard_delta)
|
||||||
|
@ -713,9 +713,11 @@ def shuffle_index(index: ValidatorIndex, index_count: int, seed: Hash) -> Valida
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def compute_committee(indices: Sequence[ValidatorIndex],
|
def compute_committee(indices: Sequence[ValidatorIndex],
|
||||||
seed: Hash, index: int, count: int) -> Sequence[ValidatorIndex]:
|
seed: Hash,
|
||||||
|
index: int,
|
||||||
|
count: int) -> Sequence[ValidatorIndex]:
|
||||||
"""
|
"""
|
||||||
Return the committee corresponding to ``indices``, ``seed``, ``index`` and committee ``count``.
|
Return the committee corresponding to ``indices``, ``seed``, ``index``, and committee ``count``.
|
||||||
"""
|
"""
|
||||||
start = (len(indices) * index) // count
|
start = (len(indices) * index) // count
|
||||||
end = (len(indices) * (index + 1)) // count
|
end = (len(indices) * (index + 1)) // count
|
||||||
|
@ -780,7 +782,7 @@ def epoch_first_slot(epoch: Epoch) -> Slot:
|
||||||
```python
|
```python
|
||||||
def delayed_activation_exit_epoch(epoch: Epoch) -> Epoch:
|
def delayed_activation_exit_epoch(epoch: Epoch) -> Epoch:
|
||||||
"""
|
"""
|
||||||
Return the epoch at which an activation or exit triggered in ``epoch`` takes effect.
|
Return the epoch where validator activations and exits initiated in ``epoch`` take effect.
|
||||||
"""
|
"""
|
||||||
return Epoch(epoch + 1 + ACTIVATION_EXIT_DELAY)
|
return Epoch(epoch + 1 + ACTIVATION_EXIT_DELAY)
|
||||||
```
|
```
|
||||||
|
@ -812,7 +814,7 @@ def get_current_epoch(state: BeaconState) -> Epoch:
|
||||||
```python
|
```python
|
||||||
def get_previous_epoch(state: BeaconState) -> Epoch:
|
def get_previous_epoch(state: BeaconState) -> Epoch:
|
||||||
"""`
|
"""`
|
||||||
Return the previous epoch (current epoch if at ``GENESIS_EPOCH``).
|
Return the previous epoch (unless the current epoch is ``GENESIS_EPOCH``).
|
||||||
"""
|
"""
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
return GENESIS_EPOCH if current_epoch == GENESIS_EPOCH else Epoch(current_epoch - 1)
|
return GENESIS_EPOCH if current_epoch == GENESIS_EPOCH else Epoch(current_epoch - 1)
|
||||||
|
@ -859,10 +861,10 @@ def get_active_validator_indices(state: BeaconState, epoch: Epoch) -> Sequence[V
|
||||||
return [ValidatorIndex(i) for i, v in enumerate(state.validators) if is_active_validator(v, epoch)]
|
return [ValidatorIndex(i) for i, v in enumerate(state.validators) if is_active_validator(v, epoch)]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_churn_limit`
|
#### `get_validator_churn_limit`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_churn_limit(state: BeaconState) -> int:
|
def get_validator_churn_limit(state: BeaconState) -> int:
|
||||||
"""
|
"""
|
||||||
Return the validator churn limit for the current epoch.
|
Return the validator churn limit for the current epoch.
|
||||||
"""
|
"""
|
||||||
|
@ -870,24 +872,6 @@ def get_churn_limit(state: BeaconState) -> int:
|
||||||
return max(MIN_PER_EPOCH_CHURN_LIMIT, len(active_validator_indices) // CHURN_LIMIT_QUOTIENT)
|
return max(MIN_PER_EPOCH_CHURN_LIMIT, len(active_validator_indices) // CHURN_LIMIT_QUOTIENT)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### `get_committee_count`
|
|
||||||
|
|
||||||
```python
|
|
||||||
def get_committee_count(state: BeaconState, epoch: Epoch) -> int:
|
|
||||||
"""
|
|
||||||
Return the number of committees at ``epoch``.
|
|
||||||
"""
|
|
||||||
active_validator_indices = get_active_validator_indices(state, epoch)
|
|
||||||
return max(
|
|
||||||
1,
|
|
||||||
min(
|
|
||||||
SHARD_COUNT // SLOTS_PER_EPOCH,
|
|
||||||
len(active_validator_indices) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
|
||||||
)
|
|
||||||
) * SLOTS_PER_EPOCH
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `get_seed`
|
#### `get_seed`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -895,11 +879,25 @@ def get_seed(state: BeaconState, epoch: Epoch) -> Hash:
|
||||||
"""
|
"""
|
||||||
Return the seed at ``epoch``.
|
Return the seed at ``epoch``.
|
||||||
"""
|
"""
|
||||||
return hash(
|
randao_mix = get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) # Avoid underflow
|
||||||
get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) + # Avoid underflow
|
active_indices_root = hash_tree_root(List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, epoch)))
|
||||||
hash_tree_root(List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, epoch))) +
|
return hash(randao_mix + active_indices_root + int_to_bytes(epoch, length=32))
|
||||||
int_to_bytes(epoch, length=32)
|
```
|
||||||
|
|
||||||
|
#### `get_committee_count`
|
||||||
|
|
||||||
|
```python
|
||||||
|
def get_committee_count(state: BeaconState, epoch: Epoch) -> int:
|
||||||
|
"""
|
||||||
|
Return the number of committees at ``epoch``.
|
||||||
|
"""
|
||||||
|
return max(
|
||||||
|
1,
|
||||||
|
min(
|
||||||
|
SHARD_COUNT // SLOTS_PER_EPOCH,
|
||||||
|
len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
|
||||||
)
|
)
|
||||||
|
) * SLOTS_PER_EPOCH
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_crosslink_committee`
|
#### `get_crosslink_committee`
|
||||||
|
@ -1010,6 +1008,16 @@ def get_total_balance(state: BeaconState, indices: Set[ValidatorIndex]) -> Gwei:
|
||||||
return Gwei(max(sum([state.validators[index].effective_balance for index in indices]), 1))
|
return Gwei(max(sum([state.validators[index].effective_balance for index in indices]), 1))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `get_total_active_balance`
|
||||||
|
|
||||||
|
```python
|
||||||
|
def get_total_active_balance(state: BeaconState) -> Gwei:
|
||||||
|
"""
|
||||||
|
Return the combined effective balance of the active validators.
|
||||||
|
"""
|
||||||
|
return get_total_balance(state, set(get_active_validator_indices(state, get_current_epoch(state))))
|
||||||
|
```
|
||||||
|
|
||||||
#### `get_domain`
|
#### `get_domain`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -1093,7 +1101,7 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH]
|
exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH]
|
||||||
exit_queue_epoch = max(exit_epochs + [delayed_activation_exit_epoch(get_current_epoch(state))])
|
exit_queue_epoch = max(exit_epochs + [delayed_activation_exit_epoch(get_current_epoch(state))])
|
||||||
exit_queue_churn = len([v for v in state.validators if v.exit_epoch == exit_queue_epoch])
|
exit_queue_churn = len([v for v in state.validators if v.exit_epoch == exit_queue_epoch])
|
||||||
if exit_queue_churn >= get_churn_limit(state):
|
if exit_queue_churn >= get_validator_churn_limit(state):
|
||||||
exit_queue_epoch += Epoch(1)
|
exit_queue_epoch += Epoch(1)
|
||||||
|
|
||||||
# Set validator exit epoch and withdrawable epoch
|
# Set validator exit epoch and withdrawable epoch
|
||||||
|
@ -1219,11 +1227,9 @@ def process_slot(state: BeaconState) -> None:
|
||||||
# Cache state root
|
# Cache state root
|
||||||
previous_state_root = hash_tree_root(state)
|
previous_state_root = hash_tree_root(state)
|
||||||
state.state_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_state_root
|
state.state_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_state_root
|
||||||
|
|
||||||
# Cache latest block header state root
|
# Cache latest block header state root
|
||||||
if state.latest_block_header.state_root == ZERO_HASH:
|
if state.latest_block_header.state_root == ZERO_HASH:
|
||||||
state.latest_block_header.state_root = previous_state_root
|
state.latest_block_header.state_root = previous_state_root
|
||||||
|
|
||||||
# Cache block root
|
# Cache block root
|
||||||
previous_block_root = signing_root(state.latest_block_header)
|
previous_block_root = signing_root(state.latest_block_header)
|
||||||
state.block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_block_root
|
state.block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_block_root
|
||||||
|
@ -1248,11 +1254,6 @@ def process_epoch(state: BeaconState) -> None:
|
||||||
|
|
||||||
#### Helper functions
|
#### Helper functions
|
||||||
|
|
||||||
```python
|
|
||||||
def get_total_active_balance(state: BeaconState) -> Gwei:
|
|
||||||
return get_total_balance(state, set(get_active_validator_indices(state, get_current_epoch(state))))
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_matching_source_attestations(state: BeaconState, epoch: Epoch) -> Sequence[PendingAttestation]:
|
def get_matching_source_attestations(state: BeaconState, epoch: Epoch) -> Sequence[PendingAttestation]:
|
||||||
assert epoch in (get_previous_epoch(state), get_current_epoch(state))
|
assert epoch in (get_previous_epoch(state), get_current_epoch(state))
|
||||||
|
@ -1278,7 +1279,7 @@ def get_matching_head_attestations(state: BeaconState, epoch: Epoch) -> Sequence
|
||||||
```python
|
```python
|
||||||
def get_unslashed_attesting_indices(state: BeaconState,
|
def get_unslashed_attesting_indices(state: BeaconState,
|
||||||
attestations: Sequence[PendingAttestation]) -> Set[ValidatorIndex]:
|
attestations: Sequence[PendingAttestation]) -> Set[ValidatorIndex]:
|
||||||
output = set() # Type: Set[ValidatorIndex]
|
output = set() # type: Set[ValidatorIndex]
|
||||||
for a in attestations:
|
for a in attestations:
|
||||||
output = output.union(get_attesting_indices(state, a.data, a.aggregation_bits))
|
output = output.union(get_attesting_indices(state, a.data, a.aggregation_bits))
|
||||||
return set(filter(lambda index: not state.validators[index].slashed, list(output)))
|
return set(filter(lambda index: not state.validators[index].slashed, list(output)))
|
||||||
|
@ -1477,7 +1478,7 @@ def process_registry_updates(state: BeaconState) -> None:
|
||||||
validator.activation_epoch >= delayed_activation_exit_epoch(state.finalized_checkpoint.epoch)
|
validator.activation_epoch >= delayed_activation_exit_epoch(state.finalized_checkpoint.epoch)
|
||||||
], key=lambda index: state.validators[index].activation_eligibility_epoch)
|
], key=lambda index: state.validators[index].activation_eligibility_epoch)
|
||||||
# Dequeued validators for activation up to churn limit (without resetting activation epoch)
|
# Dequeued validators for activation up to churn limit (without resetting activation epoch)
|
||||||
for index in activation_queue[:get_churn_limit(state)]:
|
for index in activation_queue[:get_validator_churn_limit(state)]:
|
||||||
validator = state.validators[index]
|
validator = state.validators[index]
|
||||||
if validator.activation_epoch == FAR_FUTURE_EPOCH:
|
if validator.activation_epoch == FAR_FUTURE_EPOCH:
|
||||||
validator.activation_epoch = delayed_activation_exit_epoch(get_current_epoch(state))
|
validator.activation_epoch = delayed_activation_exit_epoch(get_current_epoch(state))
|
||||||
|
@ -1703,13 +1704,10 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
|
||||||
amount = deposit.data.amount
|
amount = deposit.data.amount
|
||||||
validator_pubkeys = [v.pubkey for v in state.validators]
|
validator_pubkeys = [v.pubkey for v in state.validators]
|
||||||
if pubkey not in validator_pubkeys:
|
if pubkey not in validator_pubkeys:
|
||||||
# Verify the deposit signature (proof of possession).
|
# Verify the deposit signature (proof of possession) for new validators.
|
||||||
# Invalid signatures are allowed by the deposit contract,
|
# Note: The deposit contract does not check signatures.
|
||||||
# and hence included on-chain, but must not be processed.
|
|
||||||
# Note: Deposits are valid across forks, hence the deposit domain is retrieved directly from `bls_domain`
|
# Note: Deposits are valid across forks, hence the deposit domain is retrieved directly from `bls_domain`
|
||||||
if not bls_verify(
|
if not bls_verify(pubkey, signing_root(deposit.data), deposit.data.signature, bls_domain(DOMAIN_DEPOSIT)):
|
||||||
pubkey, signing_root(deposit.data), deposit.data.signature, bls_domain(DOMAIN_DEPOSIT)
|
|
||||||
):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Add validator and balance entries
|
# Add validator and balance entries
|
||||||
|
@ -1757,14 +1755,14 @@ def process_transfer(state: BeaconState, transfer: Transfer) -> None:
|
||||||
assert state.balances[transfer.sender] >= max(transfer.amount + transfer.fee, transfer.amount, transfer.fee)
|
assert state.balances[transfer.sender] >= max(transfer.amount + transfer.fee, transfer.amount, transfer.fee)
|
||||||
# A transfer is valid in only one slot
|
# A transfer is valid in only one slot
|
||||||
assert state.slot == transfer.slot
|
assert state.slot == transfer.slot
|
||||||
# Sender must satisfy at least one of the following conditions in the parenthesis:
|
# Sender must satisfy at least one of the following:
|
||||||
assert (
|
assert (
|
||||||
# * Has not been activated
|
# 1) Never have been eligible for activation
|
||||||
state.validators[transfer.sender].activation_eligibility_epoch == FAR_FUTURE_EPOCH or
|
state.validators[transfer.sender].activation_eligibility_epoch == FAR_FUTURE_EPOCH or
|
||||||
# * Is withdrawable
|
# 2) Be withdrawable
|
||||||
get_current_epoch(state) >= state.validators[transfer.sender].withdrawable_epoch or
|
get_current_epoch(state) >= state.validators[transfer.sender].withdrawable_epoch or
|
||||||
# * Balance after transfer is more than the effective balance threshold
|
# 3) Have a balance of at least MAX_EFFECTIVE_BALANCE after the transfer
|
||||||
transfer.amount + transfer.fee + MAX_EFFECTIVE_BALANCE <= state.balances[transfer.sender]
|
state.balances[transfer.sender] >= transfer.amount + transfer.fee + MAX_EFFECTIVE_BALANCE
|
||||||
)
|
)
|
||||||
# Verify that the pubkey is valid
|
# Verify that the pubkey is valid
|
||||||
assert (
|
assert (
|
||||||
|
|
|
@ -71,7 +71,7 @@ def test_success_exit_queue(spec, state):
|
||||||
current_epoch = spec.get_current_epoch(state)
|
current_epoch = spec.get_current_epoch(state)
|
||||||
|
|
||||||
# exit `MAX_EXITS_PER_EPOCH`
|
# exit `MAX_EXITS_PER_EPOCH`
|
||||||
initial_indices = spec.get_active_validator_indices(state, current_epoch)[:spec.get_churn_limit(state)]
|
initial_indices = spec.get_active_validator_indices(state, current_epoch)[:spec.get_validator_churn_limit(state)]
|
||||||
|
|
||||||
# Prepare a bunch of exits, based on the current state
|
# Prepare a bunch of exits, based on the current state
|
||||||
exit_queue = []
|
exit_queue = []
|
||||||
|
|
|
@ -45,7 +45,7 @@ def test_activation_queue_sorting(spec, state):
|
||||||
state.validators[mock_activations - 1].activation_eligibility_epoch = epoch
|
state.validators[mock_activations - 1].activation_eligibility_epoch = epoch
|
||||||
|
|
||||||
# make sure we are hitting the churn
|
# make sure we are hitting the churn
|
||||||
churn_limit = spec.get_churn_limit(state)
|
churn_limit = spec.get_validator_churn_limit(state)
|
||||||
assert mock_activations > churn_limit
|
assert mock_activations > churn_limit
|
||||||
|
|
||||||
yield from run_process_registry_updates(spec, state)
|
yield from run_process_registry_updates(spec, state)
|
||||||
|
|
Loading…
Reference in New Issue