mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 13:24:21 +00:00
maintenance update
why: some handy features were intended to support the unit test from the clique/clique_test.go source (the other one is from clique/snapshot_test.go.) as this test cannot realistically be implemented without the full api (includes mining support), it is left as that
This commit is contained in:
parent
90b012ad3f
commit
82e6cd991d
@ -230,7 +230,7 @@ proc setDebug*(rs: var RecentSnaps; debug: bool) =
|
||||
proc getRecentSnaps*(rs: var RecentSnaps; args: RecentArgs): auto {.
|
||||
gcsafe, raises: [Defect,CatchableError].} =
|
||||
## Get snapshot from cache or disk
|
||||
rs.say "getRecentSnap #", args.blockNumber.truncate(uint64)
|
||||
rs.say "getRecentSnap #", args.blockNumber
|
||||
rs.cache.getLruItem:
|
||||
RecentDesc(cfg: rs.cfg,
|
||||
debug: rs.debug,
|
||||
|
@ -74,7 +74,6 @@ proc getPrettyPrinters(s: var Snapshot): var PrettyPrinters =
|
||||
proc pp(s: var Snapshot; h: var AddressHistory): string =
|
||||
ppExceptionWrap:
|
||||
toSeq(h.keys)
|
||||
.mapIt(it.truncate(uint64))
|
||||
.sorted
|
||||
.mapIt("#" & $it & ":" & s.pp(h[it.u256]))
|
||||
.join(",")
|
||||
@ -85,7 +84,7 @@ proc pp(s: var Snapshot; v: Vote): string =
|
||||
ppExceptionWrap:
|
||||
"(" & &"address={s.pp(v.address)}" &
|
||||
&",signer={s.pp(v.signer)}" &
|
||||
&",blockNumber={v.blockNumber.truncate(uint64)}" &
|
||||
&",blockNumber={v.blockNumber}" &
|
||||
&",{authorized(v.authorize)}" & ")"
|
||||
|
||||
proc votesList(s: var Snapshot; sep: string): string =
|
||||
@ -234,7 +233,7 @@ proc applySnapshot*(s: var Snapshot;
|
||||
header = headers[headersIndex]
|
||||
number = header.blockNumber
|
||||
|
||||
s.say "applySnapshot processing #", number.truncate(uint64)
|
||||
s.say "applySnapshot processing #", number
|
||||
|
||||
# Remove any votes on checkpoint blocks
|
||||
if (number mod s.cfg.epoch) == 0:
|
||||
|
@ -17,6 +17,7 @@ import
|
||||
stint,
|
||||
unittest2
|
||||
|
||||
|
||||
# clique/snapshot_test.go(99): func TestClique(t *testing.T) {
|
||||
proc cliqueMain*(noisy = defined(debug)) =
|
||||
## Clique PoA Snapshot
|
||||
@ -27,12 +28,11 @@ proc cliqueMain*(noisy = defined(debug)) =
|
||||
##
|
||||
suite "Clique PoA Snapshot":
|
||||
var
|
||||
pool = newTesterPool()
|
||||
pool = newVoterPool().setDebug(noisy)
|
||||
const
|
||||
skipSet = {999}
|
||||
testSet = {0 .. 999}
|
||||
|
||||
pool.setDebug(noisy)
|
||||
|
||||
# clique/snapshot_test.go(379): for i, tt := range tests {
|
||||
for tt in voterSamples.filterIt(it.id in testSet):
|
||||
|
||||
@ -45,12 +45,11 @@ proc cliqueMain*(noisy = defined(debug)) =
|
||||
else:
|
||||
# Assemble a chain of headers from the cast votes
|
||||
# see clique/snapshot_test.go(407): config := *params.TestChainConfig
|
||||
pool.resetVoterChain(tt.signers, tt.epoch)
|
||||
|
||||
# see clique/snapshot_test.go(425): for j, block := range blocks {
|
||||
for voter in tt.votes:
|
||||
pool.appendVoter(voter)
|
||||
pool.commitVoterChain
|
||||
pool
|
||||
.resetVoterChain(tt.signers, tt.epoch)
|
||||
# see clique/snapshot_test.go(425): for j, block := range blocks {
|
||||
.appendVoter(tt.votes)
|
||||
.commitVoterChain
|
||||
|
||||
# see clique/snapshot_test.go(476): snap, err := engine.snapshot( [..]
|
||||
let topHeader = pool.topVoterHeader
|
||||
|
@ -51,19 +51,18 @@ type
|
||||
# Private Helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc bespokeGenesis(file: string): CustomGenesis =
|
||||
## Find genesis block
|
||||
if file == "":
|
||||
let networkId = getConfiguration().net.networkId
|
||||
result.genesis = defaultGenesisBlockForNetwork(networkId)
|
||||
else:
|
||||
doAssert file.loadCustomGenesis(result)
|
||||
result.config.poaEngine = true
|
||||
|
||||
proc chain(ap: TesterPool): BaseChainDB =
|
||||
## Getter
|
||||
ap.engine.cfgInternal.dbChain
|
||||
|
||||
proc getBlockHeader(ap: TesterPool; number: BlockNumber): BlockHeader =
|
||||
## Shortcut => db/db_chain.getBlockHeader()
|
||||
doAssert ap.chain.getBlockHeader(number, result)
|
||||
|
||||
proc getBlockHeader(ap: TesterPool; hash: Hash256): BlockHeader =
|
||||
## Shortcut => db/db_chain.getBlockHeader()
|
||||
doAssert ap.chain.getBlockHeader(hash, result)
|
||||
|
||||
proc isZero(a: openArray[byte]): bool =
|
||||
result = true
|
||||
for w in a:
|
||||
@ -189,12 +188,32 @@ proc ppBlockHeader(ap: TesterPool; v: BlockHeader; delim: string): string =
|
||||
&"{sep}nonce={ap.ppNonce(v.nonce)}" &
|
||||
&"{sep}extraData={ap.ppExtraData(v.extraData)})"
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private: Constructor helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc initPrettyPrinters(pp: var PrettyPrinters; ap: TesterPool) =
|
||||
pp.nonce = proc(v:BlockNonce): string = ap.ppNonce(v)
|
||||
pp.address = proc(v:EthAddress): string = ap.ppAddress(v)
|
||||
pp.extraData = proc(v:Blob): string = ap.ppExtraData(v)
|
||||
pp.blockHeader = proc(v:BlockHeader; d:string): string = ap.ppBlockHeader(v,d)
|
||||
|
||||
proc initTesterPool(ap: TesterPool): TesterPool {.discardable.} =
|
||||
result = ap
|
||||
result.boot.config.poaEngine = true
|
||||
result.prng = initRand(prngSeed)
|
||||
result.batch = @[newSeq[BlockHeader]()]
|
||||
result.accounts = initTable[string,PrivateKey]()
|
||||
result.xSeals = initTable[XSealKey,XSealValue]()
|
||||
result.names = initTable[EthAddress,string]()
|
||||
result.engine = newCliqueCfg(
|
||||
dbChain = BaseChainDB(),
|
||||
period = initDuration(seconds = 1))
|
||||
.initClique
|
||||
result.engine.setDebug(false)
|
||||
result.engine.cfgInternal.prettyPrint.initPrettyPrinters(result)
|
||||
result.resetChainDb(@[])
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -203,33 +222,26 @@ proc getPrettyPrinters*(t: TesterPool): var PrettyPrinters =
|
||||
## Mixin for pretty printers, see `clique/clique_cfg.pp()`
|
||||
t.engine.cfgInternal.prettyPrint
|
||||
|
||||
proc setDebug*(ap: TesterPool; debug=true): TesterPool {.inline,discardable,} =
|
||||
## Set debugging mode on/off
|
||||
result = ap
|
||||
ap.debug = debug
|
||||
ap.engine.setDebug(debug)
|
||||
|
||||
proc say*(t: TesterPool; v: varargs[string,`$`]) =
|
||||
if t.debug:
|
||||
stderr.write v.join & "\n"
|
||||
|
||||
|
||||
proc newTesterPool*(epoch = 0.u256; genesisTemplate = ""): TesterPool =
|
||||
new result
|
||||
result.boot = genesisTemplate.bespokeGenesis
|
||||
result.prng = initRand(prngSeed)
|
||||
result.batch = @[newSeq[BlockHeader]()]
|
||||
result.accounts = initTable[string,PrivateKey]()
|
||||
result.xSeals = initTable[XSealKey,XSealValue]()
|
||||
result.names = initTable[EthAddress,string]()
|
||||
result.engine = newCliqueCfg(
|
||||
dbChain = BaseChainDB(),
|
||||
period = initDuration(seconds = 1),
|
||||
epoch = epoch)
|
||||
.initClique
|
||||
result.engine.setDebug(false)
|
||||
result.engine.cfgInternal.prettyPrint.initPrettyPrinters(result)
|
||||
result.resetChainDb(@[])
|
||||
|
||||
|
||||
proc setDebug*(ap: TesterPool; debug = true) =
|
||||
## Set debugging mode on/off
|
||||
ap.debug = debug
|
||||
ap.engine.setDebug(debug)
|
||||
proc sayHeaderChain*(ap: TesterPool; indent = 0): TesterPool {.discardable.} =
|
||||
result = ap
|
||||
let pfx = ' '.repeat(indent)
|
||||
var top = if 0 < ap.batch[^1].len: ap.batch[^1][^1]
|
||||
else: ap.getBlockHeader(0.u256)
|
||||
ap.say pfx, " top header: " & ap.pp(top, 16+indent)
|
||||
while not top.blockNumber.isZero:
|
||||
top = ap.getBlockHeader(top.parentHash)
|
||||
ap.say pfx, "parent header: " & ap.pp(top, 16+indent)
|
||||
|
||||
|
||||
# clique/snapshot_test.go(62): func (ap *testerAccountPool) address(account [..]
|
||||
@ -277,13 +289,9 @@ proc snapshot*(ap: TesterPool; number: BlockNumber; hash: Hash256;
|
||||
parent: openArray[BlockHeader]): auto =
|
||||
## Call p2p/clique.snapshotInternal()
|
||||
if ap.debug:
|
||||
var header = ap.chain.getBlockHeader(number)
|
||||
ap.say "*** snapshot argument: ", ap.pp(header,24)
|
||||
while true:
|
||||
doAssert ap.chain.getBlockHeader(header.parentHash,header)
|
||||
ap.say " parent header: ", ap.pp(header,24)
|
||||
if header.blockNumber.isZero:
|
||||
break
|
||||
var header = ap.getBlockHeader(number)
|
||||
ap.say "*** snapshot argument: #", number
|
||||
ap.sayHeaderChain(8)
|
||||
when false: # all addresses are typically pp-mappable
|
||||
ap.say " address map: ", toSeq(ap.names.pairs)
|
||||
.mapIt(&"@{it[1]}:{it[0]}")
|
||||
@ -292,13 +300,41 @@ proc snapshot*(ap: TesterPool; number: BlockNumber; hash: Hash256;
|
||||
|
||||
ap.engine.snapshotInternal(number, hash, parent)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public: Constructor
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc newVoterPool*(genesisTemplate = ""): TesterPool =
|
||||
new result
|
||||
if genesisTemplate == "":
|
||||
let networkId = getConfiguration().net.networkId
|
||||
result.boot.genesis = defaultGenesisBlockForNetwork(networkId)
|
||||
else:
|
||||
# Find genesis block
|
||||
doAssert genesisTemplate.loadCustomGenesis(result.boot)
|
||||
result.initTesterPool
|
||||
|
||||
proc newVoterPool*(customGenesis: CustomGenesis): TesterPool =
|
||||
TesterPool(boot: customGenesis).initTesterPool
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public: set up & manage voter database
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc resetVoterChain*(ap: TesterPool;
|
||||
signers: openArray[string]; epoch: uint64) =
|
||||
proc setVoterAccount*(ap: TesterPool; account: string;
|
||||
prvKey: PrivateKey): TesterPool {.discardable.} =
|
||||
## Manually define/import account
|
||||
result = ap
|
||||
ap.accounts[account] = prvKey
|
||||
let address = prvKey.toPublicKey.toCanonicalAddress
|
||||
ap.names[address] = account
|
||||
|
||||
|
||||
proc resetVoterChain*(ap: TesterPool; signers: openArray[string];
|
||||
epoch = 0): TesterPool {.discardable.} =
|
||||
## Reset the batch list for voter headers and update genesis block
|
||||
result = ap
|
||||
|
||||
ap.batch = @[newSeq[BlockHeader]()]
|
||||
|
||||
# clique/snapshot_test.go(384): signers := make([]common.Address, [..]
|
||||
@ -315,15 +351,18 @@ proc resetVoterChain*(ap: TesterPool;
|
||||
|
||||
# store modified genesis block and epoch
|
||||
ap.resetChainDb(extraData)
|
||||
ap.engine.cfgInternal.epoch = epoch
|
||||
ap.engine.cfgInternal.epoch = epoch.uint
|
||||
|
||||
|
||||
# clique/snapshot_test.go(415): blocks, _ := core.GenerateChain(&config, [..]
|
||||
proc appendVoter*(ap: TesterPool; voter: TesterVote) =
|
||||
proc appendVoter*(ap: TesterPool;
|
||||
voter: TesterVote): TesterPool {.discardable.} =
|
||||
## Append a voter header to the block chain batch list
|
||||
result = ap
|
||||
|
||||
doAssert 0 < ap.batch.len # see initTesterPool() and resetVoterChain()
|
||||
let parent = if ap.batch[^1].len == 0:
|
||||
ap.chain.getBlockHeader(0.u256)
|
||||
ap.getBlockHeader(0.u256)
|
||||
else:
|
||||
ap.batch[^1][^1]
|
||||
|
||||
@ -361,8 +400,18 @@ proc appendVoter*(ap: TesterPool; voter: TesterVote) =
|
||||
ap.batch[^1].add header
|
||||
|
||||
|
||||
proc commitVoterChain*(ap: TesterPool) =
|
||||
proc appendVoter*(ap: TesterPool;
|
||||
voters: openArray[TesterVote]): TesterPool {.discardable.} =
|
||||
## Append a list of voter headers to the block chain batch list
|
||||
result = ap
|
||||
for voter in voters:
|
||||
ap.appendVoter(voter)
|
||||
|
||||
|
||||
proc commitVoterChain*(ap: TesterPool): TesterPool {.discardable.} =
|
||||
## Write the headers from the voter header batch list to the block chain DB
|
||||
result = ap
|
||||
|
||||
# Create a pristine blockchain with the genesis injected
|
||||
for headers in ap.batch:
|
||||
if 0 < headers.len:
|
||||
|
@ -29,7 +29,7 @@ type
|
||||
TestSpecs* = object ## Define the various voting scenarios to test
|
||||
id*: int ## Test id
|
||||
info*: string ## Test description
|
||||
epoch*: uint64 ## Number of blocks in an epoch (unset = 30000)
|
||||
epoch*: int ## Number of blocks in an epoch (unset = 30000)
|
||||
signers*: seq[string] ## Initial list of authorized signers in the
|
||||
## genesis
|
||||
votes*: seq[TesterVote] ## Chain of signed blocks, potentially influencing
|
||||
|
Loading…
x
Reference in New Issue
Block a user