nimbus-eth1/nimbus/sync/types.nim
Jordan Hrycaj 4ff0948fed
Snap sync accounts healing (#1225)
* Added inspect module

why:
  Find dangling references for trie healing support.

details:
 + This patch set provides only the inspect module and some unit tests.
 + There are also extensive unit tests which need bulk data from the
   `nimbus-eth1-blob` module.

* Alternative pivot finder

why:
  Attempt to be faster on start up. Also tying to decouple pivot finder
  somehow by providing different mechanisms (this one runs in `single`
  mode.)

* Use inspect module for healing

details:
 + After some progress with account and storage data, the inspect facility
   is used to find dangling links in the database to be filled nose-wise.
 + This is a crude attempt to cobble together functional elements. The
   set up needs to be honed.

* fix scheduler to avoid starting dead peers

why:
  Some peers drop out while in `sleepAsync()`. So extra `if` clauses
  make sure that this event is detected early.

* Bug fixes causing crashes

details:

+ prettify.toPC():
  int/intToStr() numeric range over/underflow

+ hexary_inspect.hexaryInspectPath():
  take care of half initialised step with branch but missing index into
  branch array

* improve handling of dropped peers in alternaive pivot finder

why:
  Strange things may happen while querying data from the network.
  Additional checks make sure that the state of other peers is updated
  immediately.

* Update trace messages

* reorganise snap fetch & store schedule
2022-09-16 08:24:12 +01:00

117 lines
3.8 KiB
Nim

# Nimbus
# Copyright (c) 2018-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/[math, hashes],
eth/common/eth_types_rlp,
stew/byteutils
{.push raises: [Defect].}
type
BlockHash* = distinct Hash256
## Hash of a block, goes with `BlockNumber`.
##
## Note that the `ethXX` protocol driver always uses the
## underlying `Hash256` type which needs to be converted to `BlockHash`.
# ------------------------------------------------------------------------------
# Public constructors
# ------------------------------------------------------------------------------
proc new*(T: type BlockHash): T =
Hash256().T
# ------------------------------------------------------------------------------
# Public (probably non-trivial) type conversions
# ------------------------------------------------------------------------------
proc to*(num: SomeInteger; T: type float): T =
## Convert to float. Result an d argument are not strictly equivalent. Though
## sort of `(num.to(float) + 0.5).int == num` might hold in many cases.
num.T
proc to*(longNum: UInt256; T: type float): T =
## Convert to float (see also comment at `num.to(float)`, above.)
let mantissaLen = 256 - longNum.leadingZeros
if mantissaLen <= 64:
longNum.truncate(uint64).T
else:
let exp = mantissaLen - 64
(longNum shr exp).truncate(uint64).T * (2.0 ^ exp)
proc to*(w: BlockHash; T: type Hash256): T =
## Syntactic sugar
w.Hash256
proc to*(w: seq[BlockHash]; T: type seq[Hash256]): T =
## Ditto
cast[seq[Hash256]](w)
proc to*(bh: BlockHash; T: type HashOrNum): T =
## Convert argument blocj hash `bh` to `HashOrNum`
T(isHash: true, hash: bh.Hash256)
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
proc read*(rlp: var Rlp, T: type BlockHash): T
{.gcsafe, raises: [Defect,RlpError]} =
## RLP mixin reader
rlp.read(Hash256).T
proc append*(writer: var RlpWriter; h: BlockHash) =
## RLP mixin
append(writer, h.Hash256)
proc `==`*(a: BlockHash; b: Hash256): bool =
a.Hash256 == b
proc `==`*[T: BlockHash](a,b: T): bool =
a.Hash256 == b.Hash256
proc hash*(root: BlockHash): Hash =
## Mixin for `Table` or `KeyedQueue`
root.Hash256.data.hash
# ------------------------------------------------------------------------------
# Public printing and pretty printing
# ------------------------------------------------------------------------------
func toHex*(hash: Hash256): string =
## Shortcut for `byteutils.toHex(hash.data)`
hash.data.toHex
func `$`*(h: BlockHash): string =
$h.Hash256.data.toHex
func `$`*(blob: Blob): string =
blob.toHex
func `$`*(hashOrNum: HashOrNum): string =
# It's always obvious which one from the visible length of the string.
if hashOrNum.isHash: $hashOrNum.hash
else: $hashOrNum.number
# ------------------------------------------------------------------------------
# Public debug printing helpers
# ------------------------------------------------------------------------------
func traceStep*(request: BlocksRequest): string =
var str = if request.reverse: "-" else: "+"
if request.skip < high(typeof(request.skip)):
return str & $(request.skip + 1)
return static($(high(typeof(request.skip)).u256 + 1))
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------