nimbus-eth1/nimbus/sync/sync_desc.nim
Jordan Hrycaj 430611d3bc
Beacon sync updates tbc (#2818)
* Clear rejected sync target so that it would not be processed again

* Use in-memory table to stash headers after FCU import has started

why:
  After block imported has started, there is no way to save/stash block
  headers persistently. The FCU handlers always maintain a positive
  transaction level and in some instances the current transaction is
  flushed and re-opened.

  This patch fixes an exception thrown when a block header has gone
  missing.

* When resuming sync, delete stale headers and state

why:
  Deleting headers saves some persistent space that would get lost
  otherwise. Deleting the state after resuming prevents from race
  conditions.

* On clean start hibernate sync `deamon` entity before first update from CL

details:
  Only reduces services are running
  * accept FCU from CL
  * fetch finalised header after accepting FCY (provides hash only)

* Improve text/meaning of some log messages

* Revisit error handling for useless peers

why:
  A peer is abandoned from if the error score is too high. This was not
  properly handled for some fringe case when the error was detected at
  staging time but fetching via eth/xx was ok.

* Clarify `break` meaning by using labelled `break` statements

* Fix action how to commit when sync target has been reached

why:
  The sync target block number might precede than latest FCU block number.
  This happens when the engine API squeezes in some request to execute
  and import subsequent blocks.

  This patch fixes and assert thrown when after reaching target the latest
  FCU block number is higher than the expected target block number.

* Update TODO list
2024-11-01 19:18:41 +00:00

122 lines
3.9 KiB
Nim

# Nimbus
# Copyright (c) 2021-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed
# except according to those terms.
## Worker peers scheduler template
## ===============================
##
## Public descriptors
{.push raises: [].}
import
eth/p2p
type
BuddyRunState* = enum
Running = 0 ## Running, default state
Stopped ## Stopped or about stopping
ZombieStop ## Abandon/ignore (wait for pushed out of LRU table)
ZombieRun ## Extra zombie state to potentially recover from
BuddyCtrlRef* = ref object
## Control and state settings
runState: BuddyRunState ## Access with getters
BuddyRef*[S,W] = ref object
## Worker peer state descriptor.
ctx*: CtxRef[S] ## Shared data descriptor back reference
peer*: Peer ## Reference to eth p2pProtocol entry
ctrl*: BuddyCtrlRef ## Control and state settings
only*: W ## Worker peer specific data
CtxRef*[S] = ref object
## Shared state among all syncing peer workers (aka buddies.)
noisyLog*: bool ## Hold back `trace` and `debug` msgs if `false`
poolMode*: bool ## Activate `runPool()` workers if set `true`
daemon*: bool ## Enable global background job
pool*: S ## Shared context for all worker peers
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
proc `$`*[S,W](worker: BuddyRef[S,W]): string =
$worker.peer & "$" & $worker.ctrl.runState
# ------------------------------------------------------------------------------
# Public getters, `BuddyRunState` execution control functions
# ------------------------------------------------------------------------------
proc state*(ctrl: BuddyCtrlRef): BuddyRunState =
## Getter (logging only, details of `BuddyCtrl` are private)
ctrl.runState
proc running*(ctrl: BuddyCtrlRef): bool =
## Getter, if `true` if `ctrl.state()` is `Running`
ctrl.runState == Running
proc stopped*(ctrl: BuddyCtrlRef): bool =
## Getter, if `true`, if `ctrl.state()` is not `Running`
ctrl.runState != Running
proc zombie*(ctrl: BuddyCtrlRef): bool =
## Getter, `true` if `ctrl.state()` is `Zombie` (i.e. not `running()` and
## not `stopped()`)
ctrl.runState in {ZombieStop, ZombieRun}
# ------------------------------------------------------------------------------
# Public setters, `BuddyRunState` execution control functions
# ------------------------------------------------------------------------------
proc `zombie=`*(ctrl: BuddyCtrlRef; value: bool) =
## Setter
if value:
case ctrl.runState:
of Running:
ctrl.runState = ZombieRun
of Stopped:
ctrl.runState = ZombieStop
else:
discard
else:
case ctrl.runState:
of ZombieRun:
ctrl.runState = Running
of ZombieStop:
ctrl.runState = Stopped
else:
discard
proc `stopped=`*(ctrl: BuddyCtrlRef; value: bool) =
## Setter
if value:
case ctrl.runState:
of Running:
ctrl.runState = Stopped
else:
discard
else:
case ctrl.runState:
of Stopped:
ctrl.runState = Running
else:
discard
proc `forceRun=`*(ctrl: BuddyCtrlRef; value: bool) =
## Setter, gets out of `Zombie` jail/locked state with `true argument.
if value:
ctrl.runState = Running
else:
ctrl.stopped = true
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------