ncli_db: add validation flag, better ux

This commit is contained in:
Jacek Sieka 2020-06-01 16:48:24 +02:00 committed by tersec
parent ef90a45509
commit 1fd2cfef62
1 changed files with 57 additions and 25 deletions

View File

@ -1,7 +1,7 @@
import import
confutils, stats, chronicles, strformat, tables, confutils, stats, chronicles, strformat, tables,
../beacon_chain/block_pool, ../beacon_chain/block_pool,
../beacon_chain/spec/[crypto, datatypes], ../beacon_chain/spec/[crypto, datatypes, helpers],
../beacon_chain/[beacon_chain_db, extras, state_transition, ssz], ../beacon_chain/[beacon_chain_db, extras, state_transition, ssz],
../research/simutils, ../research/simutils,
eth/db/[kvstore, kvstore_sqlite3] eth/db/[kvstore, kvstore_sqlite3]
@ -11,13 +11,35 @@ type Timers = enum
tLoadBlock = "Load block from database" tLoadBlock = "Load block from database"
tLoadState = "Load state from database" tLoadState = "Load state from database"
tApplyBlock = "Apply block" tApplyBlock = "Apply block"
tApplyEpochBlock = "Apply epoch block"
cli do(databaseDir: string, cmd: string): type
DbCmd* = enum
bench
DbConf = object
databaseDir* {.
defaultValue: ""
desc: "Directory where `nbc.sqlite` is stored"
name: "db" }: InputDir
case cmd* {.
command
desc: "Run benchmark by applying all blocks from database"
.}: DbCmd
of bench:
validate* {.
defaultValue: true
desc: "Enable BLS validation" }: bool
proc cmdBench(conf: DbConf) =
var timers: array[Timers, RunningStat] var timers: array[Timers, RunningStat]
echo "Opening database..." echo "Opening database..."
let let
db = BeaconChainDB.init(kvStore SqStoreRef.init(databaseDir, "nbc").tryGet()) db = BeaconChainDB.init(
kvStore SqStoreRef.init(conf.databaseDir.string, "nbc").tryGet())
if not BlockPool.isInitialized(db): if not BlockPool.isInitialized(db):
echo "Database not initialized" echo "Database not initialized"
@ -29,30 +51,40 @@ cli do(databaseDir: string, cmd: string):
echo &"Loaded {pool.blocks.len} blocks, head slot {pool.head.blck.slot}" echo &"Loaded {pool.blocks.len} blocks, head slot {pool.head.blck.slot}"
case cmd var
of "bench": blockRefs: seq[BlockRef]
var blocks: seq[SignedBeaconBlock]
blockRefs: seq[BlockRef] cur = pool.head.blck
blocks: seq[SignedBeaconBlock]
cur = pool.head.blck
while cur != nil: while cur != nil:
blockRefs.add cur blockRefs.add cur
cur = cur.parent cur = cur.parent
for b in 1..<blockRefs.len: # Skip genesis block for b in 1..<blockRefs.len: # Skip genesis block
withTimer(timers[tLoadBlock]): withTimer(timers[tLoadBlock]):
blocks.add db.getBlock(blockRefs[blockRefs.len - b - 1].root).get() blocks.add db.getBlock(blockRefs[blockRefs.len - b - 1].root).get()
let state = (ref HashedBeaconState)( let state = (ref HashedBeaconState)(
root: db.getBlock(blockRefs[^1].root).get().message.state_root root: db.getBlock(blockRefs[^1].root).get().message.state_root
) )
withTimer(timers[tLoadState]): withTimer(timers[tLoadState]):
discard db.getState(state[].root, state[].data, noRollback) discard db.getState(state[].root, state[].data, noRollback)
for b in blocks: let flags = if conf.validate: {} else: {skipBlsValidation}
withTimer(timers[tApplyBlock]): for b in blocks:
discard state_transition(state[], b, {}, noRollback) let
isEpoch = state[].data.slot.compute_epoch_at_slot !=
b.message.slot.compute_epoch_at_slot
withTimer(timers[if isEpoch: tApplyEpochBlock else: tApplyBlock]):
discard state_transition(state[], b, flags, noRollback)
printTimers(true, timers) printTimers(conf.validate, timers)
when isMainModule:
let
config = DbConf.load()
case config.cmd
of bench:
cmdBench(config)