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]
# Finality
justification_bits*: uint64 ##\
justification_bits*: uint8 ##\
## 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 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))
)
func get_unslashed_attesting_indices(
func get_attesting_indices(
state: BeaconState, attestations: openarray[PendingAttestation],
stateCache: var StateCache): HashSet[ValidatorIndex] =
result = initSet[ValidatorIndex]()
@ -75,6 +75,10 @@ func get_unslashed_attesting_indices(
result = result.union(get_attesting_indices(
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:
if state.validators[index].slashed:
result.excl index
@ -181,8 +185,8 @@ func get_winning_crosslink_and_attesting_indices(
(winning_crosslink,
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
func process_justification_and_finalization(
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.1/specs/core/0_beacon-chain.md#justification-and-finalization
proc process_justification_and_finalization(
state: var BeaconState, stateCache: var StateCache) =
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
return
@ -190,33 +194,59 @@ func process_justification_and_finalization(
let
previous_epoch = get_previous_epoch(state)
current_epoch = get_current_epoch(state)
old_previous_justified_epoch = state.previous_justified_checkpoint.epoch
old_current_justified_epoch = state.current_justified_checkpoint.epoch
old_previous_justified_checkpoint = state.previous_justified_checkpoint
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
state.previous_justified_checkpoint.epoch =
state.current_justified_checkpoint.epoch
state.previous_justified_checkpoint.root =
state.current_justified_checkpoint.root
state.justification_bits = (state.justification_bits shl 1)
let previous_epoch_matching_target_balance =
get_attesting_balance(state,
get_matching_target_attestations(state, previous_epoch), stateCache)
if previous_epoch_matching_target_balance * 3 >=
get_total_active_balance(state) * 2:
state.current_justified_checkpoint.epoch = previous_epoch
state.current_justified_checkpoint.root =
get_block_root(state, state.current_justified_checkpoint.epoch)
state.previous_justified_checkpoint = state.current_justified_checkpoint
## Spec:
## state.justification_bits[1:] = state.justification_bits[:-1]
## state.justification_bits[0] = 0b0
state.justification_bits = state.justification_bits shl 1
# This is a somewhat expensive approach
let active_validator_indices =
toSet(mapIt(
get_active_validator_indices(state, get_current_epoch(state)), it.int))
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)
let current_epoch_matching_target_balance =
get_attesting_balance(state,
get_matching_target_attestations(state, current_epoch),
stateCache)
if current_epoch_matching_target_balance * 3 >=
get_total_active_balance(state) * 2:
state.current_justified_checkpoint.epoch = current_epoch
state.current_justified_checkpoint.root =
get_block_root(state, state.current_justified_checkpoint.epoch)
let matching_target_attestations_current =
get_matching_target_attestations(state, current_epoch) # Current epoch
if get_attesting_balance(state, matching_target_attestations_current,
stateCache) * 3 >= get_total_active_balance(state) * 2:
state.current_justified_checkpoint =
Checkpoint(epoch: current_epoch,
root: get_block_root(state, current_epoch))
# Spec: state.justification_bits[0] = 0b1
state.justification_bits = state.justification_bits or (1 shl 0)
# 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
## as source
if (bitfield shr 1) mod 8 == 0b111 and old_previous_justified_epoch + 3 ==
current_epoch:
state.finalized_checkpoint.epoch = old_previous_justified_epoch
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
if (bitfield shr 1) mod 8 == 0b111 and
old_previous_justified_checkpoint.epoch + 3 == current_epoch:
state.finalized_checkpoint = old_previous_justified_checkpoint
## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as
## source
if (bitfield shr 1) mod 4 == 0b11 and old_previous_justified_epoch + 2 ==
current_epoch:
state.finalized_checkpoint.epoch = old_previous_justified_epoch
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
if (bitfield shr 1) mod 4 == 0b11 and
old_previous_justified_checkpoint.epoch + 2 == current_epoch:
state.finalized_checkpoint = old_previous_justified_checkpoint
## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as
## source
if (bitfield shr 0) mod 8 == 0b111 and old_current_justified_epoch + 2 ==
current_epoch:
state.finalized_checkpoint.epoch = old_current_justified_epoch
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
if (bitfield shr 0) mod 8 == 0b111 and
old_current_justified_checkpoint.epoch + 2 == current_epoch:
state.finalized_checkpoint = old_current_justified_checkpoint
## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as
## source
if (bitfield shr 0) mod 4 == 0b11 and old_current_justified_epoch + 1 ==
current_epoch:
state.finalized_checkpoint.epoch = old_current_justified_epoch
state.finalized_checkpoint.root =
get_block_root(state, state.finalized_checkpoint.epoch)
if (bitfield shr 0) mod 4 == 0b11 and
old_current_justified_checkpoint.epoch + 1 == current_epoch:
state.finalized_checkpoint = old_current_justified_checkpoint
# 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) =
@ -486,7 +508,7 @@ func process_final_updates(state: var BeaconState) =
state.current_epoch_attestations = @[]
# 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
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)
# 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
# Catch up to the target slot