mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-06 09:13:46 +00:00
* Somewhat tighten error handling why: Zombie state is invoked when the current peer turns out to be useless for further communication. While there is a chance to further talk to a peer about another topic (aka healing) after some protocol failure, it makes no sense to do so after a network problem. The latter state is explained bu the `peerDegraded` flag that goes together with the `zombie` state flag. A degraded peer is dropped immediately. * Remove `--sync-mode=snapCtx` option, always start snap in recovery mode why: No need for a snap sync option without recovery mode, can be achieved by deleting the database. * Code cosmetics, typos, prettify logging, debugging helper, etc. * Split off snap sync sub-mode handler into separate modules details: The original `worker.nim` source has become a multiplexer for several snap sync sub-modes `full` and `snap`. The source modules of the incarnations of a particular sync sub-mode are places into the `worker/play` directory. * Update ticker for snap and full sync logging
173 lines
5.6 KiB
Nim
173 lines
5.6 KiB
Nim
# Nimbus
|
|
# Copyright (c) 2021 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.
|
|
|
|
{.push raises: [].}
|
|
|
|
import
|
|
chronicles,
|
|
chronos,
|
|
eth/p2p,
|
|
stew/[interval_set, keyed_queue],
|
|
"../.."/[common, db/select_backend],
|
|
".."/[handlers/eth, protocol, sync_desc],
|
|
./worker/[pivot, play, ticker],
|
|
./worker/com/com_error,
|
|
./worker/db/[snapdb_desc, snapdb_pivot],
|
|
"."/[range_desc, worker_desc]
|
|
|
|
logScope:
|
|
topics = "snap-worker"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Private helpers
|
|
# ------------------------------------------------------------------------------
|
|
|
|
template ignoreException(info: static[string]; code: untyped) =
|
|
try:
|
|
code
|
|
except CatchableError as e:
|
|
error "Exception at " & info & ":", name=($e.name), msg=(e.msg)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Private functions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc disableWireServices(ctx: SnapCtxRef) =
|
|
## Helper for `setup()`: Temporarily stop useless wire protocol services.
|
|
ctx.ethWireCtx.txPoolEnabled = false
|
|
|
|
proc enableWireServices(ctx: SnapCtxRef) =
|
|
## Helper for `release()`
|
|
ctx.ethWireCtx.txPoolEnabled = true
|
|
|
|
# --------------
|
|
|
|
proc enableTicker(ctx: SnapCtxRef; tickerOK: bool) =
|
|
## Helper for `setup()`: Log/status ticker
|
|
if tickerOK:
|
|
ctx.pool.ticker = TickerRef.init(ctx.pool.pivotTable.tickerStats(ctx))
|
|
else:
|
|
trace "Ticker is disabled"
|
|
|
|
proc disableTicker(ctx: SnapCtxRef) =
|
|
## Helper for `release()`
|
|
if not ctx.pool.ticker.isNil:
|
|
ctx.pool.ticker.stop()
|
|
ctx.pool.ticker = nil
|
|
|
|
# --------------
|
|
|
|
proc enableRpcMagic(ctx: SnapCtxRef) =
|
|
## Helper for `setup()`: Enable external pivot update via RPC
|
|
ctx.chain.com.syncReqNewHead = ctx.pivotUpdateBeaconHeaderCB
|
|
|
|
proc disableRpcMagic(ctx: SnapCtxRef) =
|
|
## Helper for `release()`
|
|
ctx.chain.com.syncReqNewHead = nil
|
|
|
|
# --------------
|
|
|
|
proc detectSnapSyncRecovery(ctx: SnapCtxRef) =
|
|
## Helper for `setup()`: Initiate snap sync recovery (if any)
|
|
let rc = ctx.pool.snapDb.pivotRecoverDB()
|
|
if rc.isOk:
|
|
ctx.pool.recovery = SnapRecoveryRef(state: rc.value)
|
|
ctx.daemon = true
|
|
|
|
# Set up early initial pivot
|
|
ctx.pool.pivotTable.reverseUpdate(ctx.pool.recovery.state.header, ctx)
|
|
trace "Snap sync recovery started",
|
|
checkpoint=("#" & $ctx.pool.pivotTable.topNumber() & "(0)")
|
|
if not ctx.pool.ticker.isNil:
|
|
ctx.pool.ticker.startRecovery()
|
|
|
|
proc initSnapDb(ctx: SnapCtxRef) =
|
|
## Helper for `setup()`: Initialise snap sync database layer
|
|
ctx.pool.snapDb =
|
|
if ctx.pool.dbBackend.isNil: SnapDbRef.init(ctx.chain.db.db)
|
|
else: SnapDbRef.init(ctx.pool.dbBackend)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Public start/stop and admin functions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc setup*(ctx: SnapCtxRef; tickerOK: bool): bool =
|
|
## Global set up
|
|
|
|
# For snap sync book keeping
|
|
ctx.pool.coveredAccounts = NodeTagRangeSet.init()
|
|
|
|
ctx.enableRpcMagic() # Allow external pivot update via RPC
|
|
ctx.disableWireServices() # Stop unwanted public services
|
|
ctx.pool.syncMode.playInit() # Set up sync sub-mode specs.
|
|
ctx.initSnapDb() # Set database backend, subject to change
|
|
ctx.detectSnapSyncRecovery() # Check for recovery mode
|
|
ctx.enableTicker(tickerOK) # Start log/status ticker (if any)
|
|
|
|
# Experimental, also used for debugging
|
|
if ctx.exCtrlFile.isSome:
|
|
warn "Snap sync accepts pivot block number or hash",
|
|
syncCtrlFile=ctx.exCtrlFile.get
|
|
true
|
|
|
|
proc release*(ctx: SnapCtxRef) =
|
|
## Global clean up
|
|
ctx.disableTicker() # Stop log/status ticker (if any)
|
|
ctx.enableWireServices() # re-enable public services
|
|
ctx.disableRpcMagic() # Disable external pivot update via RPC
|
|
|
|
|
|
proc start*(buddy: SnapBuddyRef): bool =
|
|
## Initialise worker peer
|
|
let
|
|
ctx = buddy.ctx
|
|
peer = buddy.peer
|
|
if peer.supports(protocol.snap) and
|
|
peer.supports(protocol.eth) and
|
|
peer.state(protocol.eth).initialized:
|
|
buddy.only.errors = ComErrorStatsRef()
|
|
if not ctx.pool.ticker.isNil:
|
|
ctx.pool.ticker.startBuddy()
|
|
return true
|
|
|
|
proc stop*(buddy: SnapBuddyRef) =
|
|
## Clean up this peer
|
|
let ctx = buddy.ctx
|
|
if not ctx.pool.ticker.isNil:
|
|
ctx.pool.ticker.stopBuddy()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Public functions, sync handler multiplexers
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc runDaemon*(ctx: SnapCtxRef) {.async.} =
|
|
## Sync processsing multiplexer
|
|
ignoreException("runDaemon"):
|
|
await ctx.playSyncSpecs.daemon(ctx)
|
|
|
|
proc runSingle*(buddy: SnapBuddyRef) {.async.} =
|
|
## Sync processsing multiplexer
|
|
ignoreException("runSingle"):
|
|
await buddy.ctx.playSyncSpecs.single(buddy)
|
|
|
|
proc runPool*(buddy: SnapBuddyRef, last: bool): bool =
|
|
## Sync processsing multiplexer
|
|
ignoreException("runPool"):
|
|
result = buddy.ctx.playSyncSpecs.pool(buddy,last)
|
|
|
|
proc runMulti*(buddy: SnapBuddyRef) {.async.} =
|
|
## Sync processsing multiplexer
|
|
ignoreException("runMulti"):
|
|
await buddy.ctx.playSyncSpecs.multi(buddy)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# End
|
|
# ------------------------------------------------------------------------------
|