double altair epoch slot processing speed (#2811)
* approximately double altair epoch processing speed * don't redundantly clear state balances cache * only invalidate altair state balances cache once in process_rewards_and_penalties()
This commit is contained in:
parent
ba06f13942
commit
98547e0c6b
|
@ -19,7 +19,7 @@ import
|
||||||
|
|
||||||
export extras, phase0, altair, merge
|
export extras, phase0, altair, merge
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_valid_merkle_branch
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_valid_merkle_branch
|
||||||
func is_valid_merkle_branch*(leaf: Eth2Digest, branch: openArray[Eth2Digest],
|
func is_valid_merkle_branch*(leaf: Eth2Digest, branch: openArray[Eth2Digest],
|
||||||
depth: int, index: uint64,
|
depth: int, index: uint64,
|
||||||
root: Eth2Digest): bool {.nbench.}=
|
root: Eth2Digest): bool {.nbench.}=
|
||||||
|
@ -39,7 +39,7 @@ func is_valid_merkle_branch*(leaf: Eth2Digest, branch: openArray[Eth2Digest],
|
||||||
value = eth2digest(buf)
|
value = eth2digest(buf)
|
||||||
value == root
|
value == root
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#increase_balance
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#increase_balance
|
||||||
func increase_balance*(balance: var Gwei, delta: Gwei) =
|
func increase_balance*(balance: var Gwei, delta: Gwei) =
|
||||||
balance += delta
|
balance += delta
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func increase_balance*(
|
||||||
if delta != 0: # avoid dirtying the balance cache if not needed
|
if delta != 0: # avoid dirtying the balance cache if not needed
|
||||||
increase_balance(state.balances[index], delta)
|
increase_balance(state.balances[index], delta)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#decrease_balance
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#decrease_balance
|
||||||
func decrease_balance*(balance: var Gwei, delta: Gwei) =
|
func decrease_balance*(balance: var Gwei, delta: Gwei) =
|
||||||
balance =
|
balance =
|
||||||
if delta > balance:
|
if delta > balance:
|
||||||
|
@ -64,8 +64,8 @@ func decrease_balance*(
|
||||||
if delta != 0: # avoid dirtying the balance cache if not needed
|
if delta != 0: # avoid dirtying the balance cache if not needed
|
||||||
decrease_balance(state.balances[index], delta)
|
decrease_balance(state.balances[index], delta)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#deposits
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#deposits
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.6/specs/altair/beacon-chain.md#modified-process_deposit
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#modified-process_deposit
|
||||||
func get_validator_from_deposit*(deposit: DepositData):
|
func get_validator_from_deposit*(deposit: DepositData):
|
||||||
Validator =
|
Validator =
|
||||||
let
|
let
|
||||||
|
@ -83,13 +83,13 @@ func get_validator_from_deposit*(deposit: DepositData):
|
||||||
effective_balance: effective_balance
|
effective_balance: effective_balance
|
||||||
)
|
)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_activation_exit_epoch
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_activation_exit_epoch
|
||||||
func compute_activation_exit_epoch(epoch: Epoch): Epoch =
|
func compute_activation_exit_epoch(epoch: Epoch): Epoch =
|
||||||
## Return the epoch during which validator activations and exits initiated in
|
## Return the epoch during which validator activations and exits initiated in
|
||||||
## ``epoch`` take effect.
|
## ``epoch`` take effect.
|
||||||
epoch + 1 + MAX_SEED_LOOKAHEAD
|
epoch + 1 + MAX_SEED_LOOKAHEAD
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_validator_churn_limit
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_validator_churn_limit
|
||||||
func get_validator_churn_limit(
|
func get_validator_churn_limit(
|
||||||
cfg: RuntimeConfig, state: SomeBeaconState, cache: var StateCache):
|
cfg: RuntimeConfig, state: SomeBeaconState, cache: var StateCache):
|
||||||
uint64 =
|
uint64 =
|
||||||
|
@ -99,7 +99,7 @@ func get_validator_churn_limit(
|
||||||
count_active_validators(
|
count_active_validators(
|
||||||
state, state.get_current_epoch(), cache) div cfg.CHURN_LIMIT_QUOTIENT)
|
state, state.get_current_epoch(), cache) div cfg.CHURN_LIMIT_QUOTIENT)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#initiate_validator_exit
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#initiate_validator_exit
|
||||||
func initiate_validator_exit*(cfg: RuntimeConfig, state: var SomeBeaconState,
|
func initiate_validator_exit*(cfg: RuntimeConfig, state: var SomeBeaconState,
|
||||||
index: ValidatorIndex, cache: var StateCache) =
|
index: ValidatorIndex, cache: var StateCache) =
|
||||||
## Initiate the exit of the validator with index ``index``.
|
## Initiate the exit of the validator with index ``index``.
|
||||||
|
@ -139,8 +139,8 @@ func initiate_validator_exit*(cfg: RuntimeConfig, state: var SomeBeaconState,
|
||||||
validator.withdrawable_epoch =
|
validator.withdrawable_epoch =
|
||||||
validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#slash_validator
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#slash_validator
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.6/specs/altair/beacon-chain.md#modified-slash_validator
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#modified-slash_validator
|
||||||
proc slash_validator*(
|
proc slash_validator*(
|
||||||
cfg: RuntimeConfig, state: var SomeBeaconState,
|
cfg: RuntimeConfig, state: var SomeBeaconState,
|
||||||
slashed_index: ValidatorIndex, cache: var StateCache) =
|
slashed_index: ValidatorIndex, cache: var StateCache) =
|
||||||
|
@ -216,7 +216,7 @@ func altairFork*(cfg: RuntimeConfig): Fork =
|
||||||
current_version: cfg.ALTAIR_FORK_VERSION,
|
current_version: cfg.ALTAIR_FORK_VERSION,
|
||||||
epoch: cfg.ALTAIR_FORK_EPOCH)
|
epoch: cfg.ALTAIR_FORK_EPOCH)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#genesis
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#genesis
|
||||||
proc initialize_beacon_state_from_eth1*(
|
proc initialize_beacon_state_from_eth1*(
|
||||||
cfg: RuntimeConfig,
|
cfg: RuntimeConfig,
|
||||||
eth1_block_hash: Eth2Digest,
|
eth1_block_hash: Eth2Digest,
|
||||||
|
@ -314,7 +314,7 @@ proc initialize_hashed_beacon_state_from_eth1*(
|
||||||
phase0.HashedBeaconState(
|
phase0.HashedBeaconState(
|
||||||
data: genesisState[], root: hash_tree_root(genesisState[]))
|
data: genesisState[], root: hash_tree_root(genesisState[]))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#genesis-block
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#genesis-block
|
||||||
func get_initial_beacon_block*(state: phase0.BeaconState):
|
func get_initial_beacon_block*(state: phase0.BeaconState):
|
||||||
phase0.TrustedSignedBeaconBlock =
|
phase0.TrustedSignedBeaconBlock =
|
||||||
# The genesis block is implicitly trusted
|
# The genesis block is implicitly trusted
|
||||||
|
@ -326,7 +326,7 @@ func get_initial_beacon_block*(state: phase0.BeaconState):
|
||||||
phase0.TrustedSignedBeaconBlock(
|
phase0.TrustedSignedBeaconBlock(
|
||||||
message: message, root: hash_tree_root(message))
|
message: message, root: hash_tree_root(message))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_block_root_at_slot
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_block_root_at_slot
|
||||||
func get_block_root_at_slot*(state: SomeBeaconState,
|
func get_block_root_at_slot*(state: SomeBeaconState,
|
||||||
slot: Slot): Eth2Digest =
|
slot: Slot): Eth2Digest =
|
||||||
## Return the block root at a recent ``slot``.
|
## Return the block root at a recent ``slot``.
|
||||||
|
@ -339,27 +339,29 @@ func get_block_root_at_slot*(state: SomeBeaconState,
|
||||||
doAssert slot < state.slot
|
doAssert slot < state.slot
|
||||||
state.block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
|
state.block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_block_root
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_block_root
|
||||||
func get_block_root*(state: SomeBeaconState, epoch: Epoch): Eth2Digest =
|
func get_block_root*(state: SomeBeaconState, epoch: Epoch): Eth2Digest =
|
||||||
## Return the block root at the start of a recent ``epoch``.
|
## Return the block root at the start of a recent ``epoch``.
|
||||||
get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch))
|
get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_total_balance
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_total_balance
|
||||||
func get_total_balance*(state: SomeBeaconState, validators: auto): Gwei =
|
template get_total_balance*(
|
||||||
|
state: SomeBeaconState, validator_indices: untyped): Gwei =
|
||||||
## Return the combined effective balance of the ``indices``.
|
## Return the combined effective balance of the ``indices``.
|
||||||
## ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
## ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
||||||
## Math safe up to ~10B ETH, afterwhich this overflows uint64.
|
## Math safe up to ~10B ETH, afterwhich this overflows uint64.
|
||||||
max(EFFECTIVE_BALANCE_INCREMENT,
|
var res = 0.Gwei
|
||||||
foldl(validators, a + state.validators[b].effective_balance, 0'u64)
|
for validator_index in validator_indices:
|
||||||
)
|
res += state.validators.asSeq()[validator_index].effective_balance
|
||||||
|
max(EFFECTIVE_BALANCE_INCREMENT, res)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue
|
||||||
func is_eligible_for_activation_queue(validator: Validator): bool =
|
func is_eligible_for_activation_queue(validator: Validator): bool =
|
||||||
## Check if ``validator`` is eligible to be placed into the activation queue.
|
## Check if ``validator`` is eligible to be placed into the activation queue.
|
||||||
validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and
|
validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and
|
||||||
validator.effective_balance == MAX_EFFECTIVE_BALANCE
|
validator.effective_balance == MAX_EFFECTIVE_BALANCE
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_eligible_for_activation
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_eligible_for_activation
|
||||||
func is_eligible_for_activation(state: SomeBeaconState, validator: Validator):
|
func is_eligible_for_activation(state: SomeBeaconState, validator: Validator):
|
||||||
bool =
|
bool =
|
||||||
## Check if ``validator`` is eligible for activation.
|
## Check if ``validator`` is eligible for activation.
|
||||||
|
@ -369,7 +371,7 @@ func is_eligible_for_activation(state: SomeBeaconState, validator: Validator):
|
||||||
# Has not yet been activated
|
# Has not yet been activated
|
||||||
validator.activation_epoch == FAR_FUTURE_EPOCH
|
validator.activation_epoch == FAR_FUTURE_EPOCH
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#registry-updates
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#registry-updates
|
||||||
proc process_registry_updates*(
|
proc process_registry_updates*(
|
||||||
cfg: RuntimeConfig, state: var SomeBeaconState, cache: var StateCache) {.nbench.} =
|
cfg: RuntimeConfig, state: var SomeBeaconState, cache: var StateCache) {.nbench.} =
|
||||||
## Process activation eligibility and ejections
|
## Process activation eligibility and ejections
|
||||||
|
@ -419,7 +421,7 @@ proc process_registry_updates*(
|
||||||
state.validators[index].activation_epoch =
|
state.validators[index].activation_epoch =
|
||||||
compute_activation_exit_epoch(get_current_epoch(state))
|
compute_activation_exit_epoch(get_current_epoch(state))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_valid_indexed_attestation
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_valid_indexed_attestation
|
||||||
proc is_valid_indexed_attestation*(
|
proc is_valid_indexed_attestation*(
|
||||||
state: SomeBeaconState, indexed_attestation: SomeIndexedAttestation,
|
state: SomeBeaconState, indexed_attestation: SomeIndexedAttestation,
|
||||||
flags: UpdateFlags): Result[void, cstring] =
|
flags: UpdateFlags): Result[void, cstring] =
|
||||||
|
@ -457,7 +459,7 @@ proc is_valid_indexed_attestation*(
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_attesting_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_attesting_indices
|
||||||
func get_attesting_indices*(state: SomeBeaconState,
|
func get_attesting_indices*(state: SomeBeaconState,
|
||||||
data: AttestationData,
|
data: AttestationData,
|
||||||
bits: CommitteeValidatorsBits,
|
bits: CommitteeValidatorsBits,
|
||||||
|
@ -509,8 +511,8 @@ proc is_valid_indexed_attestation*(
|
||||||
|
|
||||||
# Attestation validation
|
# Attestation validation
|
||||||
# ------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#attestations
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#attestations
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
|
||||||
|
|
||||||
func check_attestation_slot_target*(data: AttestationData): Result[void, cstring] =
|
func check_attestation_slot_target*(data: AttestationData): Result[void, cstring] =
|
||||||
if not (data.target.epoch == compute_epoch_at_slot(data.slot)):
|
if not (data.target.epoch == compute_epoch_at_slot(data.slot)):
|
||||||
|
@ -549,7 +551,7 @@ func check_attestation_index(
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.7/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#get_attestation_participation_flag_indices
|
||||||
func get_attestation_participation_flag_indices(state: altair.BeaconState,
|
func get_attestation_participation_flag_indices(state: altair.BeaconState,
|
||||||
data: AttestationData,
|
data: AttestationData,
|
||||||
inclusion_delay: uint64): seq[int] =
|
inclusion_delay: uint64): seq[int] =
|
||||||
|
@ -583,7 +585,7 @@ func get_attestation_participation_flag_indices(state: altair.BeaconState,
|
||||||
# TODO these duplicate some stuff in state_transition_epoch which uses TotalBalances
|
# TODO these duplicate some stuff in state_transition_epoch which uses TotalBalances
|
||||||
# better to centralize around that if feasible
|
# better to centralize around that if feasible
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_total_active_balance
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_total_active_balance
|
||||||
func get_total_active_balance*(state: SomeBeaconState, cache: var StateCache): Gwei =
|
func get_total_active_balance*(state: SomeBeaconState, cache: var StateCache): Gwei =
|
||||||
## Return the combined effective balance of the active validators.
|
## Return the combined effective balance of the active validators.
|
||||||
# Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei
|
# Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei
|
||||||
|
@ -594,13 +596,13 @@ func get_total_active_balance*(state: SomeBeaconState, cache: var StateCache): G
|
||||||
get_total_balance(
|
get_total_balance(
|
||||||
state, cache.get_shuffled_active_validator_indices(state, epoch))
|
state, cache.get_shuffled_active_validator_indices(state, epoch))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.8/specs/altair/beacon-chain.md#get_base_reward_per_increment
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#get_base_reward_per_increment
|
||||||
func get_base_reward_per_increment*(
|
func get_base_reward_per_increment*(
|
||||||
state: altair.BeaconState, cache: var StateCache): Gwei =
|
state: altair.BeaconState, cache: var StateCache): Gwei =
|
||||||
EFFECTIVE_BALANCE_INCREMENT * BASE_REWARD_FACTOR div
|
EFFECTIVE_BALANCE_INCREMENT * BASE_REWARD_FACTOR div
|
||||||
integer_squareroot(get_total_active_balance(state, cache))
|
integer_squareroot(get_total_active_balance(state, cache))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.8/specs/altair/beacon-chain.md#get_base_reward
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#get_base_reward
|
||||||
func get_base_reward(
|
func get_base_reward(
|
||||||
state: altair.BeaconState, index: ValidatorIndex,
|
state: altair.BeaconState, index: ValidatorIndex,
|
||||||
base_reward_per_increment: Gwei): Gwei =
|
base_reward_per_increment: Gwei): Gwei =
|
||||||
|
@ -610,7 +612,7 @@ func get_base_reward(
|
||||||
state.validators[index].effective_balance div EFFECTIVE_BALANCE_INCREMENT
|
state.validators[index].effective_balance div EFFECTIVE_BALANCE_INCREMENT
|
||||||
increments * base_reward_per_increment
|
increments * base_reward_per_increment
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#attestations
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#attestations
|
||||||
proc check_attestation*(
|
proc check_attestation*(
|
||||||
state: SomeBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
state: SomeBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
||||||
cache: var StateCache): Result[void, cstring] =
|
cache: var StateCache): Result[void, cstring] =
|
||||||
|
@ -717,7 +719,7 @@ proc process_attestation*(
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.7/specs/altair/beacon-chain.md#get_next_sync_committee_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/beacon-chain.md#get_next_sync_committee_indices
|
||||||
func get_next_sync_committee_indices(state: altair.BeaconState):
|
func get_next_sync_committee_indices(state: altair.BeaconState):
|
||||||
seq[ValidatorIndex] =
|
seq[ValidatorIndex] =
|
||||||
## Return the sequence of sync committee indices (which may include
|
## Return the sequence of sync committee indices (which may include
|
||||||
|
@ -749,7 +751,7 @@ func get_next_sync_committee_indices(state: altair.BeaconState):
|
||||||
i += 1'u64
|
i += 1'u64
|
||||||
sync_committee_indices
|
sync_committee_indices
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.7/specs/altair/beacon-chain.md#get_next_sync_committee
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/beacon-chain.md#get_next_sync_committee
|
||||||
proc get_next_sync_committee*(state: altair.BeaconState): SyncCommittee =
|
proc get_next_sync_committee*(state: altair.BeaconState): SyncCommittee =
|
||||||
## Return the *next* sync committee for a given ``state``.
|
## Return the *next* sync committee for a given ``state``.
|
||||||
let indices = get_next_sync_committee_indices(state)
|
let indices = get_next_sync_committee_indices(state)
|
||||||
|
@ -771,7 +773,7 @@ proc get_next_sync_committee*(state: altair.BeaconState): SyncCommittee =
|
||||||
res.aggregate_pubkey = finish(attestersAgg).toPubKey()
|
res.aggregate_pubkey = finish(attestersAgg).toPubKey()
|
||||||
res
|
res
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.6/specs/altair/fork.md#upgrading-the-state
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/fork.md#upgrading-the-state
|
||||||
func translate_participation(
|
func translate_participation(
|
||||||
state: var altair.BeaconState,
|
state: var altair.BeaconState,
|
||||||
pending_attestations: openArray[phase0.PendingAttestation]) =
|
pending_attestations: openArray[phase0.PendingAttestation]) =
|
||||||
|
|
|
@ -23,7 +23,7 @@ import
|
||||||
export
|
export
|
||||||
phase0, altair, eth2_merkleization, ssz_codec
|
phase0, altair, eth2_merkleization, ssz_codec
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#integer_squareroot
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#integer_squareroot
|
||||||
func integer_squareroot*(n: SomeInteger): SomeInteger =
|
func integer_squareroot*(n: SomeInteger): SomeInteger =
|
||||||
## Return the largest integer ``x`` such that ``x**2 <= n``.
|
## Return the largest integer ``x`` such that ``x**2 <= n``.
|
||||||
doAssert n >= 0'u64
|
doAssert n >= 0'u64
|
||||||
|
@ -36,7 +36,7 @@ func integer_squareroot*(n: SomeInteger): SomeInteger =
|
||||||
y = (x + n div x) div 2
|
y = (x + n div x) div 2
|
||||||
x
|
x
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_epoch_at_slot
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_epoch_at_slot
|
||||||
func compute_epoch_at_slot*(slot: Slot|uint64): Epoch =
|
func compute_epoch_at_slot*(slot: Slot|uint64): Epoch =
|
||||||
## Return the epoch number at ``slot``.
|
## Return the epoch number at ``slot``.
|
||||||
(slot div SLOTS_PER_EPOCH).Epoch
|
(slot div SLOTS_PER_EPOCH).Epoch
|
||||||
|
@ -53,24 +53,30 @@ template syncCommitteePeriod*(epoch: Epoch): uint64 =
|
||||||
template syncCommitteePeriod*(slot: Slot): uint64 =
|
template syncCommitteePeriod*(slot: Slot): uint64 =
|
||||||
epoch(slot) div EPOCHS_PER_SYNC_COMMITTEE_PERIOD
|
epoch(slot) div EPOCHS_PER_SYNC_COMMITTEE_PERIOD
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch
|
||||||
func compute_start_slot_at_epoch*(epoch: Epoch): Slot =
|
func compute_start_slot_at_epoch*(epoch: Epoch): Slot =
|
||||||
## Return the start slot of ``epoch``.
|
## Return the start slot of ``epoch``.
|
||||||
(epoch * SLOTS_PER_EPOCH).Slot
|
(epoch * SLOTS_PER_EPOCH).Slot
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_active_validator
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#is_active_validator
|
||||||
func is_active_validator*(validator: Validator, epoch: Epoch): bool =
|
func is_active_validator*(validator: Validator, epoch: Epoch): bool =
|
||||||
## Check if ``validator`` is active
|
## Check if ``validator`` is active
|
||||||
validator.activation_epoch <= epoch and epoch < validator.exit_epoch
|
validator.activation_epoch <= epoch and epoch < validator.exit_epoch
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_active_validator_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_active_validator_indices
|
||||||
|
iterator get_active_validator_indices*(state: SomeBeaconState, epoch: Epoch):
|
||||||
|
ValidatorIndex =
|
||||||
|
for idx in 0..<state.validators.len:
|
||||||
|
if is_active_validator(state.validators[idx], epoch):
|
||||||
|
yield idx.ValidatorIndex
|
||||||
|
|
||||||
func get_active_validator_indices*(state: SomeBeaconState, epoch: Epoch):
|
func get_active_validator_indices*(state: SomeBeaconState, epoch: Epoch):
|
||||||
seq[ValidatorIndex] =
|
seq[ValidatorIndex] =
|
||||||
## Return the sequence of active validator indices at ``epoch``.
|
## Return the sequence of active validator indices at ``epoch``.
|
||||||
result = newSeqOfCap[ValidatorIndex](state.validators.len)
|
var res = newSeqOfCap[ValidatorIndex](state.validators.len)
|
||||||
for idx in 0..<state.validators.len:
|
for idx in get_active_validator_indices(state, epoch):
|
||||||
if is_active_validator(state.validators[idx], epoch):
|
res.add idx.ValidatorIndex
|
||||||
result.add idx.ValidatorIndex
|
res
|
||||||
|
|
||||||
func get_active_validator_indices_len*(state: SomeBeaconState, epoch: Epoch):
|
func get_active_validator_indices_len*(state: SomeBeaconState, epoch: Epoch):
|
||||||
uint64 =
|
uint64 =
|
||||||
|
@ -78,13 +84,13 @@ func get_active_validator_indices_len*(state: SomeBeaconState, epoch: Epoch):
|
||||||
if is_active_validator(state.validators[idx], epoch):
|
if is_active_validator(state.validators[idx], epoch):
|
||||||
inc result
|
inc result
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_current_epoch
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_current_epoch
|
||||||
func get_current_epoch*(state: SomeBeaconState): Epoch =
|
func get_current_epoch*(state: SomeBeaconState): Epoch =
|
||||||
## Return the current epoch.
|
## Return the current epoch.
|
||||||
doAssert state.slot >= GENESIS_SLOT, $state.slot
|
doAssert state.slot >= GENESIS_SLOT, $state.slot
|
||||||
compute_epoch_at_slot(state.slot)
|
compute_epoch_at_slot(state.slot)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_randao_mix
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_randao_mix
|
||||||
func get_randao_mix*(state: SomeBeaconState, epoch: Epoch): Eth2Digest =
|
func get_randao_mix*(state: SomeBeaconState, epoch: Epoch): Eth2Digest =
|
||||||
## Returns the randao mix at a recent ``epoch``.
|
## Returns the randao mix at a recent ``epoch``.
|
||||||
state.randao_mixes[epoch mod EPOCHS_PER_HISTORICAL_VECTOR]
|
state.randao_mixes[epoch mod EPOCHS_PER_HISTORICAL_VECTOR]
|
||||||
|
@ -109,7 +115,7 @@ func uint_to_bytes4*(x: uint64): array[4, byte] =
|
||||||
result[2] = ((x shr 16) and 0xff).byte
|
result[2] = ((x shr 16) and 0xff).byte
|
||||||
result[3] = ((x shr 24) and 0xff).byte
|
result[3] = ((x shr 24) and 0xff).byte
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_fork_data_root
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_fork_data_root
|
||||||
func compute_fork_data_root(current_version: Version,
|
func compute_fork_data_root(current_version: Version,
|
||||||
genesis_validators_root: Eth2Digest): Eth2Digest =
|
genesis_validators_root: Eth2Digest): Eth2Digest =
|
||||||
## Return the 32-byte fork data root for the ``current_version`` and
|
## Return the 32-byte fork data root for the ``current_version`` and
|
||||||
|
@ -121,7 +127,7 @@ func compute_fork_data_root(current_version: Version,
|
||||||
genesis_validators_root: genesis_validators_root
|
genesis_validators_root: genesis_validators_root
|
||||||
))
|
))
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_fork_digest
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_fork_digest
|
||||||
func compute_fork_digest*(current_version: Version,
|
func compute_fork_digest*(current_version: Version,
|
||||||
genesis_validators_root: Eth2Digest): ForkDigest =
|
genesis_validators_root: Eth2Digest): ForkDigest =
|
||||||
## Return the 4-byte fork digest for the ``current_version`` and
|
## Return the 4-byte fork digest for the ``current_version`` and
|
||||||
|
@ -132,7 +138,7 @@ func compute_fork_digest*(current_version: Version,
|
||||||
compute_fork_data_root(
|
compute_fork_data_root(
|
||||||
current_version, genesis_validators_root).data.toOpenArray(0, 3)
|
current_version, genesis_validators_root).data.toOpenArray(0, 3)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_domain
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_domain
|
||||||
func compute_domain*(
|
func compute_domain*(
|
||||||
domain_type: DomainType,
|
domain_type: DomainType,
|
||||||
fork_version: Version,
|
fork_version: Version,
|
||||||
|
@ -143,7 +149,7 @@ func compute_domain*(
|
||||||
result[0..3] = uint_to_bytes4(domain_type.uint64)
|
result[0..3] = uint_to_bytes4(domain_type.uint64)
|
||||||
result[4..31] = fork_data_root.data.toOpenArray(0, 27)
|
result[4..31] = fork_data_root.data.toOpenArray(0, 27)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_domain
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_domain
|
||||||
func get_domain*(
|
func get_domain*(
|
||||||
fork: Fork,
|
fork: Fork,
|
||||||
domain_type: DomainType,
|
domain_type: DomainType,
|
||||||
|
@ -164,7 +170,7 @@ func get_domain*(
|
||||||
## of a message.
|
## of a message.
|
||||||
get_domain(state.fork, domain_type, epoch, state.genesis_validators_root)
|
get_domain(state.fork, domain_type, epoch, state.genesis_validators_root)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_signing_root
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_signing_root
|
||||||
func compute_signing_root*(ssz_object: auto, domain: Eth2Domain): Eth2Digest =
|
func compute_signing_root*(ssz_object: auto, domain: Eth2Domain): Eth2Digest =
|
||||||
## Return the signing root of an object by calculating the root of the
|
## Return the signing root of an object by calculating the root of the
|
||||||
## object-domain tree.
|
## object-domain tree.
|
||||||
|
@ -174,7 +180,7 @@ func compute_signing_root*(ssz_object: auto, domain: Eth2Domain): Eth2Digest =
|
||||||
)
|
)
|
||||||
hash_tree_root(domain_wrapped_object)
|
hash_tree_root(domain_wrapped_object)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_seed
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_seed
|
||||||
func get_seed*(state: SomeBeaconState, epoch: Epoch, domain_type: DomainType):
|
func get_seed*(state: SomeBeaconState, epoch: Epoch, domain_type: DomainType):
|
||||||
Eth2Digest =
|
Eth2Digest =
|
||||||
## Return the seed at ``epoch``.
|
## Return the seed at ``epoch``.
|
||||||
|
@ -192,12 +198,12 @@ func get_seed*(state: SomeBeaconState, epoch: Epoch, domain_type: DomainType):
|
||||||
epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1).data
|
epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1).data
|
||||||
eth2digest(seed_input)
|
eth2digest(seed_input)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.8/specs/altair/beacon-chain.md#add_flag
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#add_flag
|
||||||
func add_flag*(flags: ParticipationFlags, flag_index: int): ParticipationFlags =
|
func add_flag*(flags: ParticipationFlags, flag_index: int): ParticipationFlags =
|
||||||
let flag = ParticipationFlags(1'u8 shl flag_index)
|
let flag = ParticipationFlags(1'u8 shl flag_index)
|
||||||
flags or flag
|
flags or flag
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.8/specs/altair/beacon-chain.md#has_flag
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#has_flag
|
||||||
func has_flag*(flags: ParticipationFlags, flag_index: int): bool =
|
func has_flag*(flags: ParticipationFlags, flag_index: int): bool =
|
||||||
let flag = ParticipationFlags(1'u8 shl flag_index)
|
let flag = ParticipationFlags(1'u8 shl flag_index)
|
||||||
(flags and flag) == flag
|
(flags and flag) == flag
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[math, sequtils, sets, tables, algorithm],
|
std/[math, sets, tables, algorithm],
|
||||||
stew/[bitops2], chronicles,
|
stew/[bitops2], chronicles,
|
||||||
../extras,
|
../extras,
|
||||||
./datatypes/[phase0, altair],
|
./datatypes/[phase0, altair],
|
||||||
|
@ -160,26 +160,62 @@ func is_eligible_validator*(validator: RewardStatus): bool =
|
||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#get_unslashed_participating_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#get_unslashed_participating_indices
|
||||||
|
iterator get_unslashed_participating_indices(
|
||||||
|
state: altair.BeaconState, flag_index: int, epoch: Epoch):
|
||||||
|
ValidatorIndex =
|
||||||
|
## Return the set of validator indices that are both active and unslashed for
|
||||||
|
## the given ``flag_index`` and ``epoch``.
|
||||||
|
doAssert epoch in [get_previous_epoch(state), get_current_epoch(state)]
|
||||||
|
let epoch_participation =
|
||||||
|
if epoch == get_current_epoch(state):
|
||||||
|
unsafeAddr state.current_epoch_participation
|
||||||
|
else:
|
||||||
|
unsafeAddr state.previous_epoch_participation
|
||||||
|
|
||||||
|
for validator_index in get_active_validator_indices(state, epoch):
|
||||||
|
if has_flag(epoch_participation[][validator_index], flag_index) and
|
||||||
|
not state.validators[validator_index].slashed:
|
||||||
|
yield validator_index
|
||||||
|
|
||||||
func get_unslashed_participating_indices(
|
func get_unslashed_participating_indices(
|
||||||
state: altair.BeaconState, flag_index: int, epoch: Epoch):
|
state: altair.BeaconState, flag_index: int, epoch: Epoch):
|
||||||
HashSet[ValidatorIndex] =
|
HashSet[ValidatorIndex] =
|
||||||
## Return the set of validator indices that are both active and unslashed for
|
## Return the set of validator indices that are both active and unslashed for
|
||||||
## the given ``flag_index`` and ``epoch``.
|
## the given ``flag_index`` and ``epoch``.
|
||||||
doAssert epoch in [get_previous_epoch(state), get_current_epoch(state)]
|
|
||||||
let
|
|
||||||
epoch_participation =
|
|
||||||
if epoch == get_current_epoch(state):
|
|
||||||
state.current_epoch_participation
|
|
||||||
else:
|
|
||||||
state.previous_epoch_participation
|
|
||||||
|
|
||||||
# TODO use cached version, or similar
|
|
||||||
active_validator_indices = get_active_validator_indices(state, epoch)
|
|
||||||
|
|
||||||
var res: HashSet[ValidatorIndex]
|
var res: HashSet[ValidatorIndex]
|
||||||
for validator_index in active_validator_indices:
|
for validator_index in get_unslashed_participating_indices(
|
||||||
if has_flag(epoch_participation[validator_index], flag_index) and
|
state, flag_index, epoch):
|
||||||
not state.validators[validator_index].slashed:
|
res.incl validator_index
|
||||||
|
res
|
||||||
|
|
||||||
|
# For the first couple of beacon chain years there are likely to be more
|
||||||
|
# active validators than any other sort. As Ethereum matures, this won't
|
||||||
|
# continue to hold, and alternative optimization can be pursued.
|
||||||
|
iterator get_slashed_or_nonparticipating_indices(
|
||||||
|
state: altair.BeaconState, flag_index: int, epoch: Epoch):
|
||||||
|
ValidatorIndex =
|
||||||
|
## Return the set of validator indices that are both active and unslashed for
|
||||||
|
## the given ``flag_index`` and ``epoch``.
|
||||||
|
doAssert epoch in [get_previous_epoch(state), get_current_epoch(state)]
|
||||||
|
let epoch_participation =
|
||||||
|
if epoch == get_current_epoch(state):
|
||||||
|
unsafeAddr state.current_epoch_participation
|
||||||
|
else:
|
||||||
|
unsafeAddr state.previous_epoch_participation
|
||||||
|
|
||||||
|
for validator_index in get_active_validator_indices(state, epoch):
|
||||||
|
if not has_flag(epoch_participation[][validator_index], flag_index) or
|
||||||
|
state.validators[validator_index].slashed:
|
||||||
|
yield validator_index
|
||||||
|
|
||||||
|
func get_slashed_or_nonparticipating_indices(
|
||||||
|
state: altair.BeaconState, flag_index: int, epoch: Epoch):
|
||||||
|
HashSet[ValidatorIndex] =
|
||||||
|
## Return the set of validator indices that are both active and unslashed for
|
||||||
|
## the given ``flag_index`` and ``epoch``.
|
||||||
|
var res: HashSet[ValidatorIndex]
|
||||||
|
for validator_index in get_slashed_or_nonparticipating_indices(
|
||||||
|
state, flag_index, epoch):
|
||||||
res.incl validator_index
|
res.incl validator_index
|
||||||
res
|
res
|
||||||
|
|
||||||
|
@ -383,15 +419,19 @@ proc process_justification_and_finalization*(state: var altair.BeaconState,
|
||||||
# result in modifying this stub.
|
# result in modifying this stub.
|
||||||
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
|
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
|
||||||
return
|
return
|
||||||
let
|
|
||||||
# these ultimately differ from phase0 only in these lines
|
# These ultimately differ from phase0 only in these lines, with the phase 0
|
||||||
|
# version effectively embedding weigh_justification_and_finalization(), for
|
||||||
|
# historical reasons.
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/phase0/beacon-chain.md#justification-and-finalization
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/phase0/beacon-chain.md#justification-and-finalization
|
||||||
previous_indices = get_unslashed_participating_indices(
|
let
|
||||||
state, TIMELY_TARGET_FLAG_INDEX, get_previous_epoch(state))
|
previous_target_balance = get_total_balance(state,
|
||||||
current_indices = get_unslashed_participating_indices(
|
get_unslashed_participating_indices(
|
||||||
state, TIMELY_TARGET_FLAG_INDEX, get_current_epoch(state))
|
state, TIMELY_TARGET_FLAG_INDEX, get_previous_epoch(state)))
|
||||||
previous_target_balance = get_total_balance(state, previous_indices)
|
current_target_balance = get_total_balance(state,
|
||||||
current_target_balance = get_total_balance(state, current_indices)
|
get_unslashed_participating_indices(
|
||||||
|
state, TIMELY_TARGET_FLAG_INDEX, get_current_epoch(state)))
|
||||||
|
|
||||||
weigh_justification_and_finalization(
|
weigh_justification_and_finalization(
|
||||||
state, total_active_balance, previous_target_balance,
|
state, total_active_balance, previous_target_balance,
|
||||||
current_target_balance, flags)
|
current_target_balance, flags)
|
||||||
|
@ -401,7 +441,7 @@ func get_base_reward_sqrt*(state: phase0.BeaconState, index: ValidatorIndex,
|
||||||
total_balance_sqrt: auto): Gwei =
|
total_balance_sqrt: auto): Gwei =
|
||||||
# Spec function recalculates total_balance every time, which creates an
|
# Spec function recalculates total_balance every time, which creates an
|
||||||
# O(n^2) situation.
|
# O(n^2) situation.
|
||||||
let effective_balance = state.validators[index].effective_balance
|
let effective_balance = state.validators.asSeq()[index].effective_balance
|
||||||
effective_balance * BASE_REWARD_FACTOR div
|
effective_balance * BASE_REWARD_FACTOR div
|
||||||
total_balance_sqrt div BASE_REWARDS_PER_EPOCH
|
total_balance_sqrt div BASE_REWARDS_PER_EPOCH
|
||||||
|
|
||||||
|
@ -622,11 +662,13 @@ iterator get_inactivity_penalty_deltas(cfg: RuntimeConfig, state: altair.BeaconS
|
||||||
## Return the inactivity penalty deltas by considering timely target
|
## Return the inactivity penalty deltas by considering timely target
|
||||||
## participation flags and inactivity scores.
|
## participation flags and inactivity scores.
|
||||||
let
|
let
|
||||||
previous_epoch = get_previous_epoch(state)
|
|
||||||
matching_target_indices =
|
|
||||||
get_unslashed_participating_indices(state, TIMELY_TARGET_FLAG_INDEX, previous_epoch)
|
|
||||||
penalty_denominator =
|
penalty_denominator =
|
||||||
cfg.INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT_ALTAIR
|
cfg.INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT_ALTAIR
|
||||||
|
previous_epoch = get_previous_epoch(state)
|
||||||
|
|
||||||
|
# This is the set-complement of what the spec calls matching_target_indices
|
||||||
|
nontarget_indices = get_slashed_or_nonparticipating_indices(
|
||||||
|
state, TIMELY_TARGET_FLAG_INDEX, previous_epoch)
|
||||||
|
|
||||||
for index in 0 ..< state.validators.len:
|
for index in 0 ..< state.validators.len:
|
||||||
# get_eligible_validator_indices()
|
# get_eligible_validator_indices()
|
||||||
|
@ -636,7 +678,7 @@ iterator get_inactivity_penalty_deltas(cfg: RuntimeConfig, state: altair.BeaconS
|
||||||
continue
|
continue
|
||||||
|
|
||||||
template vidx: untyped = index.ValidatorIndex
|
template vidx: untyped = index.ValidatorIndex
|
||||||
if not (vidx in matching_target_indices):
|
if vidx in nontarget_indices:
|
||||||
let
|
let
|
||||||
penalty_numerator = state.validators[index].effective_balance *
|
penalty_numerator = state.validators[index].effective_balance *
|
||||||
state.inactivity_scores[index]
|
state.inactivity_scores[index]
|
||||||
|
@ -660,8 +702,10 @@ func process_rewards_and_penalties(
|
||||||
# update the raw list directly
|
# update the raw list directly
|
||||||
state.balances.clearCache()
|
state.balances.clearCache()
|
||||||
for idx, v in rewards.statuses:
|
for idx, v in rewards.statuses:
|
||||||
increase_balance(state.balances.asSeq()[idx], v.delta.rewards)
|
var balance = state.balances.asSeq()[idx]
|
||||||
decrease_balance(state.balances.asSeq()[idx], v.delta.penalties)
|
increase_balance(balance, v.delta.rewards)
|
||||||
|
decrease_balance(balance, v.delta.penalties)
|
||||||
|
state.balances.asSeq()[idx] = balance
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#rewards-and-penalties
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#rewards-and-penalties
|
||||||
func process_rewards_and_penalties(
|
func process_rewards_and_penalties(
|
||||||
|
@ -690,9 +734,12 @@ func process_rewards_and_penalties(
|
||||||
for validator_index, penalty in get_inactivity_penalty_deltas(cfg, state):
|
for validator_index, penalty in get_inactivity_penalty_deltas(cfg, state):
|
||||||
penalties[validator_index] += penalty
|
penalties[validator_index] += penalty
|
||||||
|
|
||||||
|
state.balances.clearCache()
|
||||||
for index in 0 ..< len(state.validators):
|
for index in 0 ..< len(state.validators):
|
||||||
increase_balance(state, ValidatorIndex(index), rewards[index])
|
var balance = state.balances.asSeq()[index]
|
||||||
decrease_balance(state, ValidatorIndex(index), penalties[index])
|
increase_balance(balance, rewards[index])
|
||||||
|
decrease_balance(balance, penalties[index])
|
||||||
|
state.balances.asSeq()[index] = balance
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#slashings
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#slashings
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#slashings
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.0-beta.2/specs/altair/beacon-chain.md#slashings
|
||||||
|
@ -818,24 +865,27 @@ func process_inactivity_updates*(cfg: RuntimeConfig, state: var altair.BeaconSta
|
||||||
# TODO actually implement get_eligible_validator_indices() as an iterator
|
# TODO actually implement get_eligible_validator_indices() as an iterator
|
||||||
let
|
let
|
||||||
previous_epoch = get_previous_epoch(state) # get_eligible_validator_indices()
|
previous_epoch = get_previous_epoch(state) # get_eligible_validator_indices()
|
||||||
unslashed_participating_indices =
|
slashed_or_nonparticipating_indices =
|
||||||
get_unslashed_participating_indices(
|
get_slashed_or_nonparticipating_indices(
|
||||||
state, TIMELY_TARGET_FLAG_INDEX, get_previous_epoch(state))
|
state, TIMELY_TARGET_FLAG_INDEX, get_previous_epoch(state))
|
||||||
|
let not_in_inactivity_leak = not is_in_inactivity_leak(state)
|
||||||
for index in 0'u64 ..< state.validators.lenu64:
|
for index in 0'u64 ..< state.validators.lenu64:
|
||||||
# get_eligible_validator_indices()
|
# get_eligible_validator_indices()
|
||||||
let v = state.validators[index]
|
let v = state.validators.asSeq()[index]
|
||||||
if not (is_active_validator(v, previous_epoch) or (v.slashed and previous_epoch + 1 < v.withdrawable_epoch)):
|
if not (is_active_validator(v, previous_epoch) or (v.slashed and previous_epoch + 1 < v.withdrawable_epoch)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Increase the inactivity score of inactive validators
|
# Increase the inactivity score of inactive validators
|
||||||
if index.ValidatorIndex in unslashed_participating_indices:
|
var inactivity_score = state.inactivity_scores[index]
|
||||||
state.inactivity_scores[index] -= min(1'u64, state.inactivity_scores[index])
|
if index.ValidatorIndex notin slashed_or_nonparticipating_indices:
|
||||||
|
inactivity_score -= min(1'u64, inactivity_score)
|
||||||
else:
|
else:
|
||||||
state.inactivity_scores[index] += cfg.INACTIVITY_SCORE_BIAS
|
inactivity_score += cfg.INACTIVITY_SCORE_BIAS
|
||||||
# Decrease the inactivity score of all eligible validators during a
|
# Decrease the inactivity score of all eligible validators during a
|
||||||
# leak-free epoch
|
# leak-free epoch
|
||||||
if not is_in_inactivity_leak(state):
|
if not_in_inactivity_leak:
|
||||||
state.inactivity_scores[index] -= min(INACTIVITY_SCORE_RECOVERY_RATE.uint64, state.inactivity_scores[index])
|
inactivity_score -= min(INACTIVITY_SCORE_RECOVERY_RATE.uint64, inactivity_score)
|
||||||
|
state.inactivity_scores[index] = inactivity_score
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#epoch-processing
|
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#epoch-processing
|
||||||
proc process_epoch*(
|
proc process_epoch*(
|
||||||
|
|
Loading…
Reference in New Issue