better state cache reuse (#1612)
This commit is contained in:
parent
1f9cd8ce2b
commit
7e3f20236f
|
@ -560,12 +560,12 @@ proc get*(dag: ChainDAGRef, root: Eth2Digest): Option[BlockData] =
|
||||||
none(BlockData)
|
none(BlockData)
|
||||||
|
|
||||||
proc advanceSlots(
|
proc advanceSlots(
|
||||||
dag: ChainDAGRef, state: var StateData, slot: Slot, save: bool) =
|
dag: ChainDAGRef, state: var StateData, slot: Slot, cache: var StateCache,
|
||||||
|
save: bool) =
|
||||||
# Given a state, advance it zero or more slots by applying empty slot
|
# Given a state, advance it zero or more slots by applying empty slot
|
||||||
# processing
|
# processing
|
||||||
doAssert state.data.data.slot <= slot
|
doAssert state.data.data.slot <= slot
|
||||||
|
|
||||||
var cache = getStateCache(state.blck, state.data.data.slot.epoch)
|
|
||||||
while state.data.data.slot < slot:
|
while state.data.data.slot < slot:
|
||||||
# Process slots one at a time in case afterUpdate needs to see empty states
|
# Process slots one at a time in case afterUpdate needs to see empty states
|
||||||
advance_slot(state.data, dag.updateFlags, cache)
|
advance_slot(state.data, dag.updateFlags, cache)
|
||||||
|
@ -575,7 +575,8 @@ proc advanceSlots(
|
||||||
|
|
||||||
proc applyBlock(
|
proc applyBlock(
|
||||||
dag: ChainDAGRef,
|
dag: ChainDAGRef,
|
||||||
state: var StateData, blck: BlockData, flags: UpdateFlags, save: bool): bool =
|
state: var StateData, blck: BlockData, flags: UpdateFlags,
|
||||||
|
cache: var StateCache, save: bool): bool =
|
||||||
# Apply a single block to the state - the state must be positioned at the
|
# Apply a single block to the state - the state must be positioned at the
|
||||||
# parent of the block with a slot lower than the one of the block being
|
# parent of the block with a slot lower than the one of the block being
|
||||||
# applied
|
# applied
|
||||||
|
@ -583,14 +584,13 @@ proc applyBlock(
|
||||||
|
|
||||||
# `state_transition` can handle empty slots, but we want to potentially save
|
# `state_transition` can handle empty slots, but we want to potentially save
|
||||||
# some of the empty slot states
|
# some of the empty slot states
|
||||||
dag.advanceSlots(state, blck.data.message.slot, save)
|
dag.advanceSlots(state, blck.data.message.slot, cache, save)
|
||||||
|
|
||||||
var statePtr = unsafeAddr state # safe because `restore` is locally scoped
|
var statePtr = unsafeAddr state # safe because `restore` is locally scoped
|
||||||
func restore(v: var HashedBeaconState) =
|
func restore(v: var HashedBeaconState) =
|
||||||
doAssert (addr(statePtr.data) == addr v)
|
doAssert (addr(statePtr.data) == addr v)
|
||||||
statePtr[] = dag.headState
|
statePtr[] = dag.headState
|
||||||
|
|
||||||
var cache = getStateCache(state.blck, state.data.data.slot.epoch)
|
|
||||||
let ok = state_transition(
|
let ok = state_transition(
|
||||||
dag.runtimePreset, state.data, blck.data,
|
dag.runtimePreset, state.data, blck.data,
|
||||||
cache, flags + dag.updateFlags + {slotProcessed}, restore)
|
cache, flags + dag.updateFlags + {slotProcessed}, restore)
|
||||||
|
@ -616,10 +616,12 @@ proc updateStateData*(
|
||||||
if state.blck == bs.blck and state.data.data.slot <= bs.slot:
|
if state.blck == bs.blck and state.data.data.slot <= bs.slot:
|
||||||
# The block is the same and we're at an early enough slot - advance the
|
# The block is the same and we're at an early enough slot - advance the
|
||||||
# state with empty slot processing until the slot is correct
|
# state with empty slot processing until the slot is correct
|
||||||
dag.advanceSlots(state, bs.slot, true)
|
dag.advanceSlots(state, bs.slot, cache, true)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
warn "UpdateStateData miss", bs, stateBlock = state.blck, stateSlot = state.data.data.slot
|
||||||
|
|
||||||
# Either the state is too new or was created by applying a different block.
|
# Either the state is too new or was created by applying a different block.
|
||||||
# We'll now resort to loading the state from the database then reapplying
|
# We'll now resort to loading the state from the database then reapplying
|
||||||
# blocks until we reach the desired point in time.
|
# blocks until we reach the desired point in time.
|
||||||
|
@ -658,12 +660,12 @@ proc updateStateData*(
|
||||||
# database, we can skip certain checks that have already been performed
|
# database, we can skip certain checks that have already been performed
|
||||||
# before adding the block to the database.
|
# before adding the block to the database.
|
||||||
let ok =
|
let ok =
|
||||||
dag.applyBlock(state, dag.get(ancestors[i]), {}, false)
|
dag.applyBlock(state, dag.get(ancestors[i]), {}, cache, false)
|
||||||
doAssert ok, "Blocks in database should never fail to apply.."
|
doAssert ok, "Blocks in database should never fail to apply.."
|
||||||
|
|
||||||
# We save states here - blocks were guaranteed to have passed through the save
|
# We save states here - blocks were guaranteed to have passed through the save
|
||||||
# function once at least, but not so for empty slots!
|
# function once at least, but not so for empty slots!
|
||||||
dag.advanceSlots(state, bs.slot, true)
|
dag.advanceSlots(state, bs.slot, cache, true)
|
||||||
|
|
||||||
beacon_state_rewinds.inc()
|
beacon_state_rewinds.inc()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue