Jordan Hrycaj 76f6de8059
Normalise snap objects (#1114)
* Fix/recover download flag

why:
  The fetch indicator used to control the data download somehow got
  lost during re-org.

* Updated chronicles/logger topics

* Reorganised run state flags

why:
  The original code used a pair of boolean flags `(stopped,stopThisState)`
  which was translated to three states running, stoppedPending, and
  stopped. It is currently not clear whether collapsing some states was
  correct. So the original logic has been re-stored, albeit wrapped into
  directives like `isStopped()` etc.

also:
  Moving some function bodies in `worker.nim`

* Moved `reply_data.nim` and `validate_trienode.nim` to sub-directory `fetch_trie`

why:
  Only used in `fetch_trie.nim`.

* Move `fetch_*` file and directory objects to `fetch` subdirectory

why:
  Only used in `fetch.nim`

* Added start/stop and/or setup/release methods for all sub-modules

why:
  good housekeeping

also:
  updated getters/setters for ctrl states
  updated trace messages
2022-06-06 14:42:08 +01:00

117 lines
3.8 KiB
Nim

# Nimbus - Fetch account and storage states from peers efficiently
#
# 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.
import
std/[sets, random],
chronos,
nimcrypto/keccak,
stint,
eth/[common/eth_types, p2p],
../../types,
../path_desc,
./fetch/[common, fetch_snap, fetch_trie],
./worker_desc
{.push raises: [Defect].}
logScope:
topics = "snap fetch"
# Note: To test disabling snap (or trie), modify `fetchTrieOk` or
# `fetchSnapOk` where those are defined.
# ------------------------------------------------------------------------------
# Public start/stop and admin functions
# ------------------------------------------------------------------------------
proc fetchSetup*(ns: Worker) =
## Global set up
ns.commonSetup()
proc fetchRelease*(ns: Worker) =
## Global clean up
ns.commonRelease()
proc fetchStart*(sp: WorkerBuddy) =
## Initialise `WorkerBuddy` to support `ReplyData.new()` calls.
sp.fetchTrieStart()
trace "Supported fetch modes", peer=sp,
ctrlState=sp.ctrl.state, trieMode=sp.fetchTrieOk, snapMode=sp.fetchSnapOk
proc fetchStop*(sp: WorkerBuddy) =
## Clean up for this peer
sp.fetchTrieStop()
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
proc fetch*(sp: WorkerBuddy) {.async.} =
var stateRoot = sp.ctrl.stateRoot.get
trace "Syncing from stateRoot", peer=sp, stateRoot
while true:
if not sp.fetchTrieOk and not sp.fetchSnapOk:
trace "No more sync available from this peer", peer=sp
return
if not sp.hasSlice():
trace "Nothing more to sync from this peer", peer=sp
while not sp.hasSlice():
await sleepAsync(5.seconds) # TODO: Use an event trigger instead.
if sp.ctrl.stateRoot.isNone:
trace "No current state root for this peer", peer=sp
while sp.ctrl.stateRoot.isNone and
(sp.fetchTrieOk or sp.fetchSnapOk) and
sp.hasSlice():
await sleepAsync(5.seconds) # TODO: Use an event trigger instead.
continue
if stateRoot != sp.ctrl.stateRoot.get:
trace "Syncing from new stateRoot", peer=sp, stateRoot
stateRoot = sp.ctrl.stateRoot.get
sp.ctrl.stopped = false
if sp.ctrl.stopRequest:
trace "Pausing sync until we get a new state root", peer=sp
while sp.ctrl.stateRoot.isSome and stateRoot == sp.ctrl.stateRoot.get and
(sp.fetchTrieOk or sp.fetchSnapOk) and
sp.hasSlice():
await sleepAsync(5.seconds) # TODO: Use an event trigger instead.
continue
var leafRange: LeafRange
# Mix up different slice modes, because when connecting to static nodes one
# mode or the other tends to dominate, which makes the mix harder to test.
var allowSnap = true
if sp.fetchSnapOk and sp.fetchTrieOk:
if rand(99) < 50:
allowSnap = false
if sp.fetchSnapOk and allowSnap:
discard sp.getSlice(leafRange)
trace "GetAccountRange segment", peer=sp,
leafRange=pathRange(leafRange.leafLow, leafRange.leafHigh), stateRoot
await sp.fetchSnap(stateRoot, leafRange)
elif sp.fetchTrieOk:
discard sp.getSlice(leafRange)
trace "GetNodeData segment", peer=sp,
leafRange=pathRange(leafRange.leafLow, leafRange.leafHigh), stateRoot
await sp.fetchTrie(stateRoot, leafRange)
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------