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:
parent
d1d5497233
commit
f6fd089ae7
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue