limit fork choice initialization horizon (#1910)
This helps manage the long startup time on chains that are not finalizing for long periods of time
This commit is contained in:
parent
020a32ffa4
commit
81f4fe0783
|
@ -41,22 +41,46 @@ proc init*(T: type AttestationPool, chainDag: ChainDAGRef, quarantine: Quarantin
|
|||
|
||||
var blocks: seq[BlockRef]
|
||||
var cur = chainDag.head
|
||||
|
||||
# When the chain is finalizing, the votes between the head block and the
|
||||
# finalized checkpoint should be enough for a stable fork choice - when the
|
||||
# chain is not finalizing, we want to seed it with as many votes as possible
|
||||
# since the whole history of each branch might be significant. It is however
|
||||
# a game of diminishing returns, and we have to weigh it against the time
|
||||
# it takes to replay that many blocks during startup and thus miss _new_
|
||||
# votes.
|
||||
const ForkChoiceHorizon = 256
|
||||
while cur != chainDag.finalizedHead.blck:
|
||||
blocks.add cur
|
||||
cur = cur.parent
|
||||
|
||||
debug "Preloading fork choice with blocks", blocks = blocks.len
|
||||
info "Initializing fork choice from block database",
|
||||
unfinalized_blocks = blocks.len
|
||||
|
||||
for blck in reversed(blocks):
|
||||
var epochRef = finalizedEpochRef
|
||||
for i in 0..<blocks.len:
|
||||
let
|
||||
epochRef = chainDag.getEpochRef(blck, blck.slot.compute_epoch_at_slot)
|
||||
blck = blocks[blocks.len - i - 1]
|
||||
status =
|
||||
if i > (blocks.len - ForkChoiceHorizon) or (i mod 1024 != 0):
|
||||
# Fork choice needs to know about the full block tree up to the
|
||||
# finalization point, but doesn't really need to have overly accurate
|
||||
# justification and finalization points until we get close to head -
|
||||
# nonetheless, we'll make sure to pass a fresh finalization point now
|
||||
# and then to make sure the fork choice data structure doesn't grow
|
||||
# too big - getting an EpochRef can be expensive.
|
||||
forkChoice.backend.process_block(
|
||||
blck.root, blck.parent.root,
|
||||
epochRef.current_justified_checkpoint.epoch,
|
||||
epochRef.finalized_checkpoint.epoch)
|
||||
else:
|
||||
epochRef = chainDag.getEpochRef(blck, blck.slot.epoch)
|
||||
forkChoice.process_block(
|
||||
chainDag, epochRef, blck, chainDag.get(blck).data.message, blck.slot)
|
||||
|
||||
doAssert status.isOk(), "Error in preloading the fork choice: " & $status.error
|
||||
|
||||
debug "Fork choice initialized",
|
||||
info "Fork choice initialized",
|
||||
justified_epoch = chainDag.headState.data.data.current_justified_checkpoint.epoch,
|
||||
finalized_epoch = chainDag.headState.data.data.finalized_checkpoint.epoch,
|
||||
finalized_root = shortlog(chainDag.finalizedHead.blck.root)
|
||||
|
|
|
@ -35,6 +35,15 @@ proc parseBootstrapAddress*(address: TaintedString):
|
|||
else:
|
||||
return err "Ignoring unrecognized bootstrap address type"
|
||||
|
||||
iterator strippedLines(filename: string): string {.raises: [ref IOError].} =
|
||||
for line in lines(filename):
|
||||
let stripped = strip(line)
|
||||
if stripped.startsWith('#'): # Comments
|
||||
continue
|
||||
|
||||
if stripped.len > 0:
|
||||
yield stripped
|
||||
|
||||
proc addBootstrapNode*(bootstrapAddr: string,
|
||||
bootstrapEnrs: var seq[enr.Record]) =
|
||||
# Ignore empty lines or lines starting with #
|
||||
|
@ -54,7 +63,7 @@ proc loadBootstrapFile*(bootstrapFile: string,
|
|||
let ext = splitFile(bootstrapFile).ext
|
||||
if cmpIgnoreCase(ext, ".txt") == 0 or cmpIgnoreCase(ext, ".enr") == 0 :
|
||||
try:
|
||||
for ln in lines(bootstrapFile):
|
||||
for ln in strippedLines(bootstrapFile):
|
||||
addBootstrapNode(ln, bootstrapEnrs)
|
||||
except IOError as e:
|
||||
error "Could not read bootstrap file", msg = e.msg
|
||||
|
@ -64,7 +73,7 @@ proc loadBootstrapFile*(bootstrapFile: string,
|
|||
# TODO. This is very ugly, but let's try to negotiate the
|
||||
# removal of YAML metadata.
|
||||
try:
|
||||
for ln in lines(bootstrapFile):
|
||||
for ln in strippedLines(bootstrapFile):
|
||||
addBootstrapNode(string(ln.strip()[3..^2]), bootstrapEnrs)
|
||||
except IOError as e:
|
||||
error "Could not read bootstrap file", msg = e.msg
|
||||
|
|
Loading…
Reference in New Issue