From ed7865b4e5946456d97dfcc356c53db60f022251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mamy=20Andr=C3=A9-Ratsimbazafy?= Date: Tue, 26 Jan 2021 17:23:13 +0100 Subject: [PATCH] Make stuff compile after rebase. Once again the generic sandwich rears it's ugly head https://github.com/nim-lang/Nim/issues/11225 --- .../slashing_protection.nim | 25 ++++++++++++++++++- .../slashing_protection_types.nim | 6 ++--- .../slashing_protection_v1.nim | 21 +++++++++++++++- .../slashing_protection_v2.nim | 5 +++- ncli/ncli_slashing.nim | 2 +- .../test_slashing_interchange.nim | 12 ++++----- 6 files changed, 58 insertions(+), 13 deletions(-) diff --git a/beacon_chain/validator_protection/slashing_protection.nim b/beacon_chain/validator_protection/slashing_protection.nim index 80f84fad72..10b3ad2bf0 100644 --- a/beacon_chain/validator_protection/slashing_protection.nim +++ b/beacon_chain/validator_protection/slashing_protection.nim @@ -6,6 +6,8 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. import + # stdlib + std/os, # Status eth/db/[kvstore, kvstore_sqlite3], stew/results, chronicles, @@ -16,6 +18,8 @@ import ./slashing_protection_v2 export slashing_protection_types +# Generic sandwich +export chronicles # The high-level slashing protection DB # ------------------------------------- @@ -84,6 +88,7 @@ proc init*( kCompleteArchiveV2 in modes and kLowWatermarkV2 in modes), "Mode(s): " & $modes & ". Choose only one of V2 DB modes." + new result result.modes = modes result.disagreementBehavior = disagreementBehavior @@ -92,7 +97,12 @@ proc init*( basePath, dbname ) - result.db_v1.fromRawDB(kvstore result.db_v2.getRawDBHandle()) + let rawdb = kvstore result.db_v2.getRawDBHandle() + if not rawdb.checkOrPutGenesis_DbV1(genesis_validator_root): + fatal "The slashing database refers to another chain/mainnet/testnet", + path = basePath/dbname, + genesis_validator_root = genesis_validator_root + result.db_v1.fromRawDB(rawdb) proc init*( T: type SlashingProtectionDB, @@ -318,7 +328,20 @@ proc inclSPDIR*(db: SlashingProtectionDB, spdir: SPDIR): bool doAssert useV1 return db.db_v1.inclSPDIR(spdir) +# The high-level import/export functions are +# - importSlashingInterchange +# - exportSlashingInterchange +# in slashing_protection_types.nim +# +# That builds on a DB backend inclSPDIR and toSPDIR +# SPDIR being a common Intermediate Representation + # Sanity check # -------------------------------------------------------------- +proc foo(x: SlashingProtectionDB_Concept) = + discard + +foo(SlashingProtectionDB()) {.explain.} + static: doAssert SlashingProtectionDB is SlashingProtectionDB_Concept diff --git a/beacon_chain/validator_protection/slashing_protection_types.nim b/beacon_chain/validator_protection/slashing_protection_types.nim index 8dd1e04a4a..9e8a729df8 100644 --- a/beacon_chain/validator_protection/slashing_protection_types.nim +++ b/beacon_chain/validator_protection/slashing_protection_types.nim @@ -7,7 +7,7 @@ import # Stdlib - std/typetraits, + std/[typetraits, strutils], # Status eth/db/[kvstore, kvstore_sqlite3], stew/results, @@ -201,7 +201,7 @@ proc readValue*(r: var JsonReader, a: var (SlotString or EpochString)) {.raises: [SerializationError, IOError, ValueError, Defect].} = a = (typeof a)(r.readValue(string).parseBiggestUint()) -proc exportInterchangeFormat*( +proc exportSlashingInterchange*( db: SlashingProtectionDB_Concept, path: string, prettify = true) = ## Export a database to the Slashing Protection Database Interchange Format @@ -209,7 +209,7 @@ proc exportInterchangeFormat*( Json.saveFile(path, spdir, prettify) echo "Exported slashing protection DB to '", path, "'" -proc inclInterchangeData*( +proc importSlashingInterchange*( db: SlashingProtectionDB_Concept, path: string): bool = ## Import a Slashing Protection Database Interchange Format diff --git a/beacon_chain/validator_protection/slashing_protection_v1.nim b/beacon_chain/validator_protection/slashing_protection_v1.nim index 7bb08c1b0b..9a21d6673c 100644 --- a/beacon_chain/validator_protection/slashing_protection_v1.nim +++ b/beacon_chain/validator_protection/slashing_protection_v1.nim @@ -326,8 +326,24 @@ proc setGenesis(db: SlashingProtectionDB_v1, genesis_validator_root: Eth2Digest) func version*(_: type SlashingProtectionDB_v1): static int = 1 +proc checkOrPutGenesis_DbV1*(rawdb: KvStoreRef, genesis_validator_root: Eth2Digest): bool = + if rawdb.contains( + subkey(kGenesisValidatorRoot) + ).get(): + return genesis_validator_root == rawdb.rawGet( + subkey(kGenesisValidatorRoot), + Eth2Digest + ).get() + else: + rawdb.put( + subkey(kGenesisValidatorRoot), + genesis_validator_root.data + ).expect("working database") + return true + proc fromRawDB*(dst: var SlashingProtectionDB_v1, rawdb: KvStoreRef) = ## Initialize a SlashingProtectionDB_v1 from a raw DB + ## For first instantiation, do not forget to call setGenesis doAssert rawdb.contains( subkey(kGenesisValidatorRoot) ).get(), "The Slashing DB is missing genesis information" @@ -342,7 +358,10 @@ proc init*( genesis_validator_root: Eth2Digest, basePath, dbname: string): T = result = T(backend: kvStore SqStoreRef.init(basePath, dbname).get()) - result.setGenesis(genesis_validator_root) + if not result.backend.checkOrPutGenesis_DbV1(genesis_validator_root): + fatal "The slashing database refers to another chain/mainnet/testnet", + path = basePath/dbname, + genesis_validator_root = genesis_validator_root proc loadUnchecked*( T: type SlashingProtectionDB_v1, diff --git a/beacon_chain/validator_protection/slashing_protection_v2.nim b/beacon_chain/validator_protection/slashing_protection_v2.nim index e89de52cab..e7ac97fbfa 100644 --- a/beacon_chain/validator_protection/slashing_protection_v2.nim +++ b/beacon_chain/validator_protection/slashing_protection_v2.nim @@ -451,7 +451,10 @@ proc initCompatV1*(T: type SlashingProtectionDB_v2, let alreadyExists = fileExists(basepath/dbname&".sqlite3") - result = T(backend: SqStoreRef.init(basePath, dbname, keyspaces = ["kvstore"]).get()) + result = T(backend: SqStoreRef.init( + basePath, dbname, + keyspaces = ["kvstore"] # The key compat part + ).get()) if alreadyExists: result.checkDB(genesis_validator_root) else: diff --git a/ncli/ncli_slashing.nim b/ncli/ncli_slashing.nim index 2c14f37596..351b96068a 100644 --- a/ncli/ncli_slashing.nim +++ b/ncli/ncli_slashing.nim @@ -34,7 +34,7 @@ proc doDump(conf: SlashProtConf) = # TODO: why is sqlite3 always appending .sqlite3 ? let filetrunc = file.changeFileExt("") let db = SlashingProtectionDB.loadUnchecked(dir, filetrunc, readOnly = false) - db.exportInterchangeFormat(conf.outfile) + db.exportSlashingInterchange(conf.outfile) when isMainModule: let conf = SlashProtConf.load() diff --git a/tests/slashing_protection/test_slashing_interchange.nim b/tests/slashing_protection/test_slashing_interchange.nim index 1427b98286..bc4da24f27 100644 --- a/tests/slashing_protection/test_slashing_interchange.nim +++ b/tests/slashing_protection/test_slashing_interchange.nim @@ -94,7 +94,7 @@ suiteReport "Slashing Protection DB - Interchange" & preset(): fakeRoot(65535) ) - db.toSPDIF(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") + db.exportSlashingInterchange(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") block: # import - zero root db let db2 = SlashingProtectionDB.init( @@ -106,8 +106,8 @@ suiteReport "Slashing Protection DB - Interchange" & preset(): db2.close() sqlite3db_delete(TestDir, TestDbName) - doAssert db2.fromSPDIF(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") - db2.toSPDIF(currentSourcePath.parentDir/"test_complete_export_slashing_protection_roundtrip1.json") + doAssert db2.importSlashingInterchange(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") + db2.exportSlashingInterchange(currentSourcePath.parentDir/"test_complete_export_slashing_protection_roundtrip1.json") block: # import - same root db let db3 = SlashingProtectionDB.init( @@ -119,8 +119,8 @@ suiteReport "Slashing Protection DB - Interchange" & preset(): db3.close() sqlite3db_delete(TestDir, TestDbName) - doAssert db3.fromSPDIF(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") - db3.toSPDIF(currentSourcePath.parentDir/"test_complete_export_slashing_protection_roundtrip2.json") + doAssert db3.importSlashingInterchange(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") + db3.exportSlashingInterchange(currentSourcePath.parentDir/"test_complete_export_slashing_protection_roundtrip2.json") block: # import - invalid root db let invalid_genvalroot = hexToDigest"0x1234" @@ -133,4 +133,4 @@ suiteReport "Slashing Protection DB - Interchange" & preset(): db4.close() sqlite3db_delete(TestDir, TestDbName) - doAssert not db4.fromSPDIF(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json") + doAssert not db4.importSlashingInterchange(currentSourcePath.parentDir/"test_complete_export_slashing_protection.json")