processEpoch 5x faster, total 2x faster, with 16k validators (#157)

* processEpoch 5x faster, total 2x faster, with 16k validators

* don't recompute active_validator_indices as much

* remove duplicate process_ejections function
This commit is contained in:
Dustin Brody 2019-03-07 16:53:44 +00:00 committed by GitHub
parent 4d55cf8eea
commit 72749f4d04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 29 deletions

View File

@ -317,13 +317,15 @@ func get_attestation_participants*(state: BeaconState,
if aggregation_bit == 1:
result.add(validator_index)
func process_ejections*(state: var BeaconState) =
## Iterate through the validator registry
## and eject active validators with balance below ``EJECTION_BALANCE``.
for index in get_active_validator_indices(
# TODO v0.3.0 spec bug, has this as current_epoch(state)
state.validator_registry, get_current_epoch(state)):
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#ejections
func process_ejections*(state: var BeaconState, active_validator_indices: auto) =
## Iterate through the validator registry and eject active validators with
## balance below ``EJECTION_BALANCE``
##
## `active_validator_indices` was already computed in `processEpoch`. Reuse.
## Spec recomputes. This is called before validator reshuffling, so use that
## cached version from beginning of `processEpoch`.
for index in active_validator_indices:
if state.validator_balances[index] < EJECTION_BALANCE:
exit_validator(state, index)

View File

@ -406,16 +406,6 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
true
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#ejections
func process_ejections(state: var BeaconState) =
## Iterate through the validator registry and eject active validators with
## balance below ``EJECTION_BALANCE``
for index in get_active_validator_indices(
# TODO minor 0.3.0 bug: it says just current_epoch(state)
state.validator_registry, get_current_epoch(state)):
if state.validator_balances[index] < EJECTION_BALANCE:
exit_validator(state, index)
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#per-slot-processing
func processSlot(state: var BeaconState, previous_block_root: Eth2Digest) =
## Time on the beacon chain moves in slots. Every time we make it to a new
@ -597,9 +587,11 @@ func processEpoch(state: var BeaconState) =
current_epoch
next_epoch = (current_epoch + 1).Epoch
current_total_balance = get_total_balance(
state, get_active_validator_indices(
state.validator_registry, current_epoch))
active_validator_indices =
get_active_validator_indices(state.validator_registry, current_epoch)
current_total_balance =
get_total_balance(state, active_validator_indices)
# TODO doing this with iterators failed:
# https://github.com/nim-lang/Nim/issues/9827
@ -803,9 +795,6 @@ func processEpoch(state: var BeaconState) =
block: # Justification and finalization
let
active_validator_indices =
get_active_validator_indices(
state.validator_registry, slot_to_epoch(state.slot))
epochs_since_finality = next_epoch - state.finalized_epoch
proc update_balance(attesters: HashSet[ValidatorIndex], attesting_balance: uint64) =
@ -925,20 +914,29 @@ func processEpoch(state: var BeaconState) =
for slot in get_epoch_start_slot(previous_epoch) ..< get_epoch_start_slot(current_epoch):
let crosslink_committees_at_slot = get_crosslink_committees_at_slot(state, slot)
for crosslink_committee in crosslink_committees_at_slot:
let committee_attesting_validators =
let
committee_attesting_validators =
toSet(attesting_validators(crosslink_committee))
## Keep numerator and denominator separate to allow different
## orders of operation to keep exact equivalence. TODO, check
## spec to see if this kind of fragility is in spec. Wouldn't
## be great to depend on whether integer (a*b)/c or a*(b/c)'s
## being performed.
committee_attesting_balance =
total_attesting_balance(crosslink_committee)
committee_total_balance =
get_total_balance(state, crosslink_committee.committee)
for index in crosslink_committee.committee:
if index in committee_attesting_validators:
state.validator_balances[index.int] +=
base_reward(state, index) *
total_attesting_balance(crosslink_committee) div
get_total_balance(state, crosslink_committee.committee)
base_reward(state, index) * committee_attesting_balance div
committee_total_balance
else:
reduce_balance(
state.validator_balances[index], base_reward(state, index))
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#ejections
process_ejections(state)
process_ejections(state, active_validator_indices)
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#validator-registry-and-shuffling-seed-data
block: