Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge LC db into main BN db #3832

Merged
merged 2 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion beacon_chain/beacon_chain_db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import
./networking/network_metadata, ./beacon_chain_db_immutable,
./spec/[eth2_ssz_serialization, eth2_merkleization, forks, state_transition],
./spec/datatypes/[phase0, altair, bellatrix],
./filepath
"."/[beacon_chain_db_light_client, filepath]

export
phase0, altair, eth2_ssz_serialization, eth2_merkleization, kvstore,
Expand Down Expand Up @@ -145,6 +145,9 @@ type
##
## See `summaries` for an index in the other direction.

lcData: LightClientDataDB
## Persistent light client data to avoid expensive recomputations

DbKeyKind = enum
kHashToState
kHashToBlock
Expand Down Expand Up @@ -458,6 +461,11 @@ proc new*(T: type BeaconChainDB,
summaries = kvStore db.openKvStore("beacon_block_summaries", true).expectDb()
finalizedBlocks = FinalizedBlocks.init(db, "finalized_blocks").expectDb()

lcData = db.initLightClientDataDB(LightClientDataDBNames(
altairCurrentBranches: "lc_altair_current_branches",
altairBestUpdates: "lc_altair_best_updates",
sealedPeriods: "lc_sealed_periods")).expectDb()

# Versions prior to 1.4.0 (altair) stored validators in `immutable_validators`
# which stores validator keys in compressed format - this is
# slow to load and has been superceded by `immutable_validators2` which uses
Expand Down Expand Up @@ -499,8 +507,12 @@ proc new*(T: type BeaconChainDB,
stateDiffs: stateDiffs,
summaries: summaries,
finalizedBlocks: finalizedBlocks,
lcData: lcData
)

template getLightClientDataDB*(db: BeaconChainDB): LightClientDataDB =
db.lcData

proc decodeSSZ[T](data: openArray[byte], output: var T): bool =
try:
readSszBytes(data, output, updateRoot = false)
Expand Down Expand Up @@ -637,6 +649,7 @@ proc close*(db: BeaconChainDB) =
if db.db == nil: return

# Close things roughly in reverse order
db.lcData.close()
db.finalizedBlocks.close()
discard db.summaries.close()
discard db.stateDiffs.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type
delFromStmt: SqliteStmt[int64, void]
keepFromStmt: SqliteStmt[int64, void]

LightClientDataDB* = object
LightClientDataDB* = ref object
backend: SqStoreRef
## SQLite backend

Expand All @@ -92,42 +92,49 @@ template isSupportedBySQLite(slot: Slot): bool =
template isSupportedBySQLite(period: SyncCommitteePeriod): bool =
period <= int64.high.SyncCommitteePeriod

proc initCurrentSyncCommitteeBranchStore(
backend: SqStoreRef): KvResult[CurrentSyncCommitteeBranchStore] =
proc initCurrentBranchesStore(
backend: SqStoreRef,
name: string): KvResult[CurrentSyncCommitteeBranchStore] =
? backend.exec("""
CREATE TABLE IF NOT EXISTS `altair_current_sync_committee_branches` (
CREATE TABLE IF NOT EXISTS `""" & name & """` (
`slot` INTEGER PRIMARY KEY, -- `Slot` (up through 2^63-1)
`branch` BLOB -- `altair.CurrentSyncCommitteeBranch` (SSZ)
);
""")

let
containsStmt = ? backend.prepareStmt("""
containsStmt = backend.prepareStmt("""
SELECT 1 AS `exists`
FROM `altair_current_sync_committee_branches`
FROM `""" & name & """`
WHERE `slot` = ?;
""", int64, int64)
getStmt = ? backend.prepareStmt("""
""", int64, int64, managed = false).expect("SQL query OK")
getStmt = backend.prepareStmt("""
SELECT `branch`
FROM `altair_current_sync_committee_branches`
FROM `""" & name & """`
WHERE `slot` = ?;
""", int64, seq[byte])
putStmt = ? backend.prepareStmt("""
INSERT INTO `altair_current_sync_committee_branches` (
""", int64, seq[byte], managed = false).expect("SQL query OK")
putStmt = backend.prepareStmt("""
INSERT INTO `""" & name & """` (
`slot`, `branch`
) VALUES (?, ?);
""", (int64, seq[byte]), void)
keepFromStmt = ? backend.prepareStmt("""
DELETE FROM `altair_current_sync_committee_branches`
""", (int64, seq[byte]), void, managed = false).expect("SQL query OK")
keepFromStmt = backend.prepareStmt("""
DELETE FROM `""" & name & """`
WHERE `slot` < ?;
""", int64, void)
""", int64, void, managed = false).expect("SQL query OK")

ok CurrentSyncCommitteeBranchStore(
containsStmt: containsStmt,
getStmt: getStmt,
putStmt: putStmt,
keepFromStmt: keepFromStmt)

func close(store: CurrentSyncCommitteeBranchStore) =
store.containsStmt.dispose()
store.getStmt.dispose()
store.putStmt.dispose()
store.keepFromStmt.dispose()

func hasCurrentSyncCommitteeBranch*(
db: LightClientDataDB, slot: Slot): bool =
if not slot.isSupportedBySQLite:
Expand Down Expand Up @@ -161,38 +168,39 @@ func putCurrentSyncCommitteeBranch*(
let res = db.currentBranches.putStmt.exec((slot.int64, SSZ.encode(branch)))
res.expect("SQL query OK")

proc initBestUpdateStore(
backend: SqStoreRef): KvResult[BestLightClientUpdateStore] =
proc initBestUpdatesStore(
backend: SqStoreRef,
name: string): KvResult[BestLightClientUpdateStore] =
? backend.exec("""
CREATE TABLE IF NOT EXISTS `altair_best_updates` (
CREATE TABLE IF NOT EXISTS `""" & name & """` (
`period` INTEGER PRIMARY KEY, -- `SyncCommitteePeriod`
`update` BLOB -- `altair.LightClientUpdate` (SSZ)
);
""")

let
getStmt = ? backend.prepareStmt("""
getStmt = backend.prepareStmt("""
SELECT `update`
FROM `altair_best_updates`
FROM `""" & name & """`
WHERE `period` = ?;
""", int64, seq[byte])
putStmt = ? backend.prepareStmt("""
REPLACE INTO `altair_best_updates` (
""", int64, seq[byte], managed = false).expect("SQL query OK")
putStmt = backend.prepareStmt("""
REPLACE INTO `""" & name & """` (
`period`, `update`
) VALUES (?, ?);
""", (int64, seq[byte]), void)
delStmt = ? backend.prepareStmt("""
DELETE FROM `altair_best_updates`
""", (int64, seq[byte]), void, managed = false).expect("SQL query OK")
delStmt = backend.prepareStmt("""
DELETE FROM `""" & name & """`
WHERE `period` = ?;
""", int64, void)
delFromStmt = ? backend.prepareStmt("""
DELETE FROM `altair_best_updates`
""", int64, void, managed = false).expect("SQL query OK")
delFromStmt = backend.prepareStmt("""
DELETE FROM `""" & name & """`
WHERE `period` >= ?;
""", int64, void)
keepFromStmt = ? backend.prepareStmt("""
DELETE FROM `altair_best_updates`
""", int64, void, managed = false).expect("SQL query OK")
keepFromStmt = backend.prepareStmt("""
DELETE FROM `""" & name & """`
WHERE `period` < ?;
""", int64, void)
""", int64, void, managed = false).expect("SQL query OK")

ok BestLightClientUpdateStore(
getStmt: getStmt,
Expand All @@ -201,6 +209,13 @@ proc initBestUpdateStore(
delFromStmt: delFromStmt,
keepFromStmt: keepFromStmt)

func close(store: BestLightClientUpdateStore) =
store.getStmt.dispose()
store.putStmt.dispose()
store.delStmt.dispose()
store.delFromStmt.dispose()
store.keepFromStmt.dispose()

proc getBestUpdate*(
db: LightClientDataDB, period: SyncCommitteePeriod
): altair.LightClientUpdate =
Expand Down Expand Up @@ -235,40 +250,47 @@ proc putUpdateIfBetter*(
if is_better_update(update, existing):
db.putBestUpdate(period, update)

proc initSealedPeriodStore(
backend: SqStoreRef): KvResult[SealedSyncCommitteePeriodStore] =
proc initSealedPeriodsStore(
backend: SqStoreRef,
name: string): KvResult[SealedSyncCommitteePeriodStore] =
? backend.exec("""
CREATE TABLE IF NOT EXISTS `sealed_sync_committee_periods` (
CREATE TABLE IF NOT EXISTS `""" & name & """` (
`period` INTEGER PRIMARY KEY -- `SyncCommitteePeriod`
);
""")

let
containsStmt = ? backend.prepareStmt("""
containsStmt = backend.prepareStmt("""
SELECT 1 AS `exists`
FROM `sealed_sync_committee_periods`
FROM `""" & name & """`
WHERE `period` = ?;
""", int64, int64)
putStmt = ? backend.prepareStmt("""
INSERT INTO `sealed_sync_committee_periods` (
""", int64, int64, managed = false).expect("SQL query OK")
putStmt = backend.prepareStmt("""
INSERT INTO `""" & name & """` (
`period`
) VALUES (?);
""", int64, void)
delFromStmt = ? backend.prepareStmt("""
DELETE FROM `sealed_sync_committee_periods`
""", int64, void, managed = false).expect("SQL query OK")
delFromStmt = backend.prepareStmt("""
DELETE FROM `""" & name & """`
WHERE `period` >= ?;
""", int64, void)
keepFromStmt = ? backend.prepareStmt("""
DELETE FROM `sealed_sync_committee_periods`
""", int64, void, managed = false).expect("SQL query OK")
keepFromStmt = backend.prepareStmt("""
DELETE FROM `""" & name & """`
WHERE `period` < ?;
""", int64, void)
""", int64, void, managed = false).expect("SQL query OK")

ok SealedSyncCommitteePeriodStore(
containsStmt: containsStmt,
putStmt: putStmt,
delFromStmt: delFromStmt,
keepFromStmt: keepFromStmt)

func close(store: SealedSyncCommitteePeriodStore) =
store.containsStmt.dispose()
store.putStmt.dispose()
store.delFromStmt.dispose()
store.keepFromStmt.dispose()

func isPeriodSealed*(
db: LightClientDataDB, period: SyncCommitteePeriod): bool =
doAssert period.isSupportedBySQLite
Expand Down Expand Up @@ -305,44 +327,31 @@ func keepPeriodsFrom*(
res3 = db.currentBranches.keepFromStmt.exec(minSlot.int64)
res3.expect("SQL query OK")

type LightClientDataDBNames* = object
altairCurrentBranches*: string
altairBestUpdates*: string
sealedPeriods*: string

proc initLightClientDataDB*(
dir: string, inMemory = false): Opt[LightClientDataDB] =
logScope:
path = dir
inMemory

if not inMemory:
let res = secureCreatePath(dir)
if res.isErr:
warn "Failed to create DB directory", err = ioErrorMsg(res.error)
return err()

const dbName = "lcdataV1"
backend: SqStoreRef,
names: LightClientDataDBNames): KvResult[LightClientDataDB] =
let
backend = SqStoreRef.init(dir, dbName, inMemory = inMemory).valueOr:
warn "Failed to create LC data DB", err = error
return err()

currentBranches = backend.initCurrentSyncCommitteeBranchStore().valueOr:
warn "Failed to init LC store", store = "currentBranches", err = error
backend.close()
return err()
bestUpdates = backend.initBestUpdateStore().valueOr:
warn "Failed to init LC store", store = "bestUpdates", err = error
backend.close()
return err()
sealedPeriods = backend.initSealedPeriodStore().valueOr:
warn "Failed to init LC store", store = "sealedPeriods", err = error
backend.close()
return err()
currentBranches =
? backend.initCurrentBranchesStore(names.altairCurrentBranches)
bestUpdates =
? backend.initBestUpdatesStore(names.altairBestUpdates)
sealedPeriods =
? backend.initSealedPeriodsStore(names.sealedPeriods)

ok LightClientDataDB(
backend: backend,
currentBranches: currentBranches,
bestUpdates: bestUpdates,
sealedPeriods: sealedPeriods)

proc close*(db: var LightClientDataDB) =
proc close*(db: LightClientDataDB) =
if db.backend != nil:
db.backend.close()
db.reset()
db.currentBranches.close()
db.bestUpdates.close()
db.sealedPeriods.close()
db[].reset()
3 changes: 0 additions & 3 deletions beacon_chain/conf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1056,9 +1056,6 @@ func outWalletFile*(config: BeaconNodeConf): Option[OutFile] =
func databaseDir*(config: AnyConf): string =
config.dataDir / "db"

func cachesDir*(config: AnyConf): string =
config.databaseDir / "caches"

func runAsService*(config: BeaconNodeConf): bool =
config.cmd == noCommand and config.runAsServiceFlag

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import
stew/bitops2,
# Beacon chain internals
../spec/datatypes/altair,
../light_client_data_db,
../beacon_chain_db_light_client,
./block_dag

type
Expand Down Expand Up @@ -64,8 +64,6 @@ type
## The earliest slot for which light client data is imported.

LightClientDataConfig* = object
dbDir*: Option[string]
## Directory to store light client data DB in
serve*: bool
## Whether to make local light client data available or not
importMode*: LightClientDataImportMode
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/consensus_object_pools/blockchain_dag.nim
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ proc updateBeaconMetrics(
import blockchain_dag_light_client

export
blockchain_dag_light_client.closeLightClientDataStore,
blockchain_dag_light_client.getLightClientBootstrap,
blockchain_dag_light_client.getLightClientUpdateForPeriod,
blockchain_dag_light_client.getLightClientFinalityUpdate,
Expand Down Expand Up @@ -723,7 +722,8 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,

vanityLogs: vanityLogs,

lcDataStore: initLightClientDataStore(lcDataConfig, cfg),
lcDataStore: initLightClientDataStore(
lcDataConfig, cfg, db.getLightClientDataDB()),

onBlockAdded: onBlockCb,
onHeadChanged: onHeadCb,
Expand Down
Loading