another ~2x speedup in epoch processing
This commit is contained in:
parent
e1ba820486
commit
6f481f8812
|
@ -630,7 +630,9 @@ func get_winning_root_and_participants(
|
||||||
winning_root_balance = root_balance
|
winning_root_balance = root_balance
|
||||||
|
|
||||||
(winning_root,
|
(winning_root,
|
||||||
get_attesting_indices(state, attestations_for.getOrDefault(winning_root)))
|
get_attesting_indices_cached(
|
||||||
|
state,
|
||||||
|
attestations_for.getOrDefault(winning_root), crosslink_committees_cache))
|
||||||
|
|
||||||
# Combination of earliest_attestation and inclusion_slot avoiding O(n^2)
|
# Combination of earliest_attestation and inclusion_slot avoiding O(n^2)
|
||||||
# TODO merge/refactor these two functions, which differ only very slightly.
|
# TODO merge/refactor these two functions, which differ only very slightly.
|
||||||
|
@ -728,7 +730,8 @@ func update_justification_and_finalization(state: var BeaconState) =
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#crosslinks
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/core/0_beacon-chain.md#crosslinks
|
||||||
func process_crosslinks(
|
func process_crosslinks(
|
||||||
state: var BeaconState, crosslink_committee_cache: var auto) =
|
state: var BeaconState, crosslink_committee_cache: var auto,
|
||||||
|
winning_root_participants_cache: var auto) =
|
||||||
let
|
let
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
previous_epoch = current_epoch - 1
|
previous_epoch = current_epoch - 1
|
||||||
|
@ -747,11 +750,20 @@ func process_crosslinks(
|
||||||
state, slot, false, crosslink_committee_cache):
|
state, slot, false, crosslink_committee_cache):
|
||||||
let
|
let
|
||||||
(crosslink_committee, shard) = cas
|
(crosslink_committee, shard) = cas
|
||||||
(winning_root, participants) = get_winning_root_and_participants(
|
# In general, it'll loop over the same shards twice, and
|
||||||
|
# get_winning_root_and_participants is defined to return
|
||||||
|
# the same results from the previous epoch as current.
|
||||||
|
(winning_root, participants) =
|
||||||
|
if shard notin winning_root_participants_cache:
|
||||||
|
get_winning_root_and_participants(
|
||||||
state, shard, crosslink_committee_cache)
|
state, shard, crosslink_committee_cache)
|
||||||
|
else:
|
||||||
|
(ZERO_HASH, winning_root_participants_cache[shard])
|
||||||
participating_balance = get_total_balance(state, participants)
|
participating_balance = get_total_balance(state, participants)
|
||||||
total_balance = get_total_balance(state, crosslink_committee)
|
total_balance = get_total_balance(state, crosslink_committee)
|
||||||
|
|
||||||
|
winning_root_participants_cache[shard] = participants
|
||||||
|
|
||||||
if 3'u64 * participating_balance >= 2'u64 * total_balance:
|
if 3'u64 * participating_balance >= 2'u64 * total_balance:
|
||||||
# Check not from spec; seems kludgy
|
# Check not from spec; seems kludgy
|
||||||
doAssert slot >= GENESIS_SLOT
|
doAssert slot >= GENESIS_SLOT
|
||||||
|
@ -844,7 +856,7 @@ func compute_normal_justification_and_finalization_deltas(state: BeaconState):
|
||||||
else:
|
else:
|
||||||
deltas[1][index] += get_base_reward(state, index)
|
deltas[1][index] += get_base_reward(state, index)
|
||||||
# Expected head
|
# Expected head
|
||||||
if index in get_attesting_indices(state, matching_head_attestations):
|
if index in matching_head_attestation_indices:
|
||||||
deltas[0][index] +=
|
deltas[0][index] +=
|
||||||
get_base_reward(state, index) *
|
get_base_reward(state, index) *
|
||||||
matching_head_balance div total_balance
|
matching_head_balance div total_balance
|
||||||
|
@ -929,7 +941,9 @@ func get_justification_and_finalization_deltas(state: BeaconState):
|
||||||
compute_inactivity_leak_deltas(state)
|
compute_inactivity_leak_deltas(state)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#crosslinks-1
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#crosslinks-1
|
||||||
func get_crosslink_deltas(state: BeaconState, crosslink_committees_cache: var auto):
|
func get_crosslink_deltas(
|
||||||
|
state: BeaconState, crosslink_committees_cache: var auto,
|
||||||
|
winning_root_participants_cache: var auto):
|
||||||
tuple[a: seq[Gwei], b: seq[Gwei]] =
|
tuple[a: seq[Gwei], b: seq[Gwei]] =
|
||||||
# deltas[0] for rewards
|
# deltas[0] for rewards
|
||||||
# deltas[1] for penalties
|
# deltas[1] for penalties
|
||||||
|
@ -949,11 +963,11 @@ func get_crosslink_deltas(state: BeaconState, crosslink_committees_cache: var au
|
||||||
(crosslink_committee, shard) = cas
|
(crosslink_committee, shard) = cas
|
||||||
(winning_root, participants) = get_winning_root_and_participants(
|
(winning_root, participants) = get_winning_root_and_participants(
|
||||||
state, shard, crosslink_committees_cache)
|
state, shard, crosslink_committees_cache)
|
||||||
|
nonquadraticParticipants = toSet(participants)
|
||||||
participating_balance = get_total_balance(state, participants)
|
participating_balance = get_total_balance(state, participants)
|
||||||
total_balance = get_total_balance(state, crosslink_committee)
|
total_balance = get_total_balance(state, crosslink_committee)
|
||||||
# In principle quadratic, but should be small.
|
|
||||||
for index in crosslink_committee:
|
for index in crosslink_committee:
|
||||||
if index in participants:
|
if index in nonquadraticParticipants:
|
||||||
deltas[0][index] +=
|
deltas[0][index] +=
|
||||||
get_base_reward(state, index) * participating_balance div
|
get_base_reward(state, index) * participating_balance div
|
||||||
total_balance
|
total_balance
|
||||||
|
@ -964,10 +978,12 @@ func get_crosslink_deltas(state: BeaconState, crosslink_committees_cache: var au
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#apply-rewards
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#apply-rewards
|
||||||
func apply_rewards(
|
func apply_rewards(
|
||||||
state: var BeaconState, crosslink_committees_cache: var auto) =
|
state: var BeaconState, crosslink_committees_cache: var auto,
|
||||||
|
winning_root_participants_cache: var auto) =
|
||||||
let
|
let
|
||||||
deltas1 = get_justification_and_finalization_deltas(state)
|
deltas1 = get_justification_and_finalization_deltas(state)
|
||||||
deltas2 = get_crosslink_deltas(state, crosslink_committees_cache)
|
deltas2 = get_crosslink_deltas(
|
||||||
|
state, crosslink_committees_cache, winning_root_participants_cache)
|
||||||
for i in 0 ..< len(state.validator_registry):
|
for i in 0 ..< len(state.validator_registry):
|
||||||
state.validator_balances[i] =
|
state.validator_balances[i] =
|
||||||
max(
|
max(
|
||||||
|
@ -1081,16 +1097,21 @@ func processEpoch(state: var BeaconState) =
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#justification
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#justification
|
||||||
update_justification_and_finalization(state)
|
update_justification_and_finalization(state)
|
||||||
|
|
||||||
var crosslink_committee_cache =
|
var
|
||||||
|
crosslink_committee_cache =
|
||||||
initTable[tuple[a: uint64, b: bool], seq[CrosslinkCommittee]]()
|
initTable[tuple[a: uint64, b: bool], seq[CrosslinkCommittee]]()
|
||||||
|
winning_root_participants_cache =
|
||||||
|
initTable[Shard, seq[ValidatorIndex]]()
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#crosslinks
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#crosslinks
|
||||||
process_crosslinks(state, crosslink_committee_cache)
|
process_crosslinks(
|
||||||
|
state, crosslink_committee_cache, winning_root_participants_cache)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#eth1-data
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#eth1-data
|
||||||
maybe_reset_eth1_period(state)
|
maybe_reset_eth1_period(state)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#apply-rewards
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#apply-rewards
|
||||||
apply_rewards(state, crosslink_committee_cache)
|
apply_rewards(
|
||||||
|
state, crosslink_committee_cache, winning_root_participants_cache)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#ejections
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#ejections
|
||||||
process_ejections(state)
|
process_ejections(state)
|
||||||
|
|
Loading…
Reference in New Issue