diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index da4276e63..0597f8b96 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -120,6 +120,13 @@ type desc: "Subscribe to all attestation subnet topics when gossiping" name: "subscribe-all-subnets" }: bool + # Can we use a set[enum]? + testDualSlashingProtectionDBs* {. + hidden + defaultValue: false + desc: "Use the the 2 slashing protection implementation at the same time to ensure no regression." + name: "slashing-test-dual-db" }: bool + case cmd* {. command defaultValue: noCommand }: BNStartUpCmd @@ -664,4 +671,3 @@ func defaultAdminListenAddress*(conf: BeaconNodeConf|ValidatorClientConf): Valid template writeValue*(writer: var JsonWriter, value: TypedInputFile|InputFile|InputDir|OutPath|OutDir|OutFile) = writer.writeValue(string value) - diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index a7a302215..90876595d 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -320,13 +320,24 @@ proc init*(T: type BeaconNode, topics &= getAttestationTopic(enrForkId.forkDigest, subnet) topics) - info "Loading slashing protection database", path = conf.validatorsDir() - res.attachedValidators = ValidatorPool.init( - SlashingProtectionDB.init( - chainDag.headState.data.data.genesis_validators_root, - conf.validatorsDir(), "slashing_protection" + if conf.testDualSlashingProtectionDBs: + info "Loading slashing protection database (dual DB mode)", path = conf.validatorsDir() + res.attachedValidators = ValidatorPool.init( + SlashingProtectionDB.init( + chainDag.headState.data.data.genesis_validators_root, + conf.validatorsDir(), "slashing_protection", + modes = {kCompleteArchiveV1, kCompleteArchiveV2}, + disagreementBehavior = kChooseV2 + ) + ) + else: + info "Loading slashing protection database", path = conf.validatorsDir() + res.attachedValidators = ValidatorPool.init( + SlashingProtectionDB.init( + chainDag.headState.data.data.genesis_validators_root, + conf.validatorsDir(), "slashing_protection" + ) ) - ) proc getWallTime(): BeaconTime = res.beaconClock.now() diff --git a/beacon_chain/validator_protection/slashing_protection.nim b/beacon_chain/validator_protection/slashing_protection.nim index 9f9c70e26..43b58e3e8 100644 --- a/beacon_chain/validator_protection/slashing_protection.nim +++ b/beacon_chain/validator_protection/slashing_protection.nim @@ -67,29 +67,6 @@ func version*(_: type SlashingProtectionDB): static int = # The highest DB version supported 2 -# DB Migration -# ------------------------------------------------------------- - -proc requiresMigrationFromDB_v1(db: SlashingProtectionDB_v2): bool = - ## Migrate a v1 DB to v2. - # Check if we have v2 data: - let rawdb = kvstore db.getRawDBHandle() - - let v1Root = rawdb.getMetadataTable_DbV1() - if v1Root.isNone(): - return false - - let v2Root = db.getMetadataTable_DbV2() - if v2Root.isNone(): - return true - - if v1Root != v2Root: - fatal "Trying to merge-migrate slashing databases from different chains", - v1Root = shortLog(v1Root.get()), - v2Root = shortLog(v2Root.get()) - quit 1 - return true - # Resource Management # ------------------------------------------------------------- @@ -113,12 +90,11 @@ proc init*( result.modes = modes result.disagreementBehavior = disagreementBehavior - result.db_v2 = SlashingProtectionDB_v2.initCompatV1( + let (db, requiresMigration) = SlashingProtectionDB_v2.initCompatV1( genesis_validators_root, basePath, dbname ) - - let requiresMigration = result.db_v2.requiresMigrationFromDB_v1() + result.db_v2 = db let rawdb = kvstore result.db_v2.getRawDBHandle() if not rawdb.checkOrPutGenesis_DbV1(genesis_validators_root): @@ -433,10 +409,4 @@ proc inclSPDIR*(db: SlashingProtectionDB, spdir: SPDIR): SlashingImportStatus # Sanity check # -------------------------------------------------------------- -proc foo(db: SlashingProtectionDB_Concept) = - discard - -var x: SlashingProtectionDB -foo(x) {.explain.} - static: doAssert SlashingProtectionDB is SlashingProtectionDB_Concept diff --git a/beacon_chain/validator_protection/slashing_protection_v2.nim b/beacon_chain/validator_protection/slashing_protection_v2.nim index b36f7afdf..68cb9eabc 100644 --- a/beacon_chain/validator_protection/slashing_protection_v2.nim +++ b/beacon_chain/validator_protection/slashing_protection_v2.nim @@ -594,24 +594,30 @@ proc getMetadataTable_DbV2*(db: SlashingProtectionDB_v2): Option[Eth2Digest] = proc initCompatV1*(T: type SlashingProtectionDB_v2, genesis_validators_root: Eth2Digest, basePath: string, - dbname: string): T = + dbname: string + ): tuple[db: SlashingProtectionDB_v2, requiresMigration: bool] = ## Initialize a new slashing protection database ## or load an existing one with matching genesis root ## `dbname` MUST not be ending with .sqlite3 let alreadyExists = fileExists(basepath/dbname&".sqlite3") - result = T(backend: SqStoreRef.init( + result.db = T(backend: SqStoreRef.init( basePath, dbname, keyspaces = ["kvstore"] # The key compat part ).get()) - if alreadyExists and result.getMetadataTable_DbV2().isSome(): - result.checkDB(genesis_validators_root) + if alreadyExists and result.db.getMetadataTable_DbV2().isSome(): + result.db.checkDB(genesis_validators_root) + result.requiresMigration = false + elif alreadyExists: + result.db.setupDB(genesis_validators_root) + result.requiresMigration = true else: - result.setupDB(genesis_validators_root) + result.db.setupDB(genesis_validators_root) + result.requiresMigration = false # Cached queries - result.setupCachedQueries() + result.db.setupCachedQueries() # Resource Management # -------------------------------------------------------------