Skip to content

Commit 850a228

Browse files
committed
Create database tables for block / blob data sidecar quarantine
Add low-level interface to persist blocks by block root and sidecars by block root + index. Also support deleting junk that's been finalized and deletion of all data associated with a block root. Can pass `db.getQuarantineDB()` into the quarantine to expose the new DB tables while hiding APIs that deal with trusted data, and then use the new `beacon_chain_db_quarantine.nim` APIs to store / fetch / delete.
1 parent ecabeee commit 850a228

6 files changed

+398
-46
lines changed

beacon_chain/beacon_chain_db.nim

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import
2020
forks,
2121
presets,
2222
state_transition],
23-
"."/[beacon_chain_db_light_client, filepath]
23+
"."/[beacon_chain_db_light_client,
24+
beacon_chain_db_quarantine,
25+
db_utils,
26+
filepath]
2427

2528
from ./spec/datatypes/capella import BeaconState
2629
from ./spec/datatypes/deneb import TrustedSignedBeaconBlock
@@ -153,6 +156,10 @@ type
153156
##
154157
## See `summaries` for an index in the other direction.
155158

159+
quarantine: QuarantineDB
160+
## Pending data that passed basic checks including proposer signature
161+
## but that is not fully validated / trusted yet.
162+
156163
lcData: LightClientDataDB
157164
## Persistent light client data to avoid expensive recomputations
158165

@@ -593,6 +600,36 @@ proc new*(T: type BeaconChainDB,
593600
if cfg.FULU_FORK_EPOCH != FAR_FUTURE_EPOCH:
594601
columns = kvStore db.openKvStore("fulu_columns").expectDb()
595602

603+
let quarantine = db.initQuarantineDB(QuarantineDBNames(
604+
# TODO Set these to non-empty string to actually use them
605+
# once we have a new quarantine implemented. If empty string is used,
606+
# no database table is created!
607+
phase0Blocks:
608+
"", # "blocks_quarantine"
609+
altairBlocks:
610+
"", # "altair_blocks_quarantine"
611+
bellatrixBlocks:
612+
"", # "bellatrix_blocks_quarantine"
613+
capellaBlocks:
614+
"", # "capella_blocks_quarantine"
615+
denebBlocks:
616+
"", # "deneb_blocks_quarantine"
617+
electraBlocks:
618+
"", # "electra_blocks_quarantine"
619+
fuluBlocks:
620+
if cfg.FULU_FORK_EPOCH != FAR_FUTURE_EPOCH:
621+
"" # "fulu_blocks_quarantine"
622+
else:
623+
"",
624+
denebDataSidecars:
625+
"", # "deneb_blobs_quarantine"
626+
fuluDataSidecars:
627+
if cfg.FULU_FORK_EPOCH != FAR_FUTURE_EPOCH:
628+
"" # "fulu_columns_quarantine"
629+
else:
630+
"")).expectDb()
631+
static: doAssert ConsensusFork.high == ConsensusFork.Fulu
632+
596633
# Versions prior to 1.4.0 (altair) stored validators in `immutable_validators`
597634
# which stores validator keys in compressed format - this is
598635
# slow to load and has been superceded by `immutable_validators2` which uses
@@ -634,6 +671,7 @@ proc new*(T: type BeaconChainDB,
634671
stateDiffs: stateDiffs,
635672
summaries: summaries,
636673
finalizedBlocks: finalizedBlocks,
674+
quarantine: quarantine,
637675
lcData: lcData
638676
)
639677

@@ -657,6 +695,9 @@ proc new*(T: type BeaconChainDB,
657695
dir, "nbc", readOnly = readOnly, manualCheckpoint = true).expectDb()
658696
BeaconChainDB.new(db, cfg)
659697

698+
template getQuarantineDB*(db: BeaconChainDB): QuarantineDB =
699+
db.quarantine
700+
660701
template getLightClientDataDB*(db: BeaconChainDB): LightClientDataDB =
661702
db.lcData
662703

@@ -683,18 +724,6 @@ proc decodeSnappySSZ[T](data: openArray[byte], output: var T): bool =
683724
err = e.msg, typ = name(T), dataLen = data.len
684725
false
685726

686-
proc decodeSZSSZ[T](data: openArray[byte], output: var T): bool =
687-
try:
688-
let decompressed = decodeFramed(data, checkIntegrity = false)
689-
readSszBytes(decompressed, output, updateRoot = false)
690-
true
691-
except CatchableError as e:
692-
# If the data can't be deserialized, it could be because it's from a
693-
# version of the software that uses a different SSZ encoding
694-
warn "Unable to deserialize data, old database?",
695-
err = e.msg, typ = name(T), dataLen = data.len
696-
false
697-
698727
func encodeSSZ*(v: auto): seq[byte] =
699728
try:
700729
SSZ.encode(v)
@@ -708,14 +737,6 @@ func encodeSnappySSZ(v: auto): seq[byte] =
708737
# In-memory encode shouldn't fail!
709738
raiseAssert err.msg
710739

711-
func encodeSZSSZ(v: auto): seq[byte] =
712-
# https://github.com/google/snappy/blob/main/framing_format.txt
713-
try:
714-
encodeFramed(SSZ.encode(v))
715-
except CatchableError as err:
716-
# In-memory encode shouldn't fail!
717-
raiseAssert err.msg
718-
719740
proc getRaw(db: KvStoreRef, key: openArray[byte], T: type Eth2Digest): Opt[T] =
720741
var res: Opt[T]
721742
proc decode(data: openArray[byte]) =
@@ -796,6 +817,7 @@ proc close*(db: BeaconChainDB) =
796817
if db.db == nil: return
797818

798819
# Close things roughly in reverse order
820+
db.quarantine.close()
799821
if not isNil(db.columns):
800822
discard db.columns.close()
801823
if not isNil(db.blobs):
@@ -1131,7 +1153,7 @@ proc getBlobSidecar*(db: BeaconChainDB, root: Eth2Digest, index: BlobIndex,
11311153
value: var BlobSidecar): bool =
11321154
db.blobs.getSZSSZ(blobkey(root, index), value) == GetResult.found
11331155

1134-
proc getDataColumnSidecarSZ*(db: BeaconChainDB, root: Eth2Digest,
1156+
proc getDataColumnSidecarSZ*(db: BeaconChainDB, root: Eth2Digest,
11351157
index: ColumnIndex, data: var seq[byte]): bool =
11361158
let dataPtr = addr data # Short-lived
11371159
func decode(data: openArray[byte]) =

beacon_chain/beacon_chain_db_light_client.nim

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import
1515
# Beacon chain internals
1616
spec/datatypes/altair,
1717
spec/[eth2_ssz_serialization, helpers],
18-
./db_limits
18+
./db_utils
1919

2020
logScope: topics = "lcdata"
2121

@@ -172,11 +172,6 @@ type
172172
## Tracks the finalized sync committee periods for which complete data
173173
## has been imported (from `dag.tail.slot`).
174174

175-
template disposeSafe(s: untyped): untyped =
176-
if distinctBase(s) != nil:
177-
s.dispose()
178-
s = typeof(s)(nil)
179-
180175
proc initHeadersStore(
181176
backend: SqStoreRef,
182177
name, typeName: string): KvResult[LightClientHeaderStore] =

0 commit comments

Comments
 (0)