@lodestar/beacon-node 1.48.0-dev.a0619b279a → 1.48.0-dev.a427d3dbb5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +0 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +0 -2
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +1 -4
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +34 -31
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +16 -9
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +1 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +24 -47
- package/lib/chain/chain.js.map +1 -1
- package/lib/db/beacon.d.ts +5 -14
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +3 -17
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/index.d.ts +0 -1
- package/lib/db/index.d.ts.map +1 -1
- package/lib/db/interface.d.ts +1 -8
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.d.ts +1 -8
- package/lib/db/repositories/blockArchive.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.js +28 -65
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.js +7 -3
- package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +0 -18
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +1 -55
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/monitoring/clientStats.js +1 -1
- package/lib/monitoring/clientStats.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +1 -0
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +91 -112
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +0 -2
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts +1 -2
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js +9 -14
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
- package/lib/node/nodejs.d.ts +1 -2
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +2 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/util/sszBytes.d.ts +0 -6
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +1 -1
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +18 -17
- package/src/chain/archiveStore/archiveStore.ts +1 -6
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +0 -1
- package/src/chain/archiveStore/historicalState/types.ts +0 -2
- package/src/chain/archiveStore/historicalState/worker.ts +1 -4
- package/src/chain/archiveStore/utils/archiveBlocks.ts +39 -34
- package/src/chain/blocks/writeBlockInputToDb.ts +17 -10
- package/src/chain/chain.ts +23 -53
- package/src/db/beacon.ts +6 -33
- package/src/db/index.ts +0 -1
- package/src/db/interface.ts +1 -9
- package/src/db/repositories/blockArchive.ts +30 -89
- package/src/db/repositories/blockArchiveIndex.ts +9 -4
- package/src/metrics/metrics/lodestar.ts +1 -57
- package/src/monitoring/clientStats.ts +1 -1
- package/src/network/gossip/encoding.ts +1 -0
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +105 -139
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +0 -2
- package/src/network/reqresp/utils/dataColumnResponseValidation.ts +7 -15
- package/src/node/nodejs.ts +1 -6
- package/src/util/sszBytes.ts +1 -1
- package/lib/db/dataColumnStore.d.ts +0 -39
- package/lib/db/dataColumnStore.d.ts.map +0 -1
- package/lib/db/dataColumnStore.js +0 -81
- package/lib/db/dataColumnStore.js.map +0 -1
- package/lib/db/flatFileStore/atomicWrite.d.ts +0 -8
- package/lib/db/flatFileStore/atomicWrite.d.ts.map +0 -1
- package/lib/db/flatFileStore/atomicWrite.js +0 -61
- package/lib/db/flatFileStore/atomicWrite.js.map +0 -1
- package/lib/db/flatFileStore/dcolFormat.d.ts +0 -90
- package/lib/db/flatFileStore/dcolFormat.d.ts.map +0 -1
- package/lib/db/flatFileStore/dcolFormat.js +0 -286
- package/lib/db/flatFileStore/dcolFormat.js.map +0 -1
- package/lib/db/flatFileStore/errors.d.ts +0 -82
- package/lib/db/flatFileStore/errors.d.ts.map +0 -1
- package/lib/db/flatFileStore/errors.js +0 -32
- package/lib/db/flatFileStore/errors.js.map +0 -1
- package/lib/db/flatFileStore/flatFileStore.d.ts +0 -41
- package/lib/db/flatFileStore/flatFileStore.d.ts.map +0 -1
- package/lib/db/flatFileStore/flatFileStore.js +0 -251
- package/lib/db/flatFileStore/flatFileStore.js.map +0 -1
- package/lib/db/flatFileStore/index.d.ts +0 -4
- package/lib/db/flatFileStore/index.d.ts.map +0 -1
- package/lib/db/flatFileStore/index.js +0 -2
- package/lib/db/flatFileStore/index.js.map +0 -1
- package/lib/db/flatFileStore/interface.d.ts +0 -25
- package/lib/db/flatFileStore/interface.d.ts.map +0 -1
- package/lib/db/flatFileStore/interface.js +0 -2
- package/lib/db/flatFileStore/interface.js.map +0 -1
- package/lib/db/flatFileStore/metrics.d.ts +0 -24
- package/lib/db/flatFileStore/metrics.d.ts.map +0 -1
- package/lib/db/flatFileStore/metrics.js +0 -25
- package/lib/db/flatFileStore/metrics.js.map +0 -1
- package/lib/db/flatFileStore/path.d.ts +0 -9
- package/lib/db/flatFileStore/path.d.ts.map +0 -1
- package/lib/db/flatFileStore/path.js +0 -21
- package/lib/db/flatFileStore/path.js.map +0 -1
- package/lib/db/flatFileStore/slotIndex.d.ts +0 -14
- package/lib/db/flatFileStore/slotIndex.d.ts.map +0 -1
- package/lib/db/flatFileStore/slotIndex.js +0 -46
- package/lib/db/flatFileStore/slotIndex.js.map +0 -1
- package/lib/db/flatFileStore/snappy.d.ts +0 -3
- package/lib/db/flatFileStore/snappy.d.ts.map +0 -1
- package/lib/db/flatFileStore/snappy.js +0 -12
- package/lib/db/flatFileStore/snappy.js.map +0 -1
- package/src/db/dataColumnStore.ts +0 -113
- package/src/db/flatFileStore/atomicWrite.ts +0 -65
- package/src/db/flatFileStore/dcolFormat.ts +0 -389
- package/src/db/flatFileStore/errors.ts +0 -53
- package/src/db/flatFileStore/flatFileStore.ts +0 -310
- package/src/db/flatFileStore/index.ts +0 -3
- package/src/db/flatFileStore/interface.ts +0 -21
- package/src/db/flatFileStore/metrics.ts +0 -48
- package/src/db/flatFileStore/path.ts +0 -32
- package/src/db/flatFileStore/slotIndex.ts +0 -56
- package/src/db/flatFileStore/snappy.ts +0 -14
|
@@ -134,8 +134,6 @@ export async function archiveBlocks(
|
|
|
134
134
|
logger.verbose("Migrated blobSidecars from hot DB to cold DB", {...logCtx, migratedEntries});
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
// Keep the normal LevelDB hot-to-cold flow for legacy columns. New columns are written
|
|
138
|
-
// directly to flat files, so this only moves fallback data left by older versions.
|
|
139
137
|
if (finalizedPostFulu) {
|
|
140
138
|
const migratedSlots = await migrateDataColumnSidecarsFromHotToColdDb(
|
|
141
139
|
config,
|
|
@@ -144,7 +142,7 @@ export async function archiveBlocks(
|
|
|
144
142
|
finalizedCanonicalBlocks,
|
|
145
143
|
currentEpoch
|
|
146
144
|
);
|
|
147
|
-
logger.verbose("Migrated
|
|
145
|
+
logger.verbose("Migrated dataColumnSidecars from hot DB to cold DB", {
|
|
148
146
|
...logCtx,
|
|
149
147
|
migratedEntries: migratedSlots.length,
|
|
150
148
|
slotRange: prettyPrintIndices(migratedSlots),
|
|
@@ -197,23 +195,6 @@ export async function archiveBlocks(
|
|
|
197
195
|
slotRange: prettyPrintIndices(nonCanonicalSlots),
|
|
198
196
|
};
|
|
199
197
|
|
|
200
|
-
const columnItems = finalizedNonCanonicalBlocks
|
|
201
|
-
// Gloas EMPTY and FULL variants share a block root. EMPTY has no sidecars, so deleting by its root could
|
|
202
|
-
// remove the canonical FULL variant's columns. Pre-Gloas blocks are always FULL.
|
|
203
|
-
.filter(
|
|
204
|
-
(summary) => config.getForkSeq(summary.slot) >= ForkSeq.fulu && summary.payloadStatus === PayloadStatus.FULL
|
|
205
|
-
)
|
|
206
|
-
.map((summary) => ({slot: summary.slot, blockRoot: summary.blockRoot}));
|
|
207
|
-
if (columnItems.length > 0) {
|
|
208
|
-
// Delete sidecars first so their block roots remain available to retry cleanup after a failure or crash.
|
|
209
|
-
await db.dataColumns.deleteMany(columnItems);
|
|
210
|
-
logger.verbose("Deleted non canonical data columns of blocks", {
|
|
211
|
-
...logCtx,
|
|
212
|
-
blocks: columnItems.length,
|
|
213
|
-
slotRange: prettyPrintIndices(columnItems.map(({slot}) => slot).sort((a, b) => a - b)),
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
198
|
await db.block.batchDelete(nonCanonicalBlockRoots);
|
|
218
199
|
logger.verbose("Deleted non canonical blocks from hot DB", nonCanonicalLogCtx);
|
|
219
200
|
|
|
@@ -222,6 +203,11 @@ export async function archiveBlocks(
|
|
|
222
203
|
logger.verbose("Deleted non canonical blobSidecars from hot DB", nonCanonicalLogCtx);
|
|
223
204
|
}
|
|
224
205
|
|
|
206
|
+
if (finalizedPostFulu) {
|
|
207
|
+
await db.dataColumnSidecar.deleteMany(nonCanonicalBlockRoots);
|
|
208
|
+
logger.verbose("Deleted non canonical dataColumnSidecars from hot DB", nonCanonicalLogCtx);
|
|
209
|
+
}
|
|
210
|
+
|
|
225
211
|
if (finalizedPostGloas) {
|
|
226
212
|
await db.executionPayloadEnvelope.batchDelete(nonCanonicalBlockRoots);
|
|
227
213
|
logger.verbose("Deleted non canonical executionPayloadEnvelopes from hot DB", nonCanonicalLogCtx);
|
|
@@ -259,16 +245,23 @@ export async function archiveBlocks(
|
|
|
259
245
|
);
|
|
260
246
|
const dataColumnSidecarsMinEpoch = currentEpoch - dataColumnSidecarsArchiveWindow;
|
|
261
247
|
if (dataColumnSidecarsMinEpoch >= config.FULU_FORK_EPOCH) {
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
248
|
+
const prefixedKeys = await db.dataColumnSidecarArchive.keys({
|
|
249
|
+
// The `id` value `0` refers to the column index. So we want to fetch all sidecars less than zero column of `dataColumnSidecarsMinEpoch`
|
|
250
|
+
lt: {prefix: computeStartSlotAtEpoch(dataColumnSidecarsMinEpoch), id: 0},
|
|
251
|
+
});
|
|
252
|
+
// for each slot there could be multiple dataColumnSidecar, so we need to deduplicate it
|
|
253
|
+
const slotsToDelete = [...new Set(prefixedKeys.map(({prefix}) => prefix))].sort((a, b) => a - b);
|
|
254
|
+
|
|
255
|
+
if (slotsToDelete.length > 0) {
|
|
256
|
+
await db.dataColumnSidecarArchive.deleteMany(slotsToDelete);
|
|
265
257
|
logger.verbose("dataColumnSidecars prune", {
|
|
266
258
|
...logCtx,
|
|
267
|
-
slotRange: prettyPrintIndices(
|
|
268
|
-
numOfSlots:
|
|
259
|
+
slotRange: prettyPrintIndices(slotsToDelete),
|
|
260
|
+
numOfSlots: slotsToDelete.length,
|
|
261
|
+
totalNumOfSidecars: prefixedKeys.length,
|
|
269
262
|
});
|
|
270
263
|
} else {
|
|
271
|
-
logger.verbose(
|
|
264
|
+
logger.verbose(`dataColumnSidecars prune: no entries before epoch ${dataColumnSidecarsMinEpoch}`, logCtx);
|
|
272
265
|
}
|
|
273
266
|
} else {
|
|
274
267
|
logger.verbose(
|
|
@@ -396,6 +389,7 @@ async function migrateBlobSidecarsFromHotToColdDb(
|
|
|
396
389
|
)
|
|
397
390
|
).filter((e): e is KeyValue<Slot, Uint8Array> => e !== null);
|
|
398
391
|
|
|
392
|
+
// put to blockArchive db and delete block db
|
|
399
393
|
await Promise.all([
|
|
400
394
|
db.blobSidecarsArchive.batchPutBinary(canonicalBlobSidecarsEntries),
|
|
401
395
|
db.blobSidecars.batchDelete(canonicalBlocks.map((block) => block.root)),
|
|
@@ -408,9 +402,11 @@ async function migrateBlobSidecarsFromHotToColdDb(
|
|
|
408
402
|
|
|
409
403
|
// TODO: This function can be simplified further by reducing layers of promises in a loop
|
|
410
404
|
/**
|
|
411
|
-
* Post-gloas the data columns of a Gloas block are tied to its execution payload envelope
|
|
412
|
-
*
|
|
413
|
-
* blocks only have a FULL variant, so the
|
|
405
|
+
* Post-gloas the data columns of a Gloas block are tied to its execution payload envelope —
|
|
406
|
+
* columns only exist once the FULL variant of the block is in the proto-array. Pre-Gloas (Fulu)
|
|
407
|
+
* blocks only have a FULL variant, so the `payloadStatus === FULL` filter passes them all.
|
|
408
|
+
* Blocks whose canonical variant is PENDING/EMPTY are skipped here — their columns will be picked
|
|
409
|
+
* up on a later run once the FULL variant appears in the ancestor walk.
|
|
414
410
|
*/
|
|
415
411
|
async function migrateDataColumnSidecarsFromHotToColdDb(
|
|
416
412
|
config: ChainForkConfig,
|
|
@@ -432,24 +428,32 @@ async function migrateDataColumnSidecarsFromHotToColdDb(
|
|
|
432
428
|
if (batch.length === 0) break;
|
|
433
429
|
|
|
434
430
|
const promises: Promise<void>[] = [];
|
|
431
|
+
|
|
432
|
+
// load Buffer instead of ssz deserialized to improve performance
|
|
435
433
|
for (const block of batch) {
|
|
436
|
-
const
|
|
434
|
+
const blockSlot = block.slot;
|
|
435
|
+
const blockEpoch = computeEpochAtSlot(blockSlot);
|
|
436
|
+
|
|
437
437
|
if (
|
|
438
|
-
config.getForkSeq(
|
|
438
|
+
config.getForkSeq(blockSlot) < ForkSeq.fulu ||
|
|
439
|
+
// if block is out of ${config.MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS}, skip this step
|
|
439
440
|
blockEpoch < currentEpoch - config.MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS
|
|
440
441
|
) {
|
|
441
442
|
continue;
|
|
442
443
|
}
|
|
443
444
|
|
|
445
|
+
// Here we assume the data column sidecars are already in the hot db
|
|
444
446
|
const dataColumnSidecarBytes = await fromAsync(db.dataColumnSidecar.valuesStreamBinary(block.root));
|
|
445
447
|
if (dataColumnSidecarBytes.length === 0) {
|
|
448
|
+
// Empty stream: either the block has no blobs, or columns were already archived on a
|
|
449
|
+
// previous run (boundary block). Nothing to migrate.
|
|
446
450
|
logger.debug("DataColumnSidecars in forkchoice but missing in hot db, could be already archived", {
|
|
447
451
|
slot: block.slot,
|
|
448
452
|
root: toRootHex(block.root),
|
|
449
453
|
});
|
|
450
454
|
continue;
|
|
451
455
|
}
|
|
452
|
-
logger.verbose("Migrated
|
|
456
|
+
logger.verbose("Migrated dataColumnSidecars for block", {
|
|
453
457
|
currentEpoch,
|
|
454
458
|
slot: block.slot,
|
|
455
459
|
root: toRootHex(block.root),
|
|
@@ -458,14 +462,15 @@ async function migrateDataColumnSidecarsFromHotToColdDb(
|
|
|
458
462
|
promises.push(
|
|
459
463
|
db.dataColumnSidecarArchive.putManyBinary(
|
|
460
464
|
block.slot,
|
|
461
|
-
dataColumnSidecarBytes.map((
|
|
465
|
+
dataColumnSidecarBytes.map((p) => ({key: p.id, value: p.value}))
|
|
462
466
|
)
|
|
463
467
|
);
|
|
464
468
|
migratedSlots.push(block.slot);
|
|
465
469
|
}
|
|
466
470
|
|
|
471
|
+
promises.push(db.dataColumnSidecar.deleteMany(batch.map((block) => block.root)));
|
|
472
|
+
|
|
467
473
|
await Promise.all(promises);
|
|
468
|
-
await db.dataColumnSidecar.deleteMany(batch.map((block) => block.root));
|
|
469
474
|
}
|
|
470
475
|
|
|
471
476
|
// Ancestor walk is newest to oldest; sort ascending so `prettyPrintIndices` renders cleanly.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {ForkPostDeneb,
|
|
1
|
+
import {ForkPostDeneb, isForkPostDeneb} from "@lodestar/params";
|
|
2
2
|
import {SignedBeaconBlock} from "@lodestar/types";
|
|
3
|
-
import {toRootHex} from "@lodestar/utils";
|
|
3
|
+
import {fromHex, toRootHex} from "@lodestar/utils";
|
|
4
4
|
import {getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
5
5
|
import {BeaconChain} from "../chain.js";
|
|
6
6
|
import {IBlockInput, IDataColumnsInput, isBlockInputBlobs, isBlockInputColumns} from "./blockInput/index.js";
|
|
@@ -76,6 +76,7 @@ async function writeBlockAndBlobsToDb(this: BeaconChain, blockInput: IBlockInput
|
|
|
76
76
|
*/
|
|
77
77
|
export async function writeDataColumnsToDb(this: BeaconChain, blockInput: IDataColumnsInput): Promise<void> {
|
|
78
78
|
const {slot, blockRootHex} = blockInput;
|
|
79
|
+
const blockRoot = fromHex(blockRootHex);
|
|
79
80
|
|
|
80
81
|
if (!blockInput.hasComputedAllData()) {
|
|
81
82
|
// Supernodes may only have a subset of the data columns by the time the block begins to be imported
|
|
@@ -88,19 +89,25 @@ export async function writeDataColumnsToDb(this: BeaconChain, blockInput: IDataC
|
|
|
88
89
|
|
|
89
90
|
const {custodyColumns} = this.custodyConfig;
|
|
90
91
|
const dataColumnSidecars = blockInput.getCustodyColumns();
|
|
91
|
-
const dataColumnSidecarType = this.config.getForkTypes<ForkPostFulu>(slot).DataColumnSidecar;
|
|
92
92
|
|
|
93
|
-
const
|
|
93
|
+
const binaryPuts: {key: number; value: Uint8Array}[] = [];
|
|
94
|
+
const nonbinaryPuts = [];
|
|
94
95
|
for (const dataColumnSidecar of dataColumnSidecars) {
|
|
96
|
+
// skip reserializing column if we already have it
|
|
95
97
|
const serialized = this.serializedCache.get(dataColumnSidecar);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
if (serialized) {
|
|
99
|
+
binaryPuts.push({key: dataColumnSidecar.index, value: serialized});
|
|
100
|
+
} else {
|
|
101
|
+
nonbinaryPuts.push(dataColumnSidecar);
|
|
102
|
+
}
|
|
100
103
|
}
|
|
101
|
-
await this.db.dataColumns.putManyBinary({slot, blockRoot: blockRootHex}, binaryColumns);
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
await Promise.all([
|
|
106
|
+
this.db.dataColumnSidecar.putManyBinary(blockRoot, binaryPuts),
|
|
107
|
+
this.db.dataColumnSidecar.putMany(blockRoot, nonbinaryPuts),
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
this.logger.debug("Persisted dataColumnSidecars to hot DB", {
|
|
104
111
|
slot,
|
|
105
112
|
root: blockRootHex,
|
|
106
113
|
dataColumnSidecars: dataColumnSidecars.length,
|
package/src/chain/chain.ts
CHANGED
|
@@ -268,7 +268,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
268
268
|
db,
|
|
269
269
|
dbName,
|
|
270
270
|
dataDir,
|
|
271
|
-
dataColumnDir,
|
|
272
271
|
logger,
|
|
273
272
|
processShutdownCallback,
|
|
274
273
|
clock,
|
|
@@ -286,7 +285,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
286
285
|
db: IBeaconDb;
|
|
287
286
|
dbName: string;
|
|
288
287
|
dataDir: string;
|
|
289
|
-
dataColumnDir?: string;
|
|
290
288
|
logger: Logger;
|
|
291
289
|
processShutdownCallback: ProcessShutdownCallback;
|
|
292
290
|
/** Used for testing to supply fake clock */
|
|
@@ -507,12 +505,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
507
505
|
|
|
508
506
|
this.archiveStore = new ArchiveStore(
|
|
509
507
|
{db, chain: this, logger: logger as LoggerNode, metrics},
|
|
510
|
-
{
|
|
511
|
-
...opts,
|
|
512
|
-
dbName,
|
|
513
|
-
dataColumnDir: dataColumnDir ?? path.join(dataDir, "data_columns"),
|
|
514
|
-
anchorState: {finalizedCheckpoint: anchorState.finalizedCheckpoint},
|
|
515
|
-
},
|
|
508
|
+
{...opts, dbName, anchorState: {finalizedCheckpoint: anchorState.finalizedCheckpoint}},
|
|
516
509
|
signal
|
|
517
510
|
);
|
|
518
511
|
|
|
@@ -976,15 +969,12 @@ export class BeaconChain implements IBeaconChain {
|
|
|
976
969
|
|
|
977
970
|
async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecar[]> {
|
|
978
971
|
const fork = this.config.getForkName(blockSlot);
|
|
979
|
-
const sidecarsByIndex = new Map<number, DataColumnSidecar>();
|
|
980
972
|
|
|
981
973
|
if (isForkPostGloas(fork)) {
|
|
982
974
|
// After gloas, columns are tracked in PayloadEnvelopeInput
|
|
983
975
|
const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
|
|
984
976
|
if (payloadInput) {
|
|
985
|
-
|
|
986
|
-
sidecarsByIndex.set(sidecar.index, sidecar);
|
|
987
|
-
}
|
|
977
|
+
return payloadInput.getAllColumns();
|
|
988
978
|
}
|
|
989
979
|
} else {
|
|
990
980
|
// Before gloas, columns are tracked in BlockInput
|
|
@@ -993,17 +983,16 @@ export class BeaconChain implements IBeaconChain {
|
|
|
993
983
|
if (!isBlockInputColumns(blockInput)) {
|
|
994
984
|
throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
|
|
995
985
|
}
|
|
996
|
-
|
|
997
|
-
sidecarsByIndex.set(sidecar.index, sidecar);
|
|
998
|
-
}
|
|
986
|
+
return blockInput.getAllColumns();
|
|
999
987
|
}
|
|
1000
988
|
}
|
|
1001
989
|
|
|
1002
|
-
|
|
1003
|
-
|
|
990
|
+
const sidecarsUnfinalized = await this.db.dataColumnSidecar.values(fromHex(blockRootHex));
|
|
991
|
+
if (sidecarsUnfinalized.length > 0) {
|
|
992
|
+
return sidecarsUnfinalized;
|
|
1004
993
|
}
|
|
1005
|
-
|
|
1006
|
-
return
|
|
994
|
+
const sidecarsFinalized = await this.db.dataColumnSidecarArchive.values(blockSlot);
|
|
995
|
+
return sidecarsFinalized;
|
|
1007
996
|
}
|
|
1008
997
|
|
|
1009
998
|
async getSerializedDataColumnSidecars(
|
|
@@ -1012,25 +1001,22 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1012
1001
|
indices: number[]
|
|
1013
1002
|
): Promise<(Uint8Array | undefined)[]> {
|
|
1014
1003
|
const fork = this.config.getForkName(blockSlot);
|
|
1015
|
-
const dataColumnSidecars: (Uint8Array | undefined)[] = indices.map(() => undefined);
|
|
1016
1004
|
|
|
1017
1005
|
if (isForkPostGloas(fork)) {
|
|
1018
1006
|
// After gloas, columns are tracked in PayloadEnvelopeInput
|
|
1019
1007
|
const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
|
|
1020
1008
|
if (payloadInput) {
|
|
1021
|
-
|
|
1022
|
-
const index = indices[i];
|
|
1009
|
+
return indices.map((index) => {
|
|
1023
1010
|
const sidecar = payloadInput.getColumn(index);
|
|
1024
1011
|
if (!sidecar) {
|
|
1025
|
-
|
|
1012
|
+
return undefined;
|
|
1026
1013
|
}
|
|
1027
1014
|
const serialized = this.serializedCache.get(sidecar);
|
|
1028
1015
|
if (serialized) {
|
|
1029
|
-
|
|
1030
|
-
} else {
|
|
1031
|
-
dataColumnSidecars[i] = sszTypesFor(fork as ForkPostGloas).DataColumnSidecar.serialize(sidecar);
|
|
1016
|
+
return serialized;
|
|
1032
1017
|
}
|
|
1033
|
-
|
|
1018
|
+
return sszTypesFor(fork as ForkPostGloas).DataColumnSidecar.serialize(sidecar);
|
|
1019
|
+
});
|
|
1034
1020
|
}
|
|
1035
1021
|
} else {
|
|
1036
1022
|
// Before gloas, columns are tracked in BlockInput
|
|
@@ -1039,42 +1025,26 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1039
1025
|
if (!isBlockInputColumns(blockInput)) {
|
|
1040
1026
|
throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
|
|
1041
1027
|
}
|
|
1042
|
-
|
|
1043
|
-
const index = indices[i];
|
|
1028
|
+
return indices.map((index) => {
|
|
1044
1029
|
const sidecar = blockInput.getColumn(index);
|
|
1045
1030
|
if (!sidecar) {
|
|
1046
|
-
|
|
1031
|
+
return undefined;
|
|
1047
1032
|
}
|
|
1048
1033
|
const serialized = this.serializedCache.get(sidecar);
|
|
1049
1034
|
if (serialized) {
|
|
1050
|
-
|
|
1051
|
-
} else {
|
|
1052
|
-
dataColumnSidecars[i] = sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(
|
|
1053
|
-
sidecar
|
|
1054
|
-
);
|
|
1035
|
+
return serialized;
|
|
1055
1036
|
}
|
|
1056
|
-
|
|
1037
|
+
return sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(sidecar);
|
|
1038
|
+
});
|
|
1057
1039
|
}
|
|
1058
1040
|
}
|
|
1059
1041
|
|
|
1060
|
-
const
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
if (missingPositions.length > 0) {
|
|
1065
|
-
const persistedSidecars = await this.db.dataColumns.getManyBinary(
|
|
1066
|
-
{slot: blockSlot, blockRoot: blockRootHex},
|
|
1067
|
-
missingPositions.map((position) => indices[position])
|
|
1068
|
-
);
|
|
1069
|
-
for (let i = 0; i < missingPositions.length; i++) {
|
|
1070
|
-
const sidecar = persistedSidecars[i];
|
|
1071
|
-
if (sidecar !== undefined) {
|
|
1072
|
-
dataColumnSidecars[missingPositions[i]] = sidecar;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1042
|
+
const sidecarsUnfinalized = await this.db.dataColumnSidecar.getManyBinary(fromHex(blockRootHex), indices);
|
|
1043
|
+
if (sidecarsUnfinalized.some((sidecar) => sidecar != null)) {
|
|
1044
|
+
return sidecarsUnfinalized;
|
|
1075
1045
|
}
|
|
1076
|
-
|
|
1077
|
-
return
|
|
1046
|
+
const sidecarsFinalized = await this.db.dataColumnSidecarArchive.getManyBinary(blockSlot, indices);
|
|
1047
|
+
return sidecarsFinalized;
|
|
1078
1048
|
}
|
|
1079
1049
|
|
|
1080
1050
|
async produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody> {
|
package/src/db/beacon.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {Db, LevelDbControllerMetrics, encodeKey} from "@lodestar/db";
|
|
3
|
-
import {Slot} from "@lodestar/types";
|
|
4
|
-
import {Logger} from "@lodestar/utils";
|
|
5
3
|
import {Bucket} from "./buckets.js";
|
|
6
|
-
import {type IDataColumnStore, LegacyDataColumnStore} from "./dataColumnStore.js";
|
|
7
|
-
import {FlatFileStore} from "./flatFileStore/flatFileStore.js";
|
|
8
|
-
import type {FlatFileStoreMetrics} from "./flatFileStore/metrics.js";
|
|
9
4
|
import {IBeaconDb} from "./interface.js";
|
|
10
5
|
import {CheckpointStateRepository} from "./repositories/checkpointState.js";
|
|
11
6
|
import {
|
|
@@ -29,10 +24,9 @@ import {
|
|
|
29
24
|
VoluntaryExitRepository,
|
|
30
25
|
} from "./repositories/index.js";
|
|
31
26
|
|
|
32
|
-
export type
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
metrics?: FlatFileStoreMetrics | null;
|
|
27
|
+
export type BeaconDbModules = {
|
|
28
|
+
config: ChainForkConfig;
|
|
29
|
+
db: Db;
|
|
36
30
|
};
|
|
37
31
|
|
|
38
32
|
export class BeaconDb implements IBeaconDb {
|
|
@@ -63,14 +57,9 @@ export class BeaconDb implements IBeaconDb {
|
|
|
63
57
|
|
|
64
58
|
backfilledRanges: BackfilledRanges;
|
|
65
59
|
|
|
66
|
-
readonly dataColumns: IDataColumnStore;
|
|
67
|
-
lastLegacyArchiveSlot: Slot | null = null;
|
|
68
|
-
private readonly flatFileStore: FlatFileStore;
|
|
69
|
-
|
|
70
60
|
constructor(
|
|
71
61
|
config: ChainForkConfig,
|
|
72
|
-
protected readonly db: Db
|
|
73
|
-
opts: BeaconDbOpts
|
|
62
|
+
protected readonly db: Db
|
|
74
63
|
) {
|
|
75
64
|
// Warning: If code is ever run in the constructor, must change this stub to not extend 'packages/beacon-node/test/utils/stub/beaconDb.ts' -
|
|
76
65
|
this.block = new BlockRepository(config, db);
|
|
@@ -98,30 +87,14 @@ export class BeaconDb implements IBeaconDb {
|
|
|
98
87
|
this.syncCommitteeWitness = new SyncCommitteeWitnessRepository(config, db);
|
|
99
88
|
|
|
100
89
|
this.backfilledRanges = new BackfilledRanges(config, db);
|
|
101
|
-
|
|
102
|
-
this.flatFileStore = new FlatFileStore(opts.dataColumnDir, config, opts.logger, opts.metrics);
|
|
103
|
-
this.dataColumns = new LegacyDataColumnStore(
|
|
104
|
-
this.flatFileStore,
|
|
105
|
-
this.dataColumnSidecar,
|
|
106
|
-
this.dataColumnSidecarArchive,
|
|
107
|
-
this.blockArchive
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async init(): Promise<void> {
|
|
112
|
-
await this.flatFileStore.init();
|
|
113
|
-
const [lastLegacyKey] = await this.dataColumnSidecarArchive.keys({reverse: true, limit: 1});
|
|
114
|
-
this.lastLegacyArchiveSlot = lastLegacyKey?.prefix ?? null;
|
|
115
90
|
}
|
|
116
91
|
|
|
117
|
-
|
|
118
|
-
await this.flatFileStore.close();
|
|
92
|
+
close(): Promise<void> {
|
|
119
93
|
return this.db.close();
|
|
120
94
|
}
|
|
121
95
|
|
|
122
|
-
setMetrics(metrics: LevelDbControllerMetrics
|
|
96
|
+
setMetrics(metrics: LevelDbControllerMetrics): void {
|
|
123
97
|
this.db.setMetrics(metrics);
|
|
124
|
-
this.flatFileStore.setMetrics(flatFileStoreMetrics);
|
|
125
98
|
}
|
|
126
99
|
|
|
127
100
|
async pruneHotDb(): Promise<void> {
|
package/src/db/index.ts
CHANGED
package/src/db/interface.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import {LevelDbControllerMetrics} from "@lodestar/db";
|
|
2
|
-
import {Slot} from "@lodestar/types";
|
|
3
|
-
import type {IDataColumnStore} from "./dataColumnStore.js";
|
|
4
|
-
import type {FlatFileStoreMetrics} from "./flatFileStore/metrics.js";
|
|
5
2
|
import {CheckpointStateRepository} from "./repositories/checkpointState.js";
|
|
6
3
|
import {
|
|
7
4
|
AttesterSlashingRepository,
|
|
@@ -62,11 +59,6 @@ export interface IBeaconDb {
|
|
|
62
59
|
|
|
63
60
|
backfilledRanges: BackfilledRanges;
|
|
64
61
|
|
|
65
|
-
dataColumns: IDataColumnStore;
|
|
66
|
-
/** Highest legacy column slot at startup; later archival writes the block-root index first. */
|
|
67
|
-
readonly lastLegacyArchiveSlot: Slot | null;
|
|
68
|
-
init(): Promise<void>;
|
|
69
|
-
|
|
70
62
|
pruneHotDb(): Promise<void>;
|
|
71
63
|
|
|
72
64
|
deleteDeprecatedEth1Data(): Promise<void>;
|
|
@@ -74,5 +66,5 @@ export interface IBeaconDb {
|
|
|
74
66
|
/** Close the connection to the db instance and close the db store. */
|
|
75
67
|
close(): Promise<void>;
|
|
76
68
|
/** To inject metrics after CLI initialization */
|
|
77
|
-
setMetrics(metrics: LevelDbControllerMetrics
|
|
69
|
+
setMetrics(metrics: LevelDbControllerMetrics): void;
|
|
78
70
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {Db,
|
|
2
|
+
import {Db, FilterOptions, KeyValue, Repository} from "@lodestar/db";
|
|
3
3
|
import {Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
|
|
4
|
-
import {bytesToInt
|
|
4
|
+
import {bytesToInt} from "@lodestar/utils";
|
|
5
5
|
import {getSignedBlockTypeFromBytes} from "../../util/multifork.js";
|
|
6
6
|
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
7
7
|
import {
|
|
8
8
|
deleteParentRootIndex,
|
|
9
9
|
deleteRootIndex,
|
|
10
10
|
getParentRootIndex,
|
|
11
|
-
getParentRootIndexKey,
|
|
12
11
|
getRootIndex,
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
storeParentRootIndex,
|
|
13
|
+
storeRootIndex,
|
|
15
14
|
} from "./blockArchiveIndex.js";
|
|
16
15
|
|
|
17
16
|
export interface BlockFilterOptions extends FilterOptions<Slot> {
|
|
@@ -57,91 +56,37 @@ export class BlockArchiveRepository extends Repository<Slot, SignedBeaconBlock>
|
|
|
57
56
|
// Overrides to index
|
|
58
57
|
|
|
59
58
|
async put(key: Slot, value: SignedBeaconBlock): Promise<void> {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
key,
|
|
68
|
-
value,
|
|
69
|
-
slot: block.message.slot,
|
|
70
|
-
blockRoot: this.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message),
|
|
71
|
-
parentRoot: block.message.parentRoot,
|
|
72
|
-
},
|
|
59
|
+
const blockRoot = this.config.getForkTypes(value.message.slot).BeaconBlock.hashTreeRoot(value.message);
|
|
60
|
+
const slot = value.message.slot;
|
|
61
|
+
await Promise.all([
|
|
62
|
+
super.put(key, value),
|
|
63
|
+
storeRootIndex(this.db, slot, blockRoot),
|
|
64
|
+
storeParentRootIndex(this.db, slot, value.message.parentRoot),
|
|
73
65
|
]);
|
|
74
66
|
}
|
|
75
67
|
|
|
76
68
|
async batchPut(items: KeyValue<Slot, SignedBeaconBlock>[]): Promise<void> {
|
|
77
|
-
await
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
slot
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
69
|
+
await Promise.all([
|
|
70
|
+
super.batchPut(items),
|
|
71
|
+
Array.from(items).map((item) => {
|
|
72
|
+
const slot = item.value.message.slot;
|
|
73
|
+
const blockRoot = this.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(item.value.message);
|
|
74
|
+
return storeRootIndex(this.db, slot, blockRoot);
|
|
75
|
+
}),
|
|
76
|
+
Array.from(items).map((item) => {
|
|
77
|
+
const slot = item.value.message.slot;
|
|
78
|
+
const parentRoot = item.value.message.parentRoot;
|
|
79
|
+
return storeParentRootIndex(this.db, slot, parentRoot);
|
|
80
|
+
}),
|
|
81
|
+
]);
|
|
86
82
|
}
|
|
87
83
|
|
|
88
84
|
async batchPutBinary(items: BlockArchiveBatchPutBinaryItem[]): Promise<void> {
|
|
89
|
-
await
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
async delete(slot: Slot): Promise<void> {
|
|
96
|
-
await this.batchDelete([slot]);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async batchDelete(slots: Slot[]): Promise<void> {
|
|
100
|
-
await this.db.batchDelete(
|
|
101
|
-
slots.flatMap((slot) => [this.encodeKey(slot), getSlotIndexKey(slot)]),
|
|
102
|
-
this.dbReqOpts
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async batch(operations: DbBatch<Slot, SignedBeaconBlock>): Promise<void> {
|
|
107
|
-
await this.batchBinary(
|
|
108
|
-
operations.map((operation) =>
|
|
109
|
-
operation.type === "put" ? {...operation, value: this.encodeValue(operation.value)} : operation
|
|
110
|
-
)
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async batchBinary(operations: DbBatch<Slot, Uint8Array>): Promise<void> {
|
|
115
|
-
const batch: DbBatch<Uint8Array, Uint8Array> = [];
|
|
116
|
-
for (const operation of operations) {
|
|
117
|
-
if (operation.type === "del") {
|
|
118
|
-
batch.push(
|
|
119
|
-
{type: "del", key: this.encodeKey(operation.key)},
|
|
120
|
-
{type: "del", key: getSlotIndexKey(operation.key)}
|
|
121
|
-
);
|
|
122
|
-
} else {
|
|
123
|
-
const block = this.decodeValue(operation.value);
|
|
124
|
-
const entries = this.indexedBlockEntries({
|
|
125
|
-
key: operation.key,
|
|
126
|
-
value: operation.value,
|
|
127
|
-
slot: block.message.slot,
|
|
128
|
-
blockRoot: this.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message),
|
|
129
|
-
parentRoot: block.message.parentRoot,
|
|
130
|
-
});
|
|
131
|
-
batch.push(...entries.map((entry) => ({type: "put" as const, ...entry})));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
await this.db.batch(batch, this.dbReqOpts);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private indexedBlockEntries(item: BlockArchiveBatchPutBinaryItem): KeyValue<Uint8Array, Uint8Array>[] {
|
|
138
|
-
const slotBytes = intToBytes(item.slot, 8, "be");
|
|
139
|
-
return [
|
|
140
|
-
{key: this.encodeKey(item.key), value: item.value},
|
|
141
|
-
{key: getRootIndexKey(item.blockRoot), value: slotBytes},
|
|
142
|
-
{key: getParentRootIndexKey(item.parentRoot), value: slotBytes},
|
|
143
|
-
{key: getSlotIndexKey(item.key), value: item.blockRoot},
|
|
144
|
-
];
|
|
85
|
+
await Promise.all([
|
|
86
|
+
super.batchPutBinary(items),
|
|
87
|
+
Array.from(items).map((item) => storeRootIndex(this.db, item.slot, item.blockRoot)),
|
|
88
|
+
Array.from(items).map((item) => storeParentRootIndex(this.db, item.slot, item.parentRoot)),
|
|
89
|
+
]);
|
|
145
90
|
}
|
|
146
91
|
|
|
147
92
|
async remove(value: SignedBeaconBlock): Promise<void> {
|
|
@@ -155,10 +100,10 @@ export class BlockArchiveRepository extends Repository<Slot, SignedBeaconBlock>
|
|
|
155
100
|
async batchRemove(values: SignedBeaconBlock[]): Promise<void> {
|
|
156
101
|
await Promise.all([
|
|
157
102
|
super.batchRemove(values),
|
|
158
|
-
|
|
103
|
+
Array.from(values).map((value) =>
|
|
159
104
|
deleteRootIndex(this.db, this.config.getForkTypes(value.message.slot).SignedBeaconBlock, value)
|
|
160
105
|
),
|
|
161
|
-
|
|
106
|
+
Array.from(values).map((value) => deleteParentRootIndex(this.db, value)),
|
|
162
107
|
]);
|
|
163
108
|
}
|
|
164
109
|
|
|
@@ -195,10 +140,6 @@ export class BlockArchiveRepository extends Repository<Slot, SignedBeaconBlock>
|
|
|
195
140
|
return slot !== null ? this.get(slot) : null;
|
|
196
141
|
}
|
|
197
142
|
|
|
198
|
-
async getRootBySlot(slot: Slot): Promise<Root | null> {
|
|
199
|
-
return this.db.get(getSlotIndexKey(slot), {bucketId: getBucketNameByValue(Bucket.index_mainChain)});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
143
|
async getSlotByRoot(root: Root): Promise<Slot | null> {
|
|
203
144
|
return this.parseSlot(await getRootIndex(this.db, root));
|
|
204
145
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Db, encodeKey} from "@lodestar/db";
|
|
2
2
|
import {ForkAll} from "@lodestar/params";
|
|
3
3
|
import {Root, SSZTypesFor, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
|
|
4
|
+
import {intToBytes} from "@lodestar/utils";
|
|
4
5
|
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
5
6
|
|
|
6
7
|
export const rootIndexBucketId = getBucketNameByValue(Bucket.index_blockArchiveRootIndex);
|
|
@@ -14,6 +15,14 @@ export async function getParentRootIndex(db: Db, parentRoot: Root): Promise<Uint
|
|
|
14
15
|
return db.get(getParentRootIndexKey(parentRoot), {bucketId: parentRootIndexBucketId});
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
export async function storeRootIndex(db: Db, slot: Slot, blockRoot: Root): Promise<void> {
|
|
19
|
+
return db.put(getRootIndexKey(blockRoot), intToBytes(slot, 8, "be"), {bucketId: rootIndexBucketId});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function storeParentRootIndex(db: Db, slot: Slot, parentRoot: Root): Promise<void> {
|
|
23
|
+
return db.put(getParentRootIndexKey(parentRoot), intToBytes(slot, 8, "be"), {bucketId: parentRootIndexBucketId});
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
export async function deleteRootIndex(
|
|
18
27
|
db: Db,
|
|
19
28
|
signedBeaconBlockType: SSZTypesFor<ForkAll, "SignedBeaconBlock">,
|
|
@@ -34,7 +43,3 @@ export function getParentRootIndexKey(parentRoot: Root): Uint8Array {
|
|
|
34
43
|
export function getRootIndexKey(root: Root): Uint8Array {
|
|
35
44
|
return encodeKey(Bucket.index_blockArchiveRootIndex, root);
|
|
36
45
|
}
|
|
37
|
-
|
|
38
|
-
export function getSlotIndexKey(slot: Slot): Uint8Array {
|
|
39
|
-
return encodeKey(Bucket.index_mainChain, slot);
|
|
40
|
-
}
|