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 Mamy Ratsimbazafy
parent de238c62b7
commit 04b49cae35
2 changed files with 25 additions and 13 deletions

View File

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

View File

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