2024-09-09 09:12:56 +00:00
|
|
|
# Nimbus
|
|
|
|
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at
|
|
|
|
# https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at
|
|
|
|
# https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed
|
|
|
|
# except according to those terms.
|
|
|
|
|
|
|
|
{.push raises:[].}
|
|
|
|
|
|
|
|
import
|
|
|
|
pkg/eth/[common, p2p],
|
2024-10-01 09:19:29 +00:00
|
|
|
../../../core/chain,
|
2024-09-09 09:12:56 +00:00
|
|
|
../../protocol,
|
|
|
|
../worker_desc,
|
Flare sync (#2627)
* Cosmetics, small fixes, add stashed headers verifier
* Remove direct `Era1` support
why:
Era1 is indirectly supported by using the import tool before syncing.
* Clarify database persistent save function.
why:
Function relied on the last saved state block number which was wrong.
It now relies on the tx-level. If it is 0, then data are saved directly.
Otherwise the task that owns the tx will do it.
* Extracted configuration constants into separate file
* Enable single peer mode for debugging
* Fix peer losing issue in multi-mode
details:
Running concurrent download peers was previously programmed as running
a batch downloading and storing ~8k headers and then leaving the `async`
function to be restarted by a scheduler.
This was unfortunate because of occasionally occurring long waiting
times for restart.
While the time gap until restarting were typically observed a few
millisecs, there were always a few outliers which well exceed several
seconds. This seemed to let remote peers run into timeouts.
* Prefix function names `unprocXxx()` and `stagedYyy()` by `headers`
why:
There will be other `unproc` and `staged` modules.
* Remove cruft, update logging
* Fix accounting issue
details:
When staging after fetching headers from the network, there was an off
by 1 error occurring when the result was by one smaller than requested.
Also, a whole range was mis-accounted when a peer was terminating
connection immediately after responding.
* Fix slow/error header accounting when fetching
why:
Originally set for detecting slow headers in a row, the counter
was wrongly extended to general errors.
* Ban peers for a while that respond with too few headers continuously
why:
Some peers only returned one header at a time. If these peers sit on a
farm, they might collectively slow down the download process.
* Update RPC beacon header updater
why:
Old function hook has slightly changed its meaning since it was used
for snap sync. Also, the old hook is used by other functions already.
* Limit number of peers or set to single peer mode
details:
Merge several concepts, single peer mode being one of it.
* Some code clean up, fixings for removing of compiler warnings
* De-noise header fetch related sources
why:
Header download looks relatively stable, so general debugging is not
needed, anymore. This is the equivalent of removing the scaffold from
the part of the building where work has completed.
* More clean up and code prettification for headers stuff
* Implement body fetch and block import
details:
Available headers are used stage blocks by combining existing headers
with newly fetched blocks. Then these blocks are imported/executed via
`persistBlocks()`.
* Logger cosmetics and cleanup
* Remove staged block queue debugging
details:
Feature still available, just not executed anymore
* Docu, logging update
* Update/simplify `runDaemon()`
* Re-calibrate block body requests and soft config for import blocks batch
why:
* For fetching, larger fetch requests are mostly truncated anyway on
MainNet.
* For executing, smaller batch sizes reduce the memory needed for the
price of longer execution times.
* Update metrics counters
* Docu update
* Some fixes, formatting updates, etc.
* Update `borrowed` type: uint -. uint64
also:
Always convert to `uint64` rather than `uint` where appropriate
2024-09-27 15:07:42 +00:00
|
|
|
"."/[blocks_staged, blocks_unproc, db, headers_staged, headers_unproc]
|
2024-09-09 09:12:56 +00:00
|
|
|
|
|
|
|
when enableTicker:
|
|
|
|
import ./start_stop/ticker
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private functions
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
when enableTicker:
|
2024-10-02 11:31:33 +00:00
|
|
|
proc tickerUpdater(ctx: BeaconCtxRef): TickerStatsUpdater =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Legacy stuff, will be probably be superseded by `metrics`
|
2024-10-02 11:31:33 +00:00
|
|
|
return proc: auto =
|
|
|
|
TickerStats(
|
2024-10-03 20:19:11 +00:00
|
|
|
base: ctx.dbStateBlockNumber(),
|
|
|
|
coupler: ctx.layout.coupler,
|
|
|
|
dangling: ctx.layout.dangling,
|
|
|
|
endBn: ctx.layout.endBn,
|
2024-10-09 18:00:00 +00:00
|
|
|
target: ctx.lhc.target.header.number,
|
|
|
|
newTargetOk: ctx.lhc.target.changed,
|
Flare sync (#2627)
* Cosmetics, small fixes, add stashed headers verifier
* Remove direct `Era1` support
why:
Era1 is indirectly supported by using the import tool before syncing.
* Clarify database persistent save function.
why:
Function relied on the last saved state block number which was wrong.
It now relies on the tx-level. If it is 0, then data are saved directly.
Otherwise the task that owns the tx will do it.
* Extracted configuration constants into separate file
* Enable single peer mode for debugging
* Fix peer losing issue in multi-mode
details:
Running concurrent download peers was previously programmed as running
a batch downloading and storing ~8k headers and then leaving the `async`
function to be restarted by a scheduler.
This was unfortunate because of occasionally occurring long waiting
times for restart.
While the time gap until restarting were typically observed a few
millisecs, there were always a few outliers which well exceed several
seconds. This seemed to let remote peers run into timeouts.
* Prefix function names `unprocXxx()` and `stagedYyy()` by `headers`
why:
There will be other `unproc` and `staged` modules.
* Remove cruft, update logging
* Fix accounting issue
details:
When staging after fetching headers from the network, there was an off
by 1 error occurring when the result was by one smaller than requested.
Also, a whole range was mis-accounted when a peer was terminating
connection immediately after responding.
* Fix slow/error header accounting when fetching
why:
Originally set for detecting slow headers in a row, the counter
was wrongly extended to general errors.
* Ban peers for a while that respond with too few headers continuously
why:
Some peers only returned one header at a time. If these peers sit on a
farm, they might collectively slow down the download process.
* Update RPC beacon header updater
why:
Old function hook has slightly changed its meaning since it was used
for snap sync. Also, the old hook is used by other functions already.
* Limit number of peers or set to single peer mode
details:
Merge several concepts, single peer mode being one of it.
* Some code clean up, fixings for removing of compiler warnings
* De-noise header fetch related sources
why:
Header download looks relatively stable, so general debugging is not
needed, anymore. This is the equivalent of removing the scaffold from
the part of the building where work has completed.
* More clean up and code prettification for headers stuff
* Implement body fetch and block import
details:
Available headers are used stage blocks by combining existing headers
with newly fetched blocks. Then these blocks are imported/executed via
`persistBlocks()`.
* Logger cosmetics and cleanup
* Remove staged block queue debugging
details:
Feature still available, just not executed anymore
* Docu, logging update
* Update/simplify `runDaemon()`
* Re-calibrate block body requests and soft config for import blocks batch
why:
* For fetching, larger fetch requests are mostly truncated anyway on
MainNet.
* For executing, smaller batch sizes reduce the memory needed for the
price of longer execution times.
* Update metrics counters
* Docu update
* Some fixes, formatting updates, etc.
* Update `borrowed` type: uint -. uint64
also:
Always convert to `uint64` rather than `uint` where appropriate
2024-09-27 15:07:42 +00:00
|
|
|
|
|
|
|
nHdrStaged: ctx.headersStagedQueueLen(),
|
|
|
|
hdrStagedTop: ctx.headersStagedTopKey(),
|
|
|
|
hdrUnprocTop: ctx.headersUnprocTop(),
|
|
|
|
nHdrUnprocessed: ctx.headersUnprocTotal() + ctx.headersUnprocBorrowed(),
|
|
|
|
nHdrUnprocFragm: ctx.headersUnprocChunks(),
|
|
|
|
|
|
|
|
nBlkStaged: ctx.blocksStagedQueueLen(),
|
|
|
|
blkStagedBottom: ctx.blocksStagedBottomKey(),
|
|
|
|
blkUnprocTop: ctx.blk.topRequest,
|
|
|
|
nBlkUnprocessed: ctx.blocksUnprocTotal() + ctx.blocksUnprocBorrowed(),
|
|
|
|
nBlkUnprocFragm: ctx.blocksUnprocChunks(),
|
|
|
|
|
2024-10-03 20:19:11 +00:00
|
|
|
reorg: ctx.pool.nReorg,
|
|
|
|
nBuddies: ctx.pool.nBuddies)
|
Flare sync (#2627)
* Cosmetics, small fixes, add stashed headers verifier
* Remove direct `Era1` support
why:
Era1 is indirectly supported by using the import tool before syncing.
* Clarify database persistent save function.
why:
Function relied on the last saved state block number which was wrong.
It now relies on the tx-level. If it is 0, then data are saved directly.
Otherwise the task that owns the tx will do it.
* Extracted configuration constants into separate file
* Enable single peer mode for debugging
* Fix peer losing issue in multi-mode
details:
Running concurrent download peers was previously programmed as running
a batch downloading and storing ~8k headers and then leaving the `async`
function to be restarted by a scheduler.
This was unfortunate because of occasionally occurring long waiting
times for restart.
While the time gap until restarting were typically observed a few
millisecs, there were always a few outliers which well exceed several
seconds. This seemed to let remote peers run into timeouts.
* Prefix function names `unprocXxx()` and `stagedYyy()` by `headers`
why:
There will be other `unproc` and `staged` modules.
* Remove cruft, update logging
* Fix accounting issue
details:
When staging after fetching headers from the network, there was an off
by 1 error occurring when the result was by one smaller than requested.
Also, a whole range was mis-accounted when a peer was terminating
connection immediately after responding.
* Fix slow/error header accounting when fetching
why:
Originally set for detecting slow headers in a row, the counter
was wrongly extended to general errors.
* Ban peers for a while that respond with too few headers continuously
why:
Some peers only returned one header at a time. If these peers sit on a
farm, they might collectively slow down the download process.
* Update RPC beacon header updater
why:
Old function hook has slightly changed its meaning since it was used
for snap sync. Also, the old hook is used by other functions already.
* Limit number of peers or set to single peer mode
details:
Merge several concepts, single peer mode being one of it.
* Some code clean up, fixings for removing of compiler warnings
* De-noise header fetch related sources
why:
Header download looks relatively stable, so general debugging is not
needed, anymore. This is the equivalent of removing the scaffold from
the part of the building where work has completed.
* More clean up and code prettification for headers stuff
* Implement body fetch and block import
details:
Available headers are used stage blocks by combining existing headers
with newly fetched blocks. Then these blocks are imported/executed via
`persistBlocks()`.
* Logger cosmetics and cleanup
* Remove staged block queue debugging
details:
Feature still available, just not executed anymore
* Docu, logging update
* Update/simplify `runDaemon()`
* Re-calibrate block body requests and soft config for import blocks batch
why:
* For fetching, larger fetch requests are mostly truncated anyway on
MainNet.
* For executing, smaller batch sizes reduce the memory needed for the
price of longer execution times.
* Update metrics counters
* Docu update
* Some fixes, formatting updates, etc.
* Update `borrowed` type: uint -. uint64
also:
Always convert to `uint64` rather than `uint` where appropriate
2024-09-27 15:07:42 +00:00
|
|
|
|
2024-10-09 18:00:00 +00:00
|
|
|
proc updateBeaconHeaderCB(ctx: BeaconCtxRef): ReqBeaconSyncTargetCB =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Update beacon header. This function is intended as a call back function
|
|
|
|
## for the RPC module.
|
2024-10-09 18:00:00 +00:00
|
|
|
return proc(h: Header) {.gcsafe, raises: [].} =
|
2024-10-01 09:19:29 +00:00
|
|
|
# Rpc checks empty header against a zero hash rather than `emptyRoot`
|
2024-10-09 18:00:00 +00:00
|
|
|
if ctx.lhc.target.header.number < h.number:
|
|
|
|
ctx.lhc.target.header = h
|
|
|
|
ctx.lhc.target.changed = true
|
2024-09-09 09:12:56 +00:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Public functions
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
when enableTicker:
|
2024-10-02 11:31:33 +00:00
|
|
|
proc setupTicker*(ctx: BeaconCtxRef) =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Helper for `setup()`: Start ticker
|
|
|
|
ctx.pool.ticker = TickerRef.init(ctx.tickerUpdater)
|
|
|
|
|
2024-10-02 11:31:33 +00:00
|
|
|
proc destroyTicker*(ctx: BeaconCtxRef) =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Helper for `release()`
|
|
|
|
ctx.pool.ticker.destroy()
|
|
|
|
ctx.pool.ticker = TickerRef(nil)
|
|
|
|
|
|
|
|
else:
|
2024-10-02 11:31:33 +00:00
|
|
|
template setupTicker*(ctx: BeaconCtxRef) = discard
|
|
|
|
template destroyTicker*(ctx: BeaconCtxRef) = discard
|
2024-09-09 09:12:56 +00:00
|
|
|
|
|
|
|
# ---------
|
|
|
|
|
2024-10-02 11:31:33 +00:00
|
|
|
proc setupDatabase*(ctx: BeaconCtxRef) =
|
Flare sync (#2627)
* Cosmetics, small fixes, add stashed headers verifier
* Remove direct `Era1` support
why:
Era1 is indirectly supported by using the import tool before syncing.
* Clarify database persistent save function.
why:
Function relied on the last saved state block number which was wrong.
It now relies on the tx-level. If it is 0, then data are saved directly.
Otherwise the task that owns the tx will do it.
* Extracted configuration constants into separate file
* Enable single peer mode for debugging
* Fix peer losing issue in multi-mode
details:
Running concurrent download peers was previously programmed as running
a batch downloading and storing ~8k headers and then leaving the `async`
function to be restarted by a scheduler.
This was unfortunate because of occasionally occurring long waiting
times for restart.
While the time gap until restarting were typically observed a few
millisecs, there were always a few outliers which well exceed several
seconds. This seemed to let remote peers run into timeouts.
* Prefix function names `unprocXxx()` and `stagedYyy()` by `headers`
why:
There will be other `unproc` and `staged` modules.
* Remove cruft, update logging
* Fix accounting issue
details:
When staging after fetching headers from the network, there was an off
by 1 error occurring when the result was by one smaller than requested.
Also, a whole range was mis-accounted when a peer was terminating
connection immediately after responding.
* Fix slow/error header accounting when fetching
why:
Originally set for detecting slow headers in a row, the counter
was wrongly extended to general errors.
* Ban peers for a while that respond with too few headers continuously
why:
Some peers only returned one header at a time. If these peers sit on a
farm, they might collectively slow down the download process.
* Update RPC beacon header updater
why:
Old function hook has slightly changed its meaning since it was used
for snap sync. Also, the old hook is used by other functions already.
* Limit number of peers or set to single peer mode
details:
Merge several concepts, single peer mode being one of it.
* Some code clean up, fixings for removing of compiler warnings
* De-noise header fetch related sources
why:
Header download looks relatively stable, so general debugging is not
needed, anymore. This is the equivalent of removing the scaffold from
the part of the building where work has completed.
* More clean up and code prettification for headers stuff
* Implement body fetch and block import
details:
Available headers are used stage blocks by combining existing headers
with newly fetched blocks. Then these blocks are imported/executed via
`persistBlocks()`.
* Logger cosmetics and cleanup
* Remove staged block queue debugging
details:
Feature still available, just not executed anymore
* Docu, logging update
* Update/simplify `runDaemon()`
* Re-calibrate block body requests and soft config for import blocks batch
why:
* For fetching, larger fetch requests are mostly truncated anyway on
MainNet.
* For executing, smaller batch sizes reduce the memory needed for the
price of longer execution times.
* Update metrics counters
* Docu update
* Some fixes, formatting updates, etc.
* Update `borrowed` type: uint -. uint64
also:
Always convert to `uint64` rather than `uint` where appropriate
2024-09-27 15:07:42 +00:00
|
|
|
## Initalise database related stuff
|
|
|
|
|
|
|
|
# Initialise up queues and lists
|
|
|
|
ctx.headersStagedInit()
|
|
|
|
ctx.blocksStagedInit()
|
|
|
|
ctx.headersUnprocInit()
|
|
|
|
ctx.blocksUnprocInit()
|
|
|
|
|
|
|
|
# Load initial state from database if there is any
|
|
|
|
ctx.dbLoadLinkedHChainsLayout()
|
|
|
|
|
|
|
|
# Set blocks batch import value for `persistBlocks()`
|
|
|
|
if ctx.pool.nBodiesBatch < nFetchBodiesRequest:
|
|
|
|
if ctx.pool.nBodiesBatch == 0:
|
|
|
|
ctx.pool.nBodiesBatch = nFetchBodiesBatchDefault
|
|
|
|
else:
|
|
|
|
ctx.pool.nBodiesBatch = nFetchBodiesRequest
|
|
|
|
|
|
|
|
# Set length of `staged` queue
|
|
|
|
if ctx.pool.nBodiesBatch < nFetchBodiesBatchDefault:
|
|
|
|
const nBlocks = blocksStagedQueueLenMaxDefault * nFetchBodiesBatchDefault
|
|
|
|
ctx.pool.blocksStagedQuLenMax =
|
|
|
|
(nBlocks + ctx.pool.nBodiesBatch - 1) div ctx.pool.nBodiesBatch
|
|
|
|
else:
|
|
|
|
ctx.pool.blocksStagedQuLenMax = blocksStagedQueueLenMaxDefault
|
|
|
|
|
|
|
|
|
2024-10-02 11:31:33 +00:00
|
|
|
proc setupRpcMagic*(ctx: BeaconCtxRef) =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Helper for `setup()`: Enable external pivot update via RPC
|
2024-10-09 18:00:00 +00:00
|
|
|
ctx.pool.chain.com.reqBeaconSyncTarget = ctx.updateBeaconHeaderCB
|
2024-09-09 09:12:56 +00:00
|
|
|
|
2024-10-02 11:31:33 +00:00
|
|
|
proc destroyRpcMagic*(ctx: BeaconCtxRef) =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Helper for `release()`
|
2024-10-09 18:00:00 +00:00
|
|
|
ctx.pool.chain.com.reqBeaconSyncTarget = ReqBeaconSyncTargetCB(nil)
|
2024-09-09 09:12:56 +00:00
|
|
|
|
|
|
|
# ---------
|
|
|
|
|
2024-10-02 11:31:33 +00:00
|
|
|
proc startBuddy*(buddy: BeaconBuddyRef): bool =
|
2024-09-09 09:12:56 +00:00
|
|
|
## Convenience setting for starting a new worker
|
|
|
|
let
|
|
|
|
ctx = buddy.ctx
|
|
|
|
peer = buddy.peer
|
|
|
|
if peer.supports(protocol.eth) and peer.state(protocol.eth).initialized:
|
|
|
|
ctx.pool.nBuddies.inc # for metrics
|
|
|
|
return true
|
|
|
|
|
2024-10-02 11:31:33 +00:00
|
|
|
proc stopBuddy*(buddy: BeaconBuddyRef) =
|
2024-09-09 09:12:56 +00:00
|
|
|
buddy.ctx.pool.nBuddies.dec # for metrics
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# End
|
|
|
|
# ------------------------------------------------------------------------------
|