Add non-attesting-validators instrumentation in process_justification_and_finalization(...) (#323)

* update process_justifications_and_finalizations(...) to 0.8.1
This commit is contained in:
Dustin Brody 2019-07-16 07:34:11 +00:00 committed by GitHub
parent d1d5497233
commit f6fd089ae7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 50 deletions

View File

@ -301,8 +301,10 @@ type
current_crosslinks*: array[SHARD_COUNT, Crosslink] current_crosslinks*: array[SHARD_COUNT, Crosslink]
# Finality # Finality
justification_bits*: uint64 ##\ justification_bits*: uint8 ##\
## Bit set for every recent justified epoch ## Bit set for every recent justified epoch
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
## with ssz/hashing.
previous_justified_checkpoint*: Checkpoint ##\ previous_justified_checkpoint*: Checkpoint ##\
## Previous epoch snapshot ## Previous epoch snapshot

View File

@ -67,7 +67,7 @@ func get_matching_head_attestations(state: BeaconState, epoch: Epoch):
get_block_root_at_slot(state, get_attestation_data_slot(state, it.data)) get_block_root_at_slot(state, get_attestation_data_slot(state, it.data))
) )
func get_unslashed_attesting_indices( func get_attesting_indices(
state: BeaconState, attestations: openarray[PendingAttestation], state: BeaconState, attestations: openarray[PendingAttestation],
stateCache: var StateCache): HashSet[ValidatorIndex] = stateCache: var StateCache): HashSet[ValidatorIndex] =
result = initSet[ValidatorIndex]() result = initSet[ValidatorIndex]()
@ -75,6 +75,10 @@ func get_unslashed_attesting_indices(
result = result.union(get_attesting_indices( result = result.union(get_attesting_indices(
state, a.data, a.aggregation_bits, stateCache)) state, a.data, a.aggregation_bits, stateCache))
func get_unslashed_attesting_indices(
state: BeaconState, attestations: openarray[PendingAttestation],
stateCache: var StateCache): HashSet[ValidatorIndex] =
result = get_attesting_indices(state, attestations, stateCache)
for index in result: for index in result:
if state.validators[index].slashed: if state.validators[index].slashed:
result.excl index result.excl index
@ -181,8 +185,8 @@ func get_winning_crosslink_and_attesting_indices(
(winning_crosslink, (winning_crosslink,
get_unslashed_attesting_indices(state, winning_attestations, stateCache)) get_unslashed_attesting_indices(state, winning_attestations, stateCache))
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#justification-and-finalization # https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#justification-and-finalization
func process_justification_and_finalization( proc process_justification_and_finalization(
state: var BeaconState, stateCache: var StateCache) = state: var BeaconState, stateCache: var StateCache) =
if get_current_epoch(state) <= GENESIS_EPOCH + 1: if get_current_epoch(state) <= GENESIS_EPOCH + 1:
return return
@ -190,33 +194,59 @@ func process_justification_and_finalization(
let let
previous_epoch = get_previous_epoch(state) previous_epoch = get_previous_epoch(state)
current_epoch = get_current_epoch(state) current_epoch = get_current_epoch(state)
old_previous_justified_epoch = state.previous_justified_checkpoint.epoch old_previous_justified_checkpoint = state.previous_justified_checkpoint
old_current_justified_epoch = state.current_justified_checkpoint.epoch old_current_justified_checkpoint = state.current_justified_checkpoint
## Bitvector[4] <-> uint8 mapping:
## state.justification_bits[0] is (state.justification_bits shr 0) and 1
## state.justification_bits[1] is (state.justification_bits shr 1) and 1
## state.justification_bits[2] is (state.justification_bits shr 2) and 1
## state.justification_bits[3] is (state.justification_bits shr 3) and 1
## https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/simple-serialize.md#bitvectorn
# Process justifications # Process justifications
state.previous_justified_checkpoint.epoch = state.previous_justified_checkpoint = state.current_justified_checkpoint
state.current_justified_checkpoint.epoch
state.previous_justified_checkpoint.root = ## Spec:
state.current_justified_checkpoint.root ## state.justification_bits[1:] = state.justification_bits[:-1]
state.justification_bits = (state.justification_bits shl 1) ## state.justification_bits[0] = 0b0
let previous_epoch_matching_target_balance = state.justification_bits = state.justification_bits shl 1
get_attesting_balance(state,
get_matching_target_attestations(state, previous_epoch), stateCache) # This is a somewhat expensive approach
if previous_epoch_matching_target_balance * 3 >= let active_validator_indices =
get_total_active_balance(state) * 2: toSet(mapIt(
state.current_justified_checkpoint.epoch = previous_epoch get_active_validator_indices(state, get_current_epoch(state)), it.int))
state.current_justified_checkpoint.root =
get_block_root(state, state.current_justified_checkpoint.epoch) let matching_target_attestations_previous =
get_matching_target_attestations(state, previous_epoch) # Previous epoch
debug "Non-attesting indices in previous epoch: ",
missing_all_validators=
difference(active_validator_indices,
toSet(mapIt(get_attesting_indices(state,
matching_target_attestations_previous, stateCache), it.int))),
missing_unslashed_validators=
difference(active_validator_indices,
toSet(mapIt(get_unslashed_attesting_indices(state,
matching_target_attestations_previous, stateCache), it.int))),
num_active_validators=len(active_validator_indices)
if get_attesting_balance(state, matching_target_attestations_previous,
stateCache) * 3 >= get_total_active_balance(state) * 2:
state.current_justified_checkpoint =
Checkpoint(epoch: previous_epoch,
root: get_block_root(state, previous_epoch))
# Spec: state.justification_bits[1] = 0b1
state.justification_bits = state.justification_bits or (1 shl 1) state.justification_bits = state.justification_bits or (1 shl 1)
let current_epoch_matching_target_balance =
get_attesting_balance(state, let matching_target_attestations_current =
get_matching_target_attestations(state, current_epoch), get_matching_target_attestations(state, current_epoch) # Current epoch
stateCache) if get_attesting_balance(state, matching_target_attestations_current,
if current_epoch_matching_target_balance * 3 >= stateCache) * 3 >= get_total_active_balance(state) * 2:
get_total_active_balance(state) * 2: state.current_justified_checkpoint =
state.current_justified_checkpoint.epoch = current_epoch Checkpoint(epoch: current_epoch,
state.current_justified_checkpoint.root = root: get_block_root(state, current_epoch))
get_block_root(state, state.current_justified_checkpoint.epoch)
# Spec: state.justification_bits[0] = 0b1
state.justification_bits = state.justification_bits or (1 shl 0) state.justification_bits = state.justification_bits or (1 shl 0)
# Process finalizations # Process finalizations
@ -224,35 +254,27 @@ func process_justification_and_finalization(
## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th ## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th
## as source ## as source
if (bitfield shr 1) mod 8 == 0b111 and old_previous_justified_epoch + 3 == if (bitfield shr 1) mod 8 == 0b111 and
current_epoch: old_previous_justified_checkpoint.epoch + 3 == current_epoch:
state.finalized_checkpoint.epoch = old_previous_justified_epoch state.finalized_checkpoint = old_previous_justified_checkpoint
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as ## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as
## source ## source
if (bitfield shr 1) mod 4 == 0b11 and old_previous_justified_epoch + 2 == if (bitfield shr 1) mod 4 == 0b11 and
current_epoch: old_previous_justified_checkpoint.epoch + 2 == current_epoch:
state.finalized_checkpoint.epoch = old_previous_justified_epoch state.finalized_checkpoint = old_previous_justified_checkpoint
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as ## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as
## source ## source
if (bitfield shr 0) mod 8 == 0b111 and old_current_justified_epoch + 2 == if (bitfield shr 0) mod 8 == 0b111 and
current_epoch: old_current_justified_checkpoint.epoch + 2 == current_epoch:
state.finalized_checkpoint.epoch = old_current_justified_epoch state.finalized_checkpoint = old_current_justified_checkpoint
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as ## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as
## source ## source
if (bitfield shr 0) mod 4 == 0b11 and old_current_justified_epoch + 1 == if (bitfield shr 0) mod 4 == 0b11 and
current_epoch: old_current_justified_checkpoint.epoch + 1 == current_epoch:
state.finalized_checkpoint.epoch = old_current_justified_epoch state.finalized_checkpoint = old_current_justified_checkpoint
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#crosslinks # https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#crosslinks
func process_crosslinks(state: var BeaconState, stateCache: var StateCache) = func process_crosslinks(state: var BeaconState, stateCache: var StateCache) =
@ -486,7 +508,7 @@ func process_final_updates(state: var BeaconState) =
state.current_epoch_attestations = @[] state.current_epoch_attestations = @[]
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#per-epoch-processing # https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#per-epoch-processing
func process_epoch*(state: var BeaconState) = proc process_epoch*(state: var BeaconState) =
# @proc are placeholders # @proc are placeholders
var per_epoch_cache = get_empty_per_epoch_cache() var per_epoch_cache = get_empty_per_epoch_cache()

View File

@ -55,7 +55,7 @@ func process_slot(state: var BeaconState) =
signing_root(state.latest_block_header) signing_root(state.latest_block_header)
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function # https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function
func process_slots*(state: var BeaconState, slot: Slot) = proc process_slots*(state: var BeaconState, slot: Slot) =
doAssert state.slot <= slot doAssert state.slot <= slot
# Catch up to the target slot # Catch up to the target slot