nimbus-eth1/nimbus/utils/prettify.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

68 lines
2.4 KiB
Nim

# Nimbus - Types, data structures and shared utilities used in network sync
#
# 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.
## Some logging helper moved here in absence of a known better place.
import
std/[math, strutils]
proc toSI*(num: SomeUnsignedInt): string =
## Prints `num` argument value greater than 99 as rounded SI unit.
const
siUnits = [
# <limit> <multiplier> <symbol>
( 100_000u64, 1000f64, 'k'),
( 100_000_000u64, 1000_000f64, 'm'),
( 100_000_000_000u64, 1000_000_000f64, 'g'),
( 100_000_000_000_000u64, 1000_000_000_000f64, 't'),
( 100_000_000_000_000_000u64, 1000_000_000_000_000f64, 'p'),
(10_000_000_000_000_000_000u64, 1000_000_000_000_000_000f64, 'e')]
lastUnit =
# <no-limit-here> <multiplier> <symbol>
( 1000_000_000_000_000_000_000f64, 'z')
if num < 1000:
return $num
block checkRange:
let
uNum = num.uint64
fRnd = (num.float + 5) * 100
for (top, base, sig) in siUnits:
if uNum < top:
result = (fRnd / base).int.intToStr(3) & $sig
break checkRange
result = (fRnd / lastUnit[0]).int.intToStr(3) & $lastUnit[1]
result.insert(".", result.len - 3)
proc toPC*(
num: float;
digitsAfterDot: static[int] = 2;
rounding: static[float] = 5.0
): string =
## Convert argument number `num` to percent string with decimal precision
## stated as argument `digitsAfterDot`. Standard rounding is enabled by
## default adjusting the first invisible digit, set `rounding = 0` to disable.
const
minDigits = digitsAfterDot + 1
multiplier = (10 ^ (minDigits + 1)).float
roundUp = rounding / 10.0
let
sign = if num < 0: "-" else: ""
preTruncated = (num.abs * multiplier) + roundUp
if int.high.float <= preTruncated:
return "NaN"
result = sign & preTruncated.int.intToStr(minDigits) & "%"
when 0 < digitsAfterDot:
result.insert(".", result.len - minDigits)