small perf fixes
* don't sort shuffled_validator_indices, just get them directly with iteration * grab full epoch of proposer indices while we have the data available - they'll get cached and reused * avoid computing active validator set when not used for logging
This commit is contained in:
parent
2c19e3f8cd
commit
7de05efaaf
|
@ -658,7 +658,8 @@ proc updateStateData*(
|
|||
slots = state.data.data.slot - startSlot,
|
||||
stateRoot = shortLog(state.data.root),
|
||||
stateSlot = state.data.data.slot,
|
||||
stateRoot = shortLog(startRoot),
|
||||
startRoot = shortLog(startRoot),
|
||||
startSlot,
|
||||
blck = shortLog(bs)
|
||||
|
||||
proc loadTailState*(dag: ChainDAGRef): StateData =
|
||||
|
|
|
@ -101,7 +101,7 @@ func get_attesting_balance(
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/beacon-chain.md#justification-and-finalization
|
||||
proc process_justification_and_finalization*(state: var BeaconState,
|
||||
stateCache: var StateCache, updateFlags: UpdateFlags = {}) {.nbench.} =
|
||||
cache: var StateCache, updateFlags: UpdateFlags = {}) {.nbench.} =
|
||||
|
||||
logScope: pcs = "process_justification_and_finalization"
|
||||
|
||||
|
@ -126,20 +126,19 @@ proc process_justification_and_finalization*(state: var BeaconState,
|
|||
state.justification_bits = (state.justification_bits shl 1) and
|
||||
cast[uint8]((2^JUSTIFICATION_BITS_LENGTH) - 1)
|
||||
|
||||
# This is a somewhat expensive approach
|
||||
let active_validator_indices {.used.} =
|
||||
toHashSet(mapIt(
|
||||
get_active_validator_indices(state, get_current_epoch(state)), it.uint32))
|
||||
|
||||
let matching_target_attestations_previous =
|
||||
get_matching_target_attestations(state, previous_epoch) # Previous epoch
|
||||
|
||||
if verifyFinalization in updateFlags:
|
||||
let active_validator_indices =
|
||||
toHashSet(cache.get_shuffled_active_validator_indices(
|
||||
state, get_current_epoch(state)))
|
||||
|
||||
# Non-attesting indices in previous epoch
|
||||
let missing_all_validators =
|
||||
difference(active_validator_indices,
|
||||
toHashSet(mapIt(get_attesting_indices(state,
|
||||
matching_target_attestations_previous, stateCache), it.uint32)))
|
||||
get_attesting_indices(
|
||||
state, matching_target_attestations_previous, cache))
|
||||
|
||||
# testnet0 and testnet1 have 8 non-attesting validators each, by default
|
||||
if missing_all_validators.len > 15:
|
||||
|
@ -157,42 +156,48 @@ proc process_justification_and_finalization*(state: var BeaconState,
|
|||
# and
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/beacon-chain.md#final-updates
|
||||
# after which the state.previous_epoch_attestations is replaced.
|
||||
let total_active_balance = get_total_active_balance(state, stateCache)
|
||||
trace "Non-attesting indices in previous epoch",
|
||||
missing_all_validators=
|
||||
difference(active_validator_indices,
|
||||
toHashSet(mapIt(get_attesting_indices(state,
|
||||
matching_target_attestations_previous, stateCache), it.uint32))),
|
||||
missing_unslashed_validators=
|
||||
difference(active_validator_indices,
|
||||
toHashSet(mapIt(get_unslashed_attesting_indices(state,
|
||||
matching_target_attestations_previous, stateCache), it.uint32))),
|
||||
prev_attestations_len=len(state.previous_epoch_attestations),
|
||||
cur_attestations_len=len(state.current_epoch_attestations),
|
||||
num_active_validators=len(active_validator_indices),
|
||||
required_balance = total_active_balance * 2,
|
||||
attesting_balance_prev = get_attesting_balance(state, matching_target_attestations_previous, stateCache)
|
||||
let total_active_balance = get_total_active_balance(state, cache)
|
||||
when chronicles.enabledLogLevel == LogLevel.TRACE:
|
||||
let active_validator_indices =
|
||||
toHashSet(cache.get_shuffled_active_validator_indices(
|
||||
state, get_current_epoch(state)))
|
||||
|
||||
trace "Non-attesting indices in previous epoch",
|
||||
missing_all_validators =
|
||||
difference(active_validator_indices, get_attesting_indices(
|
||||
state, matching_target_attestations_previous, cache)),
|
||||
missing_unslashed_validators =
|
||||
difference(active_validator_indices,
|
||||
get_unslashed_attesting_indices(
|
||||
state, matching_target_attestations_previous, cache)),
|
||||
prev_attestations_len = len(state.previous_epoch_attestations),
|
||||
cur_attestations_len = len(state.current_epoch_attestations),
|
||||
num_active_validators = len(active_validator_indices),
|
||||
total_active_balance,
|
||||
attesting_balance_prev = get_attesting_balance(
|
||||
state, matching_target_attestations_previous, cache)
|
||||
|
||||
if get_attesting_balance(state, matching_target_attestations_previous,
|
||||
stateCache) * 3 >= total_active_balance * 2:
|
||||
cache) * 3 >= total_active_balance * 2:
|
||||
state.current_justified_checkpoint =
|
||||
Checkpoint(epoch: previous_epoch,
|
||||
root: get_block_root(state, previous_epoch))
|
||||
state.justification_bits.setBit 1
|
||||
|
||||
debug "Justified with previous epoch",
|
||||
trace "Justified with previous epoch",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.current_justified_checkpoint)
|
||||
|
||||
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 >= total_active_balance * 2:
|
||||
cache) * 3 >= total_active_balance * 2:
|
||||
state.current_justified_checkpoint =
|
||||
Checkpoint(epoch: current_epoch,
|
||||
root: get_block_root(state, current_epoch))
|
||||
state.justification_bits.setBit 0
|
||||
|
||||
debug "Justified with current epoch",
|
||||
trace "Justified with current epoch",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.current_justified_checkpoint)
|
||||
|
||||
|
@ -205,7 +210,7 @@ proc process_justification_and_finalization*(state: var BeaconState,
|
|||
old_previous_justified_checkpoint.epoch + 3 == current_epoch:
|
||||
state.finalized_checkpoint = old_previous_justified_checkpoint
|
||||
|
||||
debug "Finalized with rule 234",
|
||||
trace "Finalized with rule 234",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.finalized_checkpoint)
|
||||
|
||||
|
@ -215,7 +220,7 @@ proc process_justification_and_finalization*(state: var BeaconState,
|
|||
old_previous_justified_checkpoint.epoch + 2 == current_epoch:
|
||||
state.finalized_checkpoint = old_previous_justified_checkpoint
|
||||
|
||||
debug "Finalized with rule 23",
|
||||
trace "Finalized with rule 23",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.finalized_checkpoint)
|
||||
|
||||
|
@ -225,7 +230,7 @@ proc process_justification_and_finalization*(state: var BeaconState,
|
|||
old_current_justified_checkpoint.epoch + 2 == current_epoch:
|
||||
state.finalized_checkpoint = old_current_justified_checkpoint
|
||||
|
||||
debug "Finalized with rule 123",
|
||||
trace "Finalized with rule 123",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.finalized_checkpoint)
|
||||
|
||||
|
@ -235,7 +240,7 @@ proc process_justification_and_finalization*(state: var BeaconState,
|
|||
old_current_justified_checkpoint.epoch + 1 == current_epoch:
|
||||
state.finalized_checkpoint = old_current_justified_checkpoint
|
||||
|
||||
debug "Finalized with rule 12",
|
||||
trace "Finalized with rule 12",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.finalized_checkpoint)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
algorithm, options, sequtils, math, tables,
|
||||
options, sequtils, math, tables,
|
||||
./datatypes, ./digest, ./helpers
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/beacon-chain.md#compute_shuffled_index
|
||||
|
@ -296,17 +296,25 @@ func get_beacon_proposer_index*(state: BeaconState, cache: var StateCache, slot:
|
|||
|
||||
var buffer: array[32 + 8, byte]
|
||||
buffer[0..31] = get_seed(state, epoch, DOMAIN_BEACON_PROPOSER).data
|
||||
buffer[32..39] = uint_to_bytes8(slot.uint64)
|
||||
|
||||
# There's exactly one beacon proposer per slot.
|
||||
|
||||
let
|
||||
seed = eth2digest(buffer)
|
||||
indices =
|
||||
sorted(cache.get_shuffled_active_validator_indices(state, epoch), system.cmp)
|
||||
# active validator indices are kept in cache but sorting them takes
|
||||
# quite a while
|
||||
indices = get_active_validator_indices(state, epoch)
|
||||
start = slot.epoch().compute_start_slot_at_epoch()
|
||||
|
||||
return cache.beacon_proposer_indices.mgetOrPut(
|
||||
slot, compute_proposer_index(state, indices, seed))
|
||||
var res: Option[ValidatorIndex]
|
||||
for i in 0..<SLOTS_PER_EPOCH:
|
||||
buffer[32..39] = uint_to_bytes8((start + i).uint64)
|
||||
let seed = eth2digest(buffer)
|
||||
let pi = compute_proposer_index(state, indices, seed)
|
||||
if start + i == slot:
|
||||
res = pi
|
||||
cache.beacon_proposer_indices[start + i] = pi
|
||||
|
||||
return res
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/beacon-chain.md#get_beacon_proposer_index
|
||||
func get_beacon_proposer_index*(state: BeaconState, cache: var StateCache):
|
||||
|
|
Loading…
Reference in New Issue