nimbus-eth1/tests/test_clique/undump.nim

139 lines
4.2 KiB
Nim
Raw Normal View History

Feature/goerli replay clique poa (#743) * extract unused clique/mining support into separate file why: mining is currently unsupported by nimbus * Replay first 51840 transactions from Goerli block chain why: Currently Goerli is loaded but the block headers are not verified. Replaying allows real data PoA development. details: Simple stupid gzipped dump/undump layer for debugging based on the zlib module (no nim-faststream support.) This is a replay running against p2p/chain.persistBlocks() where the data were captured from. * prepare stubs for PoA engine * split executor source into sup-modules why: make room for updates, clique integration should go into executor/update_poastate.nim * Simplify p2p/executor.processBlock() function prototype why: vmState argument always wraps basicChainDB * split processBlock() into sub-functions why: isolate the part where it will support clique/poa * provided additional processTransaction() function prototype without _fork_ argument why: with the exception of some tests, the _fork_ argument is always derived from the other prototype argument _vmState_ details: similar situation with makeReceipt() * provide new processBlock() version explicitly supporting PoA details: The new processBlock() version supporting PoA is the general one also supporting non-PoA networks, it needs an additional _Clique_ descriptor function argument for PoA state (if any.) The old processBlock() function without the _Clique_ descriptor argument retorns an error on PoA networgs (e.g. Goerli.) * re-implemented Clique descriptor as _ref object_ why: gives more flexibility when moving around the descriptor object details: also cleaned up a bit the clique sources * comments for clarifying handling of Clique/PoA state descriptor
2021-07-06 13:14:45 +00:00
# Nimbus
# Copyright (c) 2018-2019 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/[sequtils, strformat, strutils],
../../nimbus/db/db_chain,
../../nimbus/utils,
./gunzip,
eth/[common, rlp],
nimcrypto,
stew/results
# ------------------------------------------------------------------------------
# Private helpers
# ------------------------------------------------------------------------------
template say(args: varargs[untyped]) =
# echo args
discard
proc toByteSeq(s: string): seq[byte] =
nimcrypto.fromHex(s)
# ------------------------------------------------------------------------------
# Public capture
# ------------------------------------------------------------------------------
proc dumpGroupBegin*(headers: openArray[BlockHeader]): string =
& "transaction #{headers[0].blockNumber} {headers.len}"
proc dumpGroupBlock*(header: BlockHeader; body: BlockBody): string =
&"block {rlp.encode(header).toHex} {rlp.encode(body).toHex}"
proc dumpGroupEnd*: string =
"commit"
proc dumpGroupEndNl*: string =
dumpGroupEnd() & "\n\n"
proc dumpGroupBlockNl*(header: BlockHeader; body: BlockBody): string =
dumpGroupBlock(header, body) & "\n"
proc dumpGroupBeginNl*(db: var BaseChainDB;
headers: openArray[BlockHeader]): string =
if headers[0].blockNumber == 1.u256:
let
h0 = db.getBlockHeader(0.u256)
b0 = db.getBlockBody(h0.hash)
result = "" &
dumpGroupBegin(@[h0]) & "\n" &
dumpGroupBlockNl(h0,b0) &
dumpGroupEndNl()
result &= dumpGroupBegin(headers) & "\n"
proc dumpGroupNl*(db: var BaseChainDB; headers: openArray[BlockHeader];
bodies: openArray[BlockBody]): string =
db.dumpGroupBeginNl(headers) &
toSeq(countup(0, headers.len-1))
.mapIt(dumpGroupBlockNl(headers[it], bodies[it]))
.join &
dumpGroupEndNl()
# ------------------------------------------------------------------------------
# Public undump
# ------------------------------------------------------------------------------
iterator undumpNextGroup*(gzFile: string): (seq[BlockHeader],seq[BlockBody]) =
var
headerQ: seq[BlockHeader]
bodyQ: seq[BlockBody]
line = ""
lno = 0
current = 0u
start = 0u
top = 0u
waitFor = "transaction"
for lno,line in gzFile.gunzipLines:
if line.len == 0 or line[0] == '#':
continue
var flds = line.split
if 0 < flds.len and (waitFor == "" or waitFor == flds[0]):
case flds[0]
of "transaction":
let flds1Len = flds[1].len
if flds.len == 3 and
0 < flds1Len and flds[1][0] == '#' and
0 < flds[2].len:
start = flds[1][1 ..< flds1Len].parseUInt
top = start + flds[2].parseUInt
current = start
waitFor = ""
headerQ.reset
bodyQ.reset
continue
else:
echo &"*** Ignoring line({lno}): {line}."
waitFor = "transaction"
of "block":
if flds.len == 3 and
0 < flds[1].len and
0 < flds[2].len and
start <= current and current < top:
var
rlpHeader = flds[1].rlpFromHex
rlpBody = flds[2].rlpFromHex
headerQ.add rlpHeader.read(BlockHeader)
bodyQ.add rlpBody.read(BlockBody)
current.inc
continue
else:
echo &"*** Ignoring line({lno}): {line}."
waitFor = "transaction"
of "commit":
if current == top:
say &"*** commit({lno}) #{start}..{top-1}"
else:
echo &"*** commit({lno}) error, current({current}) should be {top}"
yield (headerQ, bodyQ)
waitFor = "transaction"
continue
echo &"*** Ignoring line({lno}): {line}."
waitFor = "transaction"
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------