Merge pull request #521 from ethereum/hwwhww/refactor
Refactor and add docstring
This commit is contained in:
commit
d0d4cf133f
|
@ -310,7 +310,7 @@ The following data structures are defined as [SimpleSerialize (SSZ)](https://git
|
||||||
```python
|
```python
|
||||||
{
|
{
|
||||||
# Validator indices
|
# Validator indices
|
||||||
'validator_indices': '[uint64]',
|
'validator_indices': ['uint64'],
|
||||||
# Attestation data
|
# Attestation data
|
||||||
'data': AttestationData,
|
'data': AttestationData,
|
||||||
# Custody bitfield
|
# Custody bitfield
|
||||||
|
@ -631,6 +631,9 @@ Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethere
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def slot_to_epoch(slot: SlotNumber) -> EpochNumber:
|
def slot_to_epoch(slot: SlotNumber) -> EpochNumber:
|
||||||
|
"""
|
||||||
|
Return the epoch number of the given ``slot``.
|
||||||
|
"""
|
||||||
return slot // EPOCH_LENGTH
|
return slot // EPOCH_LENGTH
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -638,6 +641,9 @@ def slot_to_epoch(slot: SlotNumber) -> EpochNumber:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_current_epoch(state: BeaconState) -> EpochNumber:
|
def get_current_epoch(state: BeaconState) -> EpochNumber:
|
||||||
|
"""
|
||||||
|
Return the current epoch of the given ``state``.
|
||||||
|
"""
|
||||||
return slot_to_epoch(state.slot)
|
return slot_to_epoch(state.slot)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -645,6 +651,9 @@ def get_current_epoch(state: BeaconState) -> EpochNumber:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_epoch_start_slot(epoch: EpochNumber) -> SlotNumber:
|
def get_epoch_start_slot(epoch: EpochNumber) -> SlotNumber:
|
||||||
|
"""
|
||||||
|
Return the starting slot of the given ``epoch``.
|
||||||
|
"""
|
||||||
return epoch * EPOCH_LENGTH
|
return epoch * EPOCH_LENGTH
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -652,7 +661,7 @@ def get_epoch_start_slot(epoch: EpochNumber) -> SlotNumber:
|
||||||
```python
|
```python
|
||||||
def is_active_validator(validator: Validator, epoch: EpochNumber) -> bool:
|
def is_active_validator(validator: Validator, epoch: EpochNumber) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if ``validator`` is active.
|
Check if ``validator`` is active.
|
||||||
"""
|
"""
|
||||||
return validator.activation_epoch <= epoch < validator.exit_epoch
|
return validator.activation_epoch <= epoch < validator.exit_epoch
|
||||||
```
|
```
|
||||||
|
@ -662,7 +671,7 @@ def is_active_validator(validator: Validator, epoch: EpochNumber) -> bool:
|
||||||
```python
|
```python
|
||||||
def get_active_validator_indices(validators: List[Validator], epoch: EpochNumber) -> List[ValidatorIndex]:
|
def get_active_validator_indices(validators: List[Validator], epoch: EpochNumber) -> List[ValidatorIndex]:
|
||||||
"""
|
"""
|
||||||
Gets indices of active validators from ``validators``.
|
Get indices of active validators from ``validators``.
|
||||||
"""
|
"""
|
||||||
return [i for i, v in enumerate(validators) if is_active_validator(v, epoch)]
|
return [i for i, v in enumerate(validators) if is_active_validator(v, epoch)]
|
||||||
```
|
```
|
||||||
|
@ -672,7 +681,7 @@ def get_active_validator_indices(validators: List[Validator], epoch: EpochNumber
|
||||||
```python
|
```python
|
||||||
def shuffle(values: List[Any], seed: Bytes32) -> List[Any]:
|
def shuffle(values: List[Any], seed: Bytes32) -> List[Any]:
|
||||||
"""
|
"""
|
||||||
Returns the shuffled ``values`` with ``seed`` as entropy.
|
Return the shuffled ``values`` with ``seed`` as entropy.
|
||||||
"""
|
"""
|
||||||
values_count = len(values)
|
values_count = len(values)
|
||||||
|
|
||||||
|
@ -738,6 +747,9 @@ def split(values: List[Any], split_count: int) -> List[List[Any]]:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_epoch_committee_count(active_validator_count: int) -> int:
|
def get_epoch_committee_count(active_validator_count: int) -> int:
|
||||||
|
"""
|
||||||
|
Return the number of committees in one epoch.
|
||||||
|
"""
|
||||||
return max(
|
return max(
|
||||||
1,
|
1,
|
||||||
min(
|
min(
|
||||||
|
@ -754,8 +766,8 @@ def get_shuffling(seed: Bytes32,
|
||||||
validators: List[Validator],
|
validators: List[Validator],
|
||||||
epoch: EpochNumber) -> List[List[ValidatorIndex]]
|
epoch: EpochNumber) -> List[List[ValidatorIndex]]
|
||||||
"""
|
"""
|
||||||
Shuffles ``validators`` into crosslink committees seeded by ``seed`` and ``epoch``.
|
Shuffle ``validators`` into crosslink committees seeded by ``seed`` and ``epoch``.
|
||||||
Returns a list of ``committees_per_epoch`` committees where each
|
Return a list of ``committees_per_epoch`` committees where each
|
||||||
committee is itself a list of validator indices.
|
committee is itself a list of validator indices.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -779,6 +791,9 @@ def get_shuffling(seed: Bytes32,
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_previous_epoch_committee_count(state: BeaconState) -> int:
|
def get_previous_epoch_committee_count(state: BeaconState) -> int:
|
||||||
|
"""
|
||||||
|
Return the number of committees in the previous epoch of the given ``state``.
|
||||||
|
"""
|
||||||
previous_active_validators = get_active_validator_indices(
|
previous_active_validators = get_active_validator_indices(
|
||||||
state.validator_registry,
|
state.validator_registry,
|
||||||
state.previous_calculation_epoch,
|
state.previous_calculation_epoch,
|
||||||
|
@ -790,6 +805,9 @@ def get_previous_epoch_committee_count(state: BeaconState) -> int:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_current_epoch_committee_count(state: BeaconState) -> int:
|
def get_current_epoch_committee_count(state: BeaconState) -> int:
|
||||||
|
"""
|
||||||
|
Return the number of committees in the current epoch of the given ``state``.
|
||||||
|
"""
|
||||||
current_active_validators = get_active_validator_indices(
|
current_active_validators = get_active_validator_indices(
|
||||||
state.validator_registry,
|
state.validator_registry,
|
||||||
state.current_calculation_epoch,
|
state.current_calculation_epoch,
|
||||||
|
@ -803,7 +821,7 @@ def get_current_epoch_committee_count(state: BeaconState) -> int:
|
||||||
def get_crosslink_committees_at_slot(state: BeaconState,
|
def get_crosslink_committees_at_slot(state: BeaconState,
|
||||||
slot: SlotNumber) -> List[Tuple[List[ValidatorIndex], ShardNumber]]:
|
slot: SlotNumber) -> List[Tuple[List[ValidatorIndex], ShardNumber]]:
|
||||||
"""
|
"""
|
||||||
Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
Return the list of ``(committee, shard)`` tuples for the ``slot``.
|
||||||
"""
|
"""
|
||||||
epoch = slot_to_epoch(slot)
|
epoch = slot_to_epoch(slot)
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
|
@ -849,7 +867,7 @@ def get_crosslink_committees_at_slot(state: BeaconState,
|
||||||
def get_block_root(state: BeaconState,
|
def get_block_root(state: BeaconState,
|
||||||
slot: SlotNumber) -> Bytes32:
|
slot: SlotNumber) -> Bytes32:
|
||||||
"""
|
"""
|
||||||
Returns the block root at a recent ``slot``.
|
Return the block root at a recent ``slot``.
|
||||||
"""
|
"""
|
||||||
assert state.slot <= slot + LATEST_BLOCK_ROOTS_LENGTH
|
assert state.slot <= slot + LATEST_BLOCK_ROOTS_LENGTH
|
||||||
assert slot < state.slot
|
assert slot < state.slot
|
||||||
|
@ -864,7 +882,7 @@ def get_block_root(state: BeaconState,
|
||||||
def get_randao_mix(state: BeaconState,
|
def get_randao_mix(state: BeaconState,
|
||||||
epoch: EpochNumber) -> Bytes32:
|
epoch: EpochNumber) -> Bytes32:
|
||||||
"""
|
"""
|
||||||
Returns the randao mix at a recent ``epoch``.
|
Return the randao mix at a recent ``epoch``.
|
||||||
"""
|
"""
|
||||||
assert get_current_epoch(state) - LATEST_RANDAO_MIXES_LENGTH < epoch <= get_current_epoch(state)
|
assert get_current_epoch(state) - LATEST_RANDAO_MIXES_LENGTH < epoch <= get_current_epoch(state)
|
||||||
return state.latest_randao_mixes[epoch % LATEST_RANDAO_MIXES_LENGTH]
|
return state.latest_randao_mixes[epoch % LATEST_RANDAO_MIXES_LENGTH]
|
||||||
|
@ -876,7 +894,7 @@ def get_randao_mix(state: BeaconState,
|
||||||
def get_active_index_root(state: BeaconState,
|
def get_active_index_root(state: BeaconState,
|
||||||
epoch: EpochNumber) -> Bytes32:
|
epoch: EpochNumber) -> Bytes32:
|
||||||
"""
|
"""
|
||||||
Returns the index root at a recent ``epoch``.
|
Return the index root at a recent ``epoch``.
|
||||||
"""
|
"""
|
||||||
assert get_current_epoch(state) - LATEST_INDEX_ROOTS_LENGTH < epoch <= get_current_epoch(state)
|
assert get_current_epoch(state) - LATEST_INDEX_ROOTS_LENGTH < epoch <= get_current_epoch(state)
|
||||||
return state.latest_index_roots[epoch % LATEST_INDEX_ROOTS_LENGTH]
|
return state.latest_index_roots[epoch % LATEST_INDEX_ROOTS_LENGTH]
|
||||||
|
@ -903,7 +921,7 @@ def generate_seed(state: BeaconState,
|
||||||
def get_beacon_proposer_index(state: BeaconState,
|
def get_beacon_proposer_index(state: BeaconState,
|
||||||
slot: SlotNumber) -> ValidatorIndex:
|
slot: SlotNumber) -> ValidatorIndex:
|
||||||
"""
|
"""
|
||||||
Returns the beacon proposer index for the ``slot``.
|
Return the beacon proposer index for the ``slot``.
|
||||||
"""
|
"""
|
||||||
first_committee, _ = get_crosslink_committees_at_slot(state, slot)[0]
|
first_committee, _ = get_crosslink_committees_at_slot(state, slot)[0]
|
||||||
return first_committee[slot % len(first_committee)]
|
return first_committee[slot % len(first_committee)]
|
||||||
|
@ -929,7 +947,7 @@ def get_attestation_participants(state: BeaconState,
|
||||||
attestation_data: AttestationData,
|
attestation_data: AttestationData,
|
||||||
bitfield: bytes) -> List[ValidatorIndex]:
|
bitfield: bytes) -> List[ValidatorIndex]:
|
||||||
"""
|
"""
|
||||||
Returns the participant indices at for the ``attestation_data`` and ``bitfield``.
|
Return the participant indices at for the ``attestation_data`` and ``bitfield``.
|
||||||
"""
|
"""
|
||||||
# Find the committee in the list with the desired shard
|
# Find the committee in the list with the desired shard
|
||||||
crosslink_committees = get_crosslink_committees_at_slot(state, attestation_data.slot)
|
crosslink_committees = get_crosslink_committees_at_slot(state, attestation_data.slot)
|
||||||
|
@ -957,7 +975,7 @@ def get_attestation_participants(state: BeaconState,
|
||||||
```python
|
```python
|
||||||
def get_effective_balance(state: State, index: ValidatorIndex) -> Gwei:
|
def get_effective_balance(state: State, index: ValidatorIndex) -> Gwei:
|
||||||
"""
|
"""
|
||||||
Returns the effective balance (also known as "balance at stake") for a ``validator`` with the given ``index``.
|
Return the effective balance (also known as "balance at stake") for a ``validator`` with the given ``index``.
|
||||||
"""
|
"""
|
||||||
return min(state.validator_balances[index], MAX_DEPOSIT_AMOUNT)
|
return min(state.validator_balances[index], MAX_DEPOSIT_AMOUNT)
|
||||||
```
|
```
|
||||||
|
@ -967,6 +985,9 @@ def get_effective_balance(state: State, index: ValidatorIndex) -> Gwei:
|
||||||
```python
|
```python
|
||||||
def get_fork_version(fork: Fork,
|
def get_fork_version(fork: Fork,
|
||||||
epoch: EpochNumber) -> int:
|
epoch: EpochNumber) -> int:
|
||||||
|
"""
|
||||||
|
Return the fork version of the given ``epoch``.
|
||||||
|
"""
|
||||||
if epoch < fork.epoch:
|
if epoch < fork.epoch:
|
||||||
return fork.previous_version
|
return fork.previous_version
|
||||||
else:
|
else:
|
||||||
|
@ -979,10 +1000,11 @@ def get_fork_version(fork: Fork,
|
||||||
def get_domain(fork: Fork,
|
def get_domain(fork: Fork,
|
||||||
epoch: EpochNumber,
|
epoch: EpochNumber,
|
||||||
domain_type: int) -> int:
|
domain_type: int) -> int:
|
||||||
return get_fork_version(
|
"""
|
||||||
fork,
|
Get the domain number that represents the fork meta and signature domain.
|
||||||
epoch,
|
"""
|
||||||
) * 2**32 + domain_type
|
fork_version = get_fork_version(fork, epoch)
|
||||||
|
return fork_version * 2**32 + domain_type
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_bitfield_bit`
|
### `get_bitfield_bit`
|
||||||
|
@ -1049,8 +1071,8 @@ def verify_slashable_attestation(state: BeaconState, slashable_attestation: Slas
|
||||||
bls_aggregate_pubkeys([state.validator_registry[i].pubkey for i in custody_bit_1_indices]),
|
bls_aggregate_pubkeys([state.validator_registry[i].pubkey for i in custody_bit_1_indices]),
|
||||||
],
|
],
|
||||||
messages=[
|
messages=[
|
||||||
hash_tree_root(AttestationDataAndCustodyBit(attestation_data=slashable_attestation.data, custody_bit=0b0)),
|
hash_tree_root(AttestationDataAndCustodyBit(data=slashable_attestation.data, custody_bit=0b0)),
|
||||||
hash_tree_root(AttestationDataAndCustodyBit(attestation_data=slashable_attestation.data, custody_bit=0b1)),
|
hash_tree_root(AttestationDataAndCustodyBit(data=slashable_attestation.data, custody_bit=0b1)),
|
||||||
],
|
],
|
||||||
signature=slashable_attestation.aggregate_signature,
|
signature=slashable_attestation.aggregate_signature,
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
|
@ -1065,9 +1087,9 @@ def verify_slashable_attestation(state: BeaconState, slashable_attestation: Slas
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def is_double_vote(attestation_data_1: AttestationData,
|
def is_double_vote(attestation_data_1: AttestationData,
|
||||||
attestation_data_2: AttestationData) -> bool
|
attestation_data_2: AttestationData) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if the two ``AttestationData`` have the same target.
|
Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
|
||||||
"""
|
"""
|
||||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||||
|
@ -1080,7 +1102,7 @@ def is_double_vote(attestation_data_1: AttestationData,
|
||||||
def is_surround_vote(attestation_data_1: AttestationData,
|
def is_surround_vote(attestation_data_1: AttestationData,
|
||||||
attestation_data_2: AttestationData) -> bool:
|
attestation_data_2: AttestationData) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||||
"""
|
"""
|
||||||
source_epoch_1 = attestation_data_1.justified_epoch
|
source_epoch_1 = attestation_data_1.justified_epoch
|
||||||
source_epoch_2 = attestation_data_2.justified_epoch
|
source_epoch_2 = attestation_data_2.justified_epoch
|
||||||
|
@ -1136,6 +1158,9 @@ def validate_proof_of_possession(state: BeaconState,
|
||||||
pubkey: BLSPubkey,
|
pubkey: BLSPubkey,
|
||||||
proof_of_possession: BLSSignature,
|
proof_of_possession: BLSSignature,
|
||||||
withdrawal_credentials: Bytes32) -> bool:
|
withdrawal_credentials: Bytes32) -> bool:
|
||||||
|
"""
|
||||||
|
Verify the given ``proof_of_possession``.
|
||||||
|
"""
|
||||||
proof_of_possession_data = DepositInput(
|
proof_of_possession_data = DepositInput(
|
||||||
pubkey=pubkey,
|
pubkey=pubkey,
|
||||||
withdrawal_credentials=withdrawal_credentials,
|
withdrawal_credentials=withdrawal_credentials,
|
||||||
|
@ -1208,16 +1233,24 @@ Note: All functions in this section mutate `state`.
|
||||||
#### `activate_validator`
|
#### `activate_validator`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def activate_validator(state: BeaconState, index: ValidatorIndex, genesis: bool) -> None:
|
def activate_validator(state: BeaconState, index: ValidatorIndex, is_genesis: bool) -> None:
|
||||||
|
"""
|
||||||
|
Activate the validator of the given ``index``.
|
||||||
|
Note that this function mutates ``state``.
|
||||||
|
"""
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
|
|
||||||
validator.activation_epoch = GENESIS_EPOCH if genesis else get_entry_exit_effect_epoch(get_current_epoch(state))
|
validator.activation_epoch = GENESIS_EPOCH if is_genesis else get_entry_exit_effect_epoch(get_current_epoch(state))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `initiate_validator_exit`
|
#### `initiate_validator_exit`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
|
def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
"""
|
||||||
|
Initiate the validator of the given ``index``.
|
||||||
|
Note that this function mutates ``state``.
|
||||||
|
"""
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
validator.status_flags |= INITIATED_EXIT
|
validator.status_flags |= INITIATED_EXIT
|
||||||
```
|
```
|
||||||
|
@ -1226,6 +1259,10 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def exit_validator(state: BeaconState, index: ValidatorIndex) -> None:
|
def exit_validator(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
"""
|
||||||
|
Exit the validator of the given ``index``.
|
||||||
|
Note that this function mutates ``state``.
|
||||||
|
"""
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
|
|
||||||
# The following updates only occur if not previous exited
|
# The following updates only occur if not previous exited
|
||||||
|
@ -1239,6 +1276,10 @@ def exit_validator(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def penalize_validator(state: BeaconState, index: ValidatorIndex) -> None:
|
def penalize_validator(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
"""
|
||||||
|
Penalize the validator of the given ``index``.
|
||||||
|
Note that this function mutates ``state``.
|
||||||
|
"""
|
||||||
exit_validator(state, index)
|
exit_validator(state, index)
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
state.latest_penalized_balances[get_current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH] += get_effective_balance(state, index)
|
state.latest_penalized_balances[get_current_epoch(state) % LATEST_PENALIZED_EXIT_LENGTH] += get_effective_balance(state, index)
|
||||||
|
@ -1254,6 +1295,10 @@ def penalize_validator(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def prepare_validator_for_withdrawal(state: BeaconState, index: ValidatorIndex) -> None:
|
def prepare_validator_for_withdrawal(state: BeaconState, index: ValidatorIndex) -> None:
|
||||||
|
"""
|
||||||
|
Set the validator with the given ``index`` with ``WITHDRAWABLE`` flag.
|
||||||
|
Note that this function mutates ``state``.
|
||||||
|
"""
|
||||||
validator = state.validator_registry[index]
|
validator = state.validator_registry[index]
|
||||||
validator.status_flags |= WITHDRAWABLE
|
validator.status_flags |= WITHDRAWABLE
|
||||||
```
|
```
|
||||||
|
@ -1382,6 +1427,9 @@ A valid block with slot `GENESIS_SLOT` (a "genesis block") has the following val
|
||||||
def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
genesis_time: int,
|
genesis_time: int,
|
||||||
latest_eth1_data: Eth1Data) -> BeaconState:
|
latest_eth1_data: Eth1Data) -> BeaconState:
|
||||||
|
"""
|
||||||
|
Get the initial ``BeaconState``.
|
||||||
|
"""
|
||||||
state = BeaconState(
|
state = BeaconState(
|
||||||
# Misc
|
# Misc
|
||||||
slot=GENESIS_SLOT,
|
slot=GENESIS_SLOT,
|
||||||
|
@ -1438,7 +1486,7 @@ def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
|
||||||
# Process initial activations
|
# Process initial activations
|
||||||
for validator_index, _ in enumerate(state.validator_registry):
|
for validator_index, _ in enumerate(state.validator_registry):
|
||||||
if get_effective_balance(state, validator_index) >= MAX_DEPOSIT_AMOUNT:
|
if get_effective_balance(state, validator_index) >= MAX_DEPOSIT_AMOUNT:
|
||||||
activate_validator(state, validator_index, True)
|
activate_validator(state, validator_index, is_genesis=True)
|
||||||
|
|
||||||
state.latest_index_roots[GENESIS_EPOCH % LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state.validator_registry, GENESIS_EPOCH))
|
state.latest_index_roots[GENESIS_EPOCH % LATEST_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state.validator_registry, GENESIS_EPOCH))
|
||||||
state.current_epoch_seed = generate_seed(state, GENESIS_EPOCH)
|
state.current_epoch_seed = generate_seed(state, GENESIS_EPOCH)
|
||||||
|
@ -1477,6 +1525,9 @@ The beacon chain fork choice rule is a hybrid that combines justification and fi
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_ancestor(store: Store, block: BeaconBlock, slot: SlotNumber) -> BeaconBlock:
|
def get_ancestor(store: Store, block: BeaconBlock, slot: SlotNumber) -> BeaconBlock:
|
||||||
|
"""
|
||||||
|
Get the ancestor of ``block`` with slot number ``slot``; return ``None`` if not found.
|
||||||
|
"""
|
||||||
if block.slot == slot:
|
if block.slot == slot:
|
||||||
return block
|
return block
|
||||||
elif block.slot < slot:
|
elif block.slot < slot:
|
||||||
|
@ -1493,6 +1544,9 @@ def get_ancestor(store: Store, block: BeaconBlock, slot: SlotNumber) -> BeaconBl
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def lmd_ghost(store: Store, start_state: BeaconState, start_block: BeaconBlock) -> BeaconBlock:
|
def lmd_ghost(store: Store, start_state: BeaconState, start_block: BeaconBlock) -> BeaconBlock:
|
||||||
|
"""
|
||||||
|
Execute the LMD-GHOST algorithm to find the head ``BeaconBlock``.
|
||||||
|
"""
|
||||||
validators = start_state.validator_registry
|
validators = start_state.validator_registry
|
||||||
active_validators = [
|
active_validators = [
|
||||||
validators[i]
|
validators[i]
|
||||||
|
@ -1657,6 +1711,9 @@ For each `deposit` in `block.body.deposits`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def verify_merkle_branch(leaf: Bytes32, branch: List[Bytes32], depth: int, index: int, root: Bytes32) -> bool:
|
def verify_merkle_branch(leaf: Bytes32, branch: List[Bytes32], depth: int, index: int, root: Bytes32) -> bool:
|
||||||
|
"""
|
||||||
|
Verify that the given ``leaf`` is on the merkle branch ``branch``.
|
||||||
|
"""
|
||||||
value = leaf
|
value = leaf
|
||||||
for i in range(depth):
|
for i in range(depth):
|
||||||
if index // (2**i) % 2:
|
if index // (2**i) % 2:
|
||||||
|
@ -1887,7 +1944,7 @@ def update_validator_registry(state: BeaconState) -> None:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Activate validator
|
# Activate validator
|
||||||
activate_validator(state, index, False)
|
activate_validator(state, index, is_genesis=False)
|
||||||
|
|
||||||
# Exit validators within the allowable balance churn
|
# Exit validators within the allowable balance churn
|
||||||
balance_churn = 0
|
balance_churn = 0
|
||||||
|
@ -1924,17 +1981,21 @@ Regardless of whether or not a validator set change happens, run the following:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_penalties_and_exits(state: BeaconState) -> None:
|
def process_penalties_and_exits(state: BeaconState) -> None:
|
||||||
|
"""
|
||||||
|
Process the penalties and prepare the validators who are eligible to withdrawal.
|
||||||
|
Note that this function mutates ``state``.
|
||||||
|
"""
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
# The active validators
|
# The active validators
|
||||||
active_validator_indices = get_active_validator_indices(state.validator_registry, current_epoch)
|
active_validator_indices = get_active_validator_indices(state.validator_registry, current_epoch)
|
||||||
# The total effective balance of active validators
|
# The total effective balance of active validators
|
||||||
total_balance = sum([get_effective_balance(state, i) for i in active_validator_indices])
|
total_balance = sum(get_effective_balance(state, i) for i in active_validator_indices)
|
||||||
|
|
||||||
for index, validator in enumerate(state.validator_registry):
|
for index, validator in enumerate(state.validator_registry):
|
||||||
if current_epoch == validator.penalized_epoch + LATEST_PENALIZED_EXIT_LENGTH // 2:
|
if current_epoch == validator.penalized_epoch + LATEST_PENALIZED_EXIT_LENGTH // 2:
|
||||||
e = current_epoch % LATEST_PENALIZED_EXIT_LENGTH
|
epoch_index = current_epoch % LATEST_PENALIZED_EXIT_LENGTH
|
||||||
total_at_start = state.latest_penalized_balances[(e + 1) % LATEST_PENALIZED_EXIT_LENGTH]
|
total_at_start = state.latest_penalized_balances[(epoch_index + 1) % LATEST_PENALIZED_EXIT_LENGTH]
|
||||||
total_at_end = state.latest_penalized_balances[e]
|
total_at_end = state.latest_penalized_balances[epoch_index]
|
||||||
total_penalties = total_at_end - total_at_start
|
total_penalties = total_at_end - total_at_start
|
||||||
penalty = get_effective_balance(state, index) * min(total_penalties * 3, total_balance) // total_balance
|
penalty = get_effective_balance(state, index) * min(total_penalties * 3, total_balance) // total_balance
|
||||||
state.validator_balances[index] -= penalty
|
state.validator_balances[index] -= penalty
|
||||||
|
|
Loading…
Reference in New Issue