reuse validator key cache better (#1562)
new key cache can be used for old epochs in the same tree
This commit is contained in:
parent
ab22bad188
commit
f26d6a4fd3
|
@ -136,6 +136,16 @@ proc init*(
|
|||
|
||||
epochRef
|
||||
|
||||
func updateKeyStores*(epochRef: EpochRef, blck: BlockRef, finalized: BlockRef) =
|
||||
# Because key stores are additive lists, we can use a newer list whereever an
|
||||
# older list is expected - all indices in the new list will be valid for the
|
||||
# old list also
|
||||
var blck = blck
|
||||
while blck != nil and blck.slot >= finalized.slot:
|
||||
for e in blck.epochRefs:
|
||||
e.validator_key_store = epochRef.validator_key_store
|
||||
blck = blck.parent
|
||||
|
||||
func link*(parent, child: BlockRef) =
|
||||
doAssert (not (parent.root == Eth2Digest() or child.root == Eth2Digest())),
|
||||
"blocks missing root!"
|
||||
|
@ -400,6 +410,7 @@ proc getEpochRef*(dag: ChainDAGRef, blck: BlockRef, epoch: Epoch): EpochRef =
|
|||
|
||||
# TODO consider constraining the number of epochrefs per state
|
||||
ancestor.blck.epochRefs.add newEpochRef
|
||||
newEpochRef.updateKeyStores(blck.parent, dag.finalizedHead.blck)
|
||||
newEpochRef
|
||||
|
||||
proc getState(
|
||||
|
|
|
@ -65,7 +65,10 @@ proc addResolvedBlock(
|
|||
let prevEpochRef = blockRef.findEpochRef(blockEpoch - 1)
|
||||
|
||||
epochRef = EpochRef.init(state.data.data, cache, prevEpochRef)
|
||||
blockRef.epochAncestor(blockEpoch).blck.epochRefs.add epochRef
|
||||
let ancestor = blockRef.epochAncestor(blockEpoch)
|
||||
epochRef.updateKeyStores(ancestor.blck.parent, dag.finalizedHead.blck)
|
||||
|
||||
ancestor.blck.epochRefs.add epochRef
|
||||
|
||||
dag.blocks[blockRoot] = blockRef
|
||||
trace "Populating block dag", key = blockRoot, val = blockRef
|
||||
|
|
|
@ -343,15 +343,31 @@ suiteReport "chain DAG finalization tests" & preset():
|
|||
check:
|
||||
dag.heads.len() == 1
|
||||
|
||||
let headER = dag.heads[0].findEpochRef(dag.heads[0].slot.epoch)
|
||||
check:
|
||||
|
||||
# Epochrefs should share validator key set when the validator set is
|
||||
# stable
|
||||
not dag.heads[0].findEpochRef(dag.heads[0].slot.epoch).isNil
|
||||
not headER.isNil
|
||||
not dag.heads[0].findEpochRef(dag.heads[0].slot.epoch - 1).isNil
|
||||
dag.heads[0].findEpochRef(dag.heads[0].slot.epoch) !=
|
||||
headER !=
|
||||
dag.heads[0].findEpochRef(dag.heads[0].slot.epoch - 1)
|
||||
dag.heads[0].findEpochRef(dag.heads[0].slot.epoch).validator_key_store[1] ==
|
||||
headER.validator_key_store[1] ==
|
||||
dag.heads[0].findEpochRef(dag.heads[0].slot.epoch - 1).validator_key_store[1]
|
||||
|
||||
block:
|
||||
var cur = dag.heads[0]
|
||||
while cur != nil:
|
||||
if cur.slot < dag.finalizedHead.blck.slot:
|
||||
# Cache should be cleaned on finalization
|
||||
check: cur.epochRefs.len == 0
|
||||
else:
|
||||
# EpochRef validator keystores should back-propagate to all previous
|
||||
# epochs
|
||||
for e in cur.epochRefs:
|
||||
check (addr headER.validator_keys) == (addr e.validator_keys)
|
||||
cur = cur.parent
|
||||
|
||||
block:
|
||||
# The late block is a block whose parent was finalized long ago and thus
|
||||
# is no longer a viable head candidate
|
||||
|
|
Loading…
Reference in New Issue