Quick fix to prune some states, pending smarter state storage (#1624)

* Quick fix to prune some states, pending smarter state storage

Adverse effects might include slow rewinds - typically the protocol
doesn't ask for pre-finalized states but RPC might

* document issue, add test

* fix cache miss log
This commit is contained in:
Jacek Sieka 2020-09-11 10:03:50 +02:00 committed by GitHub
parent 9db05c484d
commit 8a5a261fcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 13 deletions

View File

@ -68,6 +68,16 @@ func parent*(bs: BlockSlot): BlockSlot =
slot: bs.slot - 1
)
func parentOrSlot*(bs: BlockSlot): BlockSlot =
## Return a blockslot representing the previous slot, using the parent block
## with the current slot if the current had a block
if bs.slot == Slot(0):
BlockSlot(blck: nil, slot: Slot(0))
elif bs.slot == bs.blck.slot:
BlockSlot(blck: bs.blck.parent, slot: bs.slot)
else:
BlockSlot(blck: bs.blck, slot: bs.slot - 1)
func get_effective_balances*(state: BeaconState): seq[Gwei] =
## Get the balances from a state as counted for fork choice
result.newSeq(state.validators.len) # zero-init
@ -620,7 +630,8 @@ proc updateStateData*(
return
warn "UpdateStateData miss", bs, stateBlock = state.blck, stateSlot = state.data.data.slot
debug "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.
# We'll now resort to loading the state from the database then reapplying
@ -768,17 +779,16 @@ proc updateHead*(
if finalizedHead != dag.finalizedHead:
block: # Remove states, walking slot by slot
discard
# TODO this is very aggressive - in theory all our operations start at
# the finalized block so all states before that can be wiped..
# TODO this is disabled for now because the logic for initializing the
# block dag and potentially a few other places depend on certain
# states (like the tail state) being present. It's also problematic
# because it is not clear what happens when tail and finalized states
# happen on an empty slot..
# var cur = finalizedHead
# while cur != dag.finalizedHead:
# cur = cur.parent
# dag.delState(cur)
var cur = finalizedHead
while cur != dag.finalizedHead:
# TODO This is a quick fix to prune some states from the database, but
# not all, pending a smarter storage - the downside of pruning these
# states is that certain rewinds will take longer
# After long periods of non-finalization, it can also take some time to
# release all these states!
if cur.slot.epoch mod 32 != 0 and cur.slot != dag.tail.slot:
dag.delState(cur)
cur = cur.parentOrSlot
block: # Clean up block refs, walking block by block
# Finalization means that we choose a single chain as the canonical one -
@ -805,7 +815,7 @@ proc updateHead*(
if cur.blck.parent.isNil:
break
cur = cur.parent
cur = cur.parentOrSlot
dag.heads.del(n)
block: # Clean up old EpochRef instances

View File

@ -108,7 +108,9 @@ suiteReport "BlockSlot and helpers" & preset():
check:
s00.parent == BlockSlot(blck: nil, slot: Slot(0))
s01.parent == s00
s01.parentOrSlot == s00
s22.parent == s01
s22.parentOrSlot == BlockSlot(blck: s0, slot: Slot(2))
s24.parent == BlockSlot(blck: s2, slot: Slot(3))
s24.parent.parent == s22