add restore from slashing DB

This commit is contained in:
Mamy André-Ratsimbazafy 2021-03-30 17:37:03 +02:00 committed by Zahary Karadjov
parent 2c257438a0
commit 0574531c43
No known key found for this signature in database
GPG Key ID: C8936F8A3073D609
4 changed files with 63 additions and 11 deletions

View File

@ -48,6 +48,7 @@ TOOLS := \
nbench_spec_scenarios \
ncli \
ncli_db \
ncli_slashing \
process_dashboard \
stack_sizes \
nimbus_validator_client \

View File

@ -105,6 +105,7 @@ proc init*(
fatal "The slashing database refers to another chain/mainnet/testnet",
path = basePath/dbname,
genesis_validators_root = genesis_validators_root
quit 1
db_v1.fromRawDB(rawdb)
if requiresMigration:
@ -153,15 +154,25 @@ proc loadUnchecked*(
## this doesn't check the genesis validator root
##
## Does not handle migration
new result
result.modes = {kCompleteArchiveV1, kCompleteArchiveV2}
result.modes = {}
result.disagreementBehavior = kCrash
result.db_v2 = SlashingProtectionDB_v2.loadUnchecked(
basePath, dbname, readOnly
)
try:
result.db_v2 = SlashingProtectionDB_v2.loadUnchecked(
basePath, dbname, readOnly
)
result.modes.incl(kCompleteArchiveV2)
except:
result.disagreementBehavior = kChooseV1
result.db_v1.fromRawDB(kvstore result.db_v2.getRawDBHandle())
try:
result.db_v1.fromRawDB(kvstore result.db_v2.getRawDBHandle())
result.modes.incl(kCompleteArchiveV1)
except:
doAssert result.modes.card > 0, "Couldn't open the DB."
result.disagreementBehavior = kChooseV2
proc close*(db: SlashingProtectionDB) =
## Close a slashing protection database

View File

@ -196,7 +196,7 @@ proc writeValue*(writer: var JsonWriter, value: PubKey0x)
proc readValue*(reader: var JsonReader, value: var PubKey0x)
{.raises: [SerializationError, IOError, Defect].} =
try:
value = PubKey0x reader.readValue(string).hexToByteArray(RawPubKeySize)
value = PubKey0x hexToByteArray(reader.readValue(string), RawPubKeySize)
except ValueError:
raiseUnexpectedValue(reader, "Hex string expected")

View File

@ -10,6 +10,7 @@
import
std/[os, strutils],
confutils,
serialization, json_serialization,
eth/db/[kvstore, kvstore_sqlite3],
../beacon_chain/validators/slashing_protection,
../beacon_chain/spec/digest
@ -21,24 +22,63 @@ type
SlashProtConf = object
db{.desc: "The path to the database .sqlite3 file" .}: string
case cmd {.
command,
desc: "Dump database or restore" .}: SlashProtCmd
of dump, restore:
infile {.argument.}: string
desc: "Dump database to or restore from a slashing interchange file" .}: SlashProtCmd
of dump:
outfile {.argument.}: string
of restore:
infile {.argument.}: string
proc doDump(conf: SlashProtConf) =
let (dir, file) = splitPath(conf.infile)
let (dir, file) = splitPath(conf.db)
# TODO: Make it read-only https://github.com/status-im/nim-eth/issues/312
# TODO: why is sqlite3 always appending .sqlite3 ?
let filetrunc = file.changeFileExt("")
let db = SlashingProtectionDB.loadUnchecked(dir, filetrunc, readOnly = false)
db.exportSlashingInterchange(conf.outfile)
echo "Export finished: '", conf.db, "' into '", conf.outfile, "'"
proc doRestore(conf: SlashProtConf) =
let (dir, file) = splitPath(conf.db)
# TODO: Make it read-only https://github.com/status-im/nim-eth/issues/312
# TODO: why is sqlite3 always appending .sqlite3 ?
let filetrunc = file.changeFileExt("")
var spdir: SPDIR
try:
spdir = JSON.loadFile(conf.infile, SPDIR)
except SerializationError as err:
writeStackTrace()
stderr.write $JSON & " load issue for file \"", conf.infile, "\"\n"
stderr.write err.formatMsg(conf.infile), "\n"
quit 1
# Open DB and handle migration from v1 to v2 if needed
let db = SlashingProtectionDB.init(
genesis_validators_root = Eth2Digest spdir.metadata.genesis_validators_root,
basePath = dir,
dbname = filetrunc,
modes = {kCompleteArchiveV2},
disagreementBehavior = kChooseV2
)
# Now import the slashing interchange file
# Failures mode:
# - siError can only happen with invalid genesis_validators_root which would be caught above
# - siPartial can happen for invalid public keys, slashable blocks, slashable votes
let status = db.inclSPDIR(spdir)
doAssert status in {siSuccess, siPartial}
echo "Import finished: '", conf.infile, "' into '", conf.db, "'"
# TODO: do we mention that v2 MUST be used?
# normally this has always been a hidden option.
when isMainModule:
let conf = SlashProtConf.load()
case conf.cmd:
of dump: conf.doDump()
of restore: doAssert false, "unimplemented"
of restore: conf.doRestore()