@lodestar/beacon-node 1.48.0-dev.a427d3dbb5 → 1.48.0-dev.acdde443d2

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.
Files changed (137) hide show
  1. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  2. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  3. package/lib/chain/archiveStore/archiveStore.js +1 -0
  4. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  5. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
  6. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
  7. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  8. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
  9. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  10. package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
  11. package/lib/chain/archiveStore/historicalState/worker.js +4 -1
  12. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  13. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  14. package/lib/chain/archiveStore/utils/archiveBlocks.js +31 -34
  15. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  16. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  17. package/lib/chain/blocks/writeBlockInputToDb.js +9 -16
  18. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  19. package/lib/chain/chain.d.ts +2 -1
  20. package/lib/chain/chain.d.ts.map +1 -1
  21. package/lib/chain/chain.js +47 -24
  22. package/lib/chain/chain.js.map +1 -1
  23. package/lib/db/beacon.d.ts +14 -5
  24. package/lib/db/beacon.d.ts.map +1 -1
  25. package/lib/db/beacon.js +17 -3
  26. package/lib/db/beacon.js.map +1 -1
  27. package/lib/db/dataColumnStore.d.ts +39 -0
  28. package/lib/db/dataColumnStore.d.ts.map +1 -0
  29. package/lib/db/dataColumnStore.js +81 -0
  30. package/lib/db/dataColumnStore.js.map +1 -0
  31. package/lib/db/flatFileStore/atomicWrite.d.ts +8 -0
  32. package/lib/db/flatFileStore/atomicWrite.d.ts.map +1 -0
  33. package/lib/db/flatFileStore/atomicWrite.js +61 -0
  34. package/lib/db/flatFileStore/atomicWrite.js.map +1 -0
  35. package/lib/db/flatFileStore/dcolFormat.d.ts +90 -0
  36. package/lib/db/flatFileStore/dcolFormat.d.ts.map +1 -0
  37. package/lib/db/flatFileStore/dcolFormat.js +286 -0
  38. package/lib/db/flatFileStore/dcolFormat.js.map +1 -0
  39. package/lib/db/flatFileStore/errors.d.ts +82 -0
  40. package/lib/db/flatFileStore/errors.d.ts.map +1 -0
  41. package/lib/db/flatFileStore/errors.js +32 -0
  42. package/lib/db/flatFileStore/errors.js.map +1 -0
  43. package/lib/db/flatFileStore/flatFileStore.d.ts +41 -0
  44. package/lib/db/flatFileStore/flatFileStore.d.ts.map +1 -0
  45. package/lib/db/flatFileStore/flatFileStore.js +251 -0
  46. package/lib/db/flatFileStore/flatFileStore.js.map +1 -0
  47. package/lib/db/flatFileStore/index.d.ts +4 -0
  48. package/lib/db/flatFileStore/index.d.ts.map +1 -0
  49. package/lib/db/flatFileStore/index.js +2 -0
  50. package/lib/db/flatFileStore/index.js.map +1 -0
  51. package/lib/db/flatFileStore/interface.d.ts +25 -0
  52. package/lib/db/flatFileStore/interface.d.ts.map +1 -0
  53. package/lib/db/flatFileStore/interface.js +2 -0
  54. package/lib/db/flatFileStore/interface.js.map +1 -0
  55. package/lib/db/flatFileStore/metrics.d.ts +24 -0
  56. package/lib/db/flatFileStore/metrics.d.ts.map +1 -0
  57. package/lib/db/flatFileStore/metrics.js +25 -0
  58. package/lib/db/flatFileStore/metrics.js.map +1 -0
  59. package/lib/db/flatFileStore/path.d.ts +9 -0
  60. package/lib/db/flatFileStore/path.d.ts.map +1 -0
  61. package/lib/db/flatFileStore/path.js +21 -0
  62. package/lib/db/flatFileStore/path.js.map +1 -0
  63. package/lib/db/flatFileStore/slotIndex.d.ts +14 -0
  64. package/lib/db/flatFileStore/slotIndex.d.ts.map +1 -0
  65. package/lib/db/flatFileStore/slotIndex.js +46 -0
  66. package/lib/db/flatFileStore/slotIndex.js.map +1 -0
  67. package/lib/db/flatFileStore/snappy.d.ts +3 -0
  68. package/lib/db/flatFileStore/snappy.d.ts.map +1 -0
  69. package/lib/db/flatFileStore/snappy.js +12 -0
  70. package/lib/db/flatFileStore/snappy.js.map +1 -0
  71. package/lib/db/index.d.ts +1 -0
  72. package/lib/db/index.d.ts.map +1 -1
  73. package/lib/db/interface.d.ts +8 -1
  74. package/lib/db/interface.d.ts.map +1 -1
  75. package/lib/db/repositories/blockArchive.d.ts +8 -1
  76. package/lib/db/repositories/blockArchive.d.ts.map +1 -1
  77. package/lib/db/repositories/blockArchive.js +65 -28
  78. package/lib/db/repositories/blockArchive.js.map +1 -1
  79. package/lib/db/repositories/blockArchiveIndex.d.ts +1 -2
  80. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  81. package/lib/db/repositories/blockArchiveIndex.js +3 -7
  82. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  83. package/lib/metrics/metrics/lodestar.d.ts +18 -0
  84. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  85. package/lib/metrics/metrics/lodestar.js +55 -1
  86. package/lib/metrics/metrics/lodestar.js.map +1 -1
  87. package/lib/monitoring/clientStats.js +1 -1
  88. package/lib/monitoring/clientStats.js.map +1 -1
  89. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  90. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +112 -91
  91. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  92. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
  93. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +2 -0
  94. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  95. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts +2 -1
  96. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
  97. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +14 -9
  98. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  99. package/lib/node/nodejs.d.ts +2 -1
  100. package/lib/node/nodejs.d.ts.map +1 -1
  101. package/lib/node/nodejs.js +4 -2
  102. package/lib/node/nodejs.js.map +1 -1
  103. package/lib/util/sszBytes.d.ts +6 -0
  104. package/lib/util/sszBytes.d.ts.map +1 -1
  105. package/lib/util/sszBytes.js +1 -1
  106. package/lib/util/sszBytes.js.map +1 -1
  107. package/package.json +15 -15
  108. package/src/chain/archiveStore/archiveStore.ts +6 -1
  109. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -0
  110. package/src/chain/archiveStore/historicalState/types.ts +2 -0
  111. package/src/chain/archiveStore/historicalState/worker.ts +4 -1
  112. package/src/chain/archiveStore/utils/archiveBlocks.ts +34 -39
  113. package/src/chain/blocks/writeBlockInputToDb.ts +10 -17
  114. package/src/chain/chain.ts +53 -23
  115. package/src/db/beacon.ts +33 -6
  116. package/src/db/dataColumnStore.ts +113 -0
  117. package/src/db/flatFileStore/atomicWrite.ts +65 -0
  118. package/src/db/flatFileStore/dcolFormat.ts +389 -0
  119. package/src/db/flatFileStore/errors.ts +53 -0
  120. package/src/db/flatFileStore/flatFileStore.ts +310 -0
  121. package/src/db/flatFileStore/index.ts +3 -0
  122. package/src/db/flatFileStore/interface.ts +21 -0
  123. package/src/db/flatFileStore/metrics.ts +48 -0
  124. package/src/db/flatFileStore/path.ts +32 -0
  125. package/src/db/flatFileStore/slotIndex.ts +56 -0
  126. package/src/db/flatFileStore/snappy.ts +14 -0
  127. package/src/db/index.ts +1 -0
  128. package/src/db/interface.ts +9 -1
  129. package/src/db/repositories/blockArchive.ts +89 -30
  130. package/src/db/repositories/blockArchiveIndex.ts +4 -9
  131. package/src/metrics/metrics/lodestar.ts +57 -1
  132. package/src/monitoring/clientStats.ts +1 -1
  133. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +139 -105
  134. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +2 -0
  135. package/src/network/reqresp/utils/dataColumnResponseValidation.ts +15 -7
  136. package/src/node/nodejs.ts +6 -1
  137. package/src/util/sszBytes.ts +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,oBAAY,wBAAwB;IAClC,YAAY,mCAAmC;IAC/C,YAAY,mCAAmC;IAC/C,iBAAiB,wCAAwC;IACzD,qBAAqB,4CAA4C;IACjE,yBAAyB,gDAAgD;IACzE,cAAc,qCAAqC;IACnD,mBAAmB,0CAA0C;IAC7D,aAAa,oCAAoC;IACjD,oBAAoB,2CAA2C;IAC/D,sBAAsB,6CAA6C;IACnE,oBAAoB,2CAA2C;IAC/D,WAAW,kCAAkC;IAC7C,aAAa,oCAAoC;IACjD,aAAa,oCAAoC;IACjD,cAAc,qCAAqC;IACnD,gBAAgB,uCAAuC;IACvD,mBAAmB,0CAA0C;IAC7D,cAAc,qCAAqC;CACpD;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAC,IAAI,EAAE,wBAAwB,CAAC,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAC3D;IAAC,IAAI,EAAE,wBAAwB,CAAC,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAC3D;IAAC,IAAI,EAAE,wBAAwB,CAAC,iBAAiB,CAAA;CAAC,GAClD;IAAC,IAAI,EAAE,wBAAwB,CAAC,qBAAqB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,GACtE;IAAC,IAAI,EAAE,wBAAwB,CAAC,yBAAyB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,GAC1E;IAAC,IAAI,EAAE,wBAAwB,CAAC,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAChF;IAAC,IAAI,EAAE,wBAAwB,CAAC,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GACrE;IAAC,IAAI,EAAE,wBAAwB,CAAC,aAAa,CAAA;CAAC,GAC9C;IAAC,IAAI,EAAE,wBAAwB,CAAC,oBAAoB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GACpE;IAAC,IAAI,EAAE,wBAAwB,CAAC,sBAAsB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GACtE;IAAC,IAAI,EAAE,wBAAwB,CAAC,oBAAoB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,GACrE;IAAC,IAAI,EAAE,wBAAwB,CAAC,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAC,GACnF;IAAC,IAAI,EAAE,wBAAwB,CAAC,aAAa,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GACpF;IAAC,IAAI,EAAE,wBAAwB,CAAC,aAAa,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GACpF;IAAC,IAAI,EAAE,wBAAwB,CAAC,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,GAC/D;IAAC,IAAI,EAAE,wBAAwB,CAAC,gBAAgB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GACpE;IAAC,IAAI,EAAE,wBAAwB,CAAC,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GACtE;IAAC,IAAI,EAAE,wBAAwB,CAAC,cAAc,CAAA;CAAC,CAAC;AAEpD,qBAAa,oBAAqB,SAAQ,aAAa,CAAC,wBAAwB,CAAC;IAC/E,YAAY,IAAI,EAAE,wBAAwB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAG5E;CACF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEzD"}
@@ -0,0 +1,32 @@
1
+ import { LodestarError } from "@lodestar/utils";
2
+ export var DataColumnStoreErrorCode;
3
+ (function (DataColumnStoreErrorCode) {
4
+ DataColumnStoreErrorCode["INVALID_ROOT"] = "DATA_COLUMN_STORE_INVALID_ROOT";
5
+ DataColumnStoreErrorCode["INVALID_SLOT"] = "DATA_COLUMN_STORE_INVALID_SLOT";
6
+ DataColumnStoreErrorCode["SLOT_OUT_OF_RANGE"] = "DATA_COLUMN_STORE_SLOT_OUT_OF_RANGE";
7
+ DataColumnStoreErrorCode["INVALID_BITMAP_LENGTH"] = "DATA_COLUMN_STORE_INVALID_BITMAP_LENGTH";
8
+ DataColumnStoreErrorCode["INVALID_BLOCK_ROOT_LENGTH"] = "DATA_COLUMN_STORE_INVALID_BLOCK_ROOT_LENGTH";
9
+ DataColumnStoreErrorCode["FILE_TOO_SMALL"] = "DATA_COLUMN_STORE_FILE_TOO_SMALL";
10
+ DataColumnStoreErrorCode["UNSUPPORTED_VERSION"] = "DATA_COLUMN_STORE_UNSUPPORTED_VERSION";
11
+ DataColumnStoreErrorCode["EMPTY_COLUMNS"] = "DATA_COLUMN_STORE_EMPTY_COLUMNS";
12
+ DataColumnStoreErrorCode["INVALID_COLUMN_INDEX"] = "DATA_COLUMN_STORE_INVALID_COLUMN_INDEX";
13
+ DataColumnStoreErrorCode["DUPLICATE_COLUMN_INDEX"] = "DATA_COLUMN_STORE_DUPLICATE_COLUMN_INDEX";
14
+ DataColumnStoreErrorCode["INVALID_OFFSET_TABLE"] = "DATA_COLUMN_STORE_INVALID_OFFSET_TABLE";
15
+ DataColumnStoreErrorCode["SLOT_PRUNED"] = "DATA_COLUMN_STORE_SLOT_PRUNED";
16
+ DataColumnStoreErrorCode["SLOT_MISMATCH"] = "DATA_COLUMN_STORE_SLOT_MISMATCH";
17
+ DataColumnStoreErrorCode["ROOT_MISMATCH"] = "DATA_COLUMN_STORE_ROOT_MISMATCH";
18
+ DataColumnStoreErrorCode["UNEXPECTED_EOF"] = "DATA_COLUMN_STORE_UNEXPECTED_EOF";
19
+ DataColumnStoreErrorCode["OPERATION_FAILED"] = "DATA_COLUMN_STORE_OPERATION_FAILED";
20
+ DataColumnStoreErrorCode["BATCH_DELETE_FAILED"] = "DATA_COLUMN_STORE_BATCH_DELETE_FAILED";
21
+ DataColumnStoreErrorCode["STARTUP_FAILED"] = "DATA_COLUMN_STORE_STARTUP_FAILED";
22
+ })(DataColumnStoreErrorCode || (DataColumnStoreErrorCode = {}));
23
+ export class DataColumnStoreError extends LodestarError {
24
+ constructor(type, message, cause) {
25
+ super(type, message);
26
+ this.cause = cause;
27
+ }
28
+ }
29
+ export function isFsNotFoundError(error) {
30
+ return error instanceof Error && "code" in error && error.code === "ENOENT";
31
+ }
32
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,MAAM,CAAN,IAAY,wBAmBX;AAnBD,WAAY,wBAAwB;IAClC,2EAA+C,CAAA;IAC/C,2EAA+C,CAAA;IAC/C,qFAAyD,CAAA;IACzD,6FAAiE,CAAA;IACjE,qGAAyE,CAAA;IACzE,+EAAmD,CAAA;IACnD,yFAA6D,CAAA;IAC7D,6EAAiD,CAAA;IACjD,2FAA+D,CAAA;IAC/D,+FAAmE,CAAA;IACnE,2FAA+D,CAAA;IAC/D,yEAA6C,CAAA;IAC7C,6EAAiD,CAAA;IACjD,6EAAiD,CAAA;IACjD,+EAAmD,CAAA;IACnD,mFAAuD,CAAA;IACvD,yFAA6D,CAAA;IAC7D,+EAAmD,CAAA;AACrD,CAAC,EAnBW,wBAAwB,KAAxB,wBAAwB,QAmBnC;AAsBD,MAAM,OAAO,oBAAqB,SAAQ,aAAuC;IAC/E,YAAY,IAA8B,EAAE,OAAgB,EAAE,KAAe;QAC3E,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { ChainForkConfig } from "@lodestar/config";
2
+ import { DataColumnSidecar, RootHex, Slot } from "@lodestar/types";
3
+ import { Logger } from "@lodestar/utils";
4
+ import type { IFlatFileStore } from "./interface.js";
5
+ import { type FlatFileStoreMetrics } from "./metrics.js";
6
+ /**
7
+ * Filesystem storage for data columns, keyed by slot and block root.
8
+ * Hot and finalized data share the same layout. The top-level slot index is rebuilt on startup
9
+ * without inspecting the contents of slot directories.
10
+ * Per-slot mutation locking coordinates incremental writes, deletion, and pruning.
11
+ */
12
+ export declare class FlatFileStore implements IFlatFileStore {
13
+ private readonly dataColumnDir;
14
+ private readonly config;
15
+ private readonly logger;
16
+ private readonly slotIndex;
17
+ private readonly mutationLocks;
18
+ private minRetainedSlot;
19
+ private metrics;
20
+ constructor(dataColumnDir: string, config: ChainForkConfig, logger: Logger, metrics?: FlatFileStoreMetrics | null);
21
+ setMetrics(metrics: FlatFileStoreMetrics | null): void;
22
+ init(): Promise<void>;
23
+ close(): Promise<void>;
24
+ getDataColumns(slot: Slot, blockRoot: RootHex): Promise<DataColumnSidecar[]>;
25
+ getDataColumnsBinary(slot: Slot, blockRoot: RootHex, indices: number[]): Promise<(Uint8Array | undefined)[] | null>;
26
+ putDataColumnsBinary(slot: Slot, blockRoot: RootHex, columns: {
27
+ index: number;
28
+ data: Uint8Array;
29
+ }[]): Promise<void>;
30
+ deleteMany(items: {
31
+ slot: Slot;
32
+ blockRoot: RootHex;
33
+ }[]): Promise<void>;
34
+ pruneBefore(minSlot: Slot): Promise<Slot[]>;
35
+ private filePath;
36
+ private acquireMutationLock;
37
+ private readFile;
38
+ private getColumnsBinaryUninstrumented;
39
+ private delete;
40
+ }
41
+ //# sourceMappingURL=flatFileStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flatFileStore.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/flatFileStore.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAC,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAC,MAAM,EAAqB,MAAM,iBAAiB,CAAC;AAe3D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAC,KAAK,oBAAoB,EAAwD,MAAM,cAAc,CAAC;AAK9G;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,cAAc;IAOhD,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IARzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,OAAO,CAAqC;IAEpD,YACmB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,EAC/B,OAAO,GAAE,oBAAoB,GAAG,IAAW,EAG5C;IAED,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAIrD;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA0B1B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAEK,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAajF;IAEK,oBAAoB,CACxB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC,CAI5C;IAEK,oBAAoB,CACxB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAC,EAAE,GAC3C,OAAO,CAAC,IAAI,CAAC,CAiCf;IAEK,UAAU,CAAC,KAAK,EAAE;QAAC,IAAI,EAAE,IAAI,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYzE;IAEK,WAAW,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAoBhD;IAED,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,mBAAmB;YAsBb,QAAQ;YASR,8BAA8B;YA+C9B,MAAM;CAUrB"}
@@ -0,0 +1,251 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fromHex, toRootHex } from "@lodestar/utils";
4
+ import { atomicWrite, mkdirDurable } from "./atomicWrite.js";
5
+ import { DCOL_HEADER_SIZE, encodeDcolFile, getColumnByteRange, mergeDcolColumns, offsetTableSize, parseDcolHeader, parseDcolOffsets, readAllColumns, totalBits, } from "./dcolFormat.js";
6
+ import { DataColumnStoreError, DataColumnStoreErrorCode, isFsNotFoundError } from "./errors.js";
7
+ import { FlatFileStoreOperation, observeFlatFileStoreOperation } from "./metrics.js";
8
+ import { assertValidRootHex, padSlot } from "./path.js";
9
+ import { SlotIndex } from "./slotIndex.js";
10
+ import { uncompress } from "./snappy.js";
11
+ /**
12
+ * Filesystem storage for data columns, keyed by slot and block root.
13
+ * Hot and finalized data share the same layout. The top-level slot index is rebuilt on startup
14
+ * without inspecting the contents of slot directories.
15
+ * Per-slot mutation locking coordinates incremental writes, deletion, and pruning.
16
+ */
17
+ export class FlatFileStore {
18
+ dataColumnDir;
19
+ config;
20
+ logger;
21
+ slotIndex = new SlotIndex();
22
+ mutationLocks = new Map();
23
+ minRetainedSlot = 0;
24
+ metrics = null;
25
+ constructor(dataColumnDir, config, logger, metrics = null) {
26
+ this.dataColumnDir = dataColumnDir;
27
+ this.config = config;
28
+ this.logger = logger;
29
+ this.setMetrics(metrics);
30
+ }
31
+ setMetrics(metrics) {
32
+ if (metrics === this.metrics)
33
+ return;
34
+ this.metrics = metrics;
35
+ metrics?.slotIndexSize.addCollect((metric) => metric.set(this.slotIndex.size));
36
+ }
37
+ async init() {
38
+ const endTimer = this.metrics?.startupDuration.startTimer();
39
+ try {
40
+ await mkdirDurable(this.dataColumnDir);
41
+ const stats = await this.slotIndex.rebuildFromDisk(this.dataColumnDir);
42
+ if (stats.ignoredEntries > 0) {
43
+ this.logger.warn("Ignored non-canonical flat file store entries", {
44
+ entries: stats.ignoredEntries,
45
+ });
46
+ }
47
+ this.logger.info("Flat file store initialized", {
48
+ slots: stats.slots,
49
+ });
50
+ }
51
+ catch (e) {
52
+ this.metrics?.startupErrors.inc();
53
+ if (e instanceof DataColumnStoreError) {
54
+ throw e;
55
+ }
56
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.STARTUP_FAILED }, "Flat file store initialization failed", e);
57
+ }
58
+ finally {
59
+ endTimer?.();
60
+ }
61
+ }
62
+ async close() {
63
+ // All operations are stateless file I/O.
64
+ }
65
+ async getDataColumns(slot, blockRoot) {
66
+ return observeFlatFileStoreOperation(this.metrics, FlatFileStoreOperation.read, async () => {
67
+ const data = await this.readFile(slot, blockRoot);
68
+ if (!data)
69
+ return [];
70
+ this.metrics?.readBytes.inc(data.length);
71
+ const header = parseDcolHeader(data);
72
+ validateDcolHeader(header, slot, blockRoot);
73
+ const columns = readAllColumns(data, header);
74
+ const dataColumnSidecarType = this.config.getForkTypes(slot).DataColumnSidecar;
75
+ return columns.map((col) => dataColumnSidecarType.deserialize(col.data));
76
+ });
77
+ }
78
+ async getDataColumnsBinary(slot, blockRoot, indices) {
79
+ return observeFlatFileStoreOperation(this.metrics, FlatFileStoreOperation.read, () => this.getColumnsBinaryUninstrumented(slot, blockRoot, indices));
80
+ }
81
+ async putDataColumnsBinary(slot, blockRoot, columns) {
82
+ const rootBytes = fromHex(blockRoot);
83
+ if (columns.length === 0)
84
+ return;
85
+ await observeFlatFileStoreOperation(this.metrics, FlatFileStoreOperation.write, async () => {
86
+ const release = await this.acquireMutationLock(slot);
87
+ try {
88
+ if (slot < this.minRetainedSlot) {
89
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.SLOT_PRUNED, slot, minRetainedSlot: this.minRetainedSlot }, `Cannot write pruned data column slot=${slot} minRetainedSlot=${this.minRetainedSlot}`);
90
+ }
91
+ const existing = await this.readFile(slot, blockRoot);
92
+ let fileData;
93
+ if (existing) {
94
+ this.metrics?.readBytes.inc(existing.length);
95
+ const header = parseDcolHeader(existing);
96
+ validateDcolHeader(header, slot, blockRoot);
97
+ fileData = mergeDcolColumns(existing, columns);
98
+ }
99
+ else {
100
+ fileData = encodeDcolFile(rootBytes, slot, columns);
101
+ }
102
+ // The rename can succeed even if syncing its directory fails.
103
+ this.slotIndex.add(slot);
104
+ await atomicWrite(this.filePath(slot, blockRoot), fileData);
105
+ this.metrics?.writeBytes.inc(fileData.length);
106
+ }
107
+ finally {
108
+ release();
109
+ }
110
+ });
111
+ }
112
+ async deleteMany(items) {
113
+ const results = await Promise.allSettled(items.map(({ slot, blockRoot }) => this.delete(slot, blockRoot)));
114
+ const errors = results
115
+ .filter((result) => result.status === "rejected")
116
+ .map((result) => result.reason);
117
+ if (errors.length > 0) {
118
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.BATCH_DELETE_FAILED, failures: errors.length }, "Failed to delete flat file data", new AggregateError(errors));
119
+ }
120
+ }
121
+ async pruneBefore(minSlot) {
122
+ return observeFlatFileStoreOperation(this.metrics, FlatFileStoreOperation.prune, async () => {
123
+ this.minRetainedSlot = Math.max(this.minRetainedSlot, minSlot);
124
+ const slotsToPrune = new Set(this.slotIndex.getBefore(this.minRetainedSlot));
125
+ for (const slot of this.mutationLocks.keys()) {
126
+ if (slot < this.minRetainedSlot)
127
+ slotsToPrune.add(slot);
128
+ }
129
+ for (const slot of slotsToPrune) {
130
+ const release = await this.acquireMutationLock(slot);
131
+ try {
132
+ await fs.promises.rm(path.join(this.dataColumnDir, padSlot(slot)), { recursive: true, force: true });
133
+ this.slotIndex.remove(slot);
134
+ this.metrics?.prunedDirectories.inc();
135
+ }
136
+ finally {
137
+ release();
138
+ }
139
+ }
140
+ return [...slotsToPrune].sort((a, b) => a - b);
141
+ });
142
+ }
143
+ filePath(slot, rootHex) {
144
+ assertValidRootHex(rootHex);
145
+ return path.join(this.dataColumnDir, padSlot(slot), `${rootHex}.dcol`);
146
+ }
147
+ acquireMutationLock(slot) {
148
+ let release;
149
+ const prev = this.mutationLocks.get(slot) ?? Promise.resolve();
150
+ const next = new Promise((resolve) => {
151
+ release = resolve;
152
+ });
153
+ const chained = prev.then(() => next);
154
+ this.mutationLocks.set(slot, chained);
155
+ return prev.then(() => {
156
+ let released = false;
157
+ return () => {
158
+ if (released)
159
+ return;
160
+ released = true;
161
+ release();
162
+ if (this.mutationLocks.get(slot) === chained) {
163
+ this.mutationLocks.delete(slot);
164
+ }
165
+ };
166
+ });
167
+ }
168
+ async readFile(slot, rootHex) {
169
+ try {
170
+ return await fs.promises.readFile(this.filePath(slot, rootHex));
171
+ }
172
+ catch (e) {
173
+ if (!isFsNotFoundError(e))
174
+ throw e;
175
+ return null;
176
+ }
177
+ }
178
+ async getColumnsBinaryUninstrumented(slot, rootHex, indices) {
179
+ let fd;
180
+ try {
181
+ fd = await fs.promises.open(this.filePath(slot, rootHex), "r");
182
+ }
183
+ catch (e) {
184
+ if (!isFsNotFoundError(e))
185
+ throw e;
186
+ return null;
187
+ }
188
+ try {
189
+ const headerBuf = new Uint8Array(DCOL_HEADER_SIZE);
190
+ await readExactly(fd, headerBuf, 0);
191
+ this.metrics?.readBytes.inc(headerBuf.length);
192
+ const header = parseDcolHeader(headerBuf);
193
+ validateDcolHeader(header, slot, rootHex);
194
+ const N = totalBits(header.bitmap);
195
+ const tableSize = offsetTableSize(N);
196
+ const offsetTable = new Uint8Array(tableSize);
197
+ await readExactly(fd, offsetTable, DCOL_HEADER_SIZE);
198
+ this.metrics?.readBytes.inc(offsetTable.length);
199
+ const fileSize = (await fd.stat()).size;
200
+ const offsets = parseDcolOffsets(offsetTable, N, fileSize - DCOL_HEADER_SIZE - tableSize);
201
+ const results = [];
202
+ for (const idx of indices) {
203
+ const range = getColumnByteRange(header, offsets, idx);
204
+ if (!range) {
205
+ results.push(undefined);
206
+ continue;
207
+ }
208
+ const buf = new Uint8Array(range.length);
209
+ await readExactly(fd, buf, range.offset);
210
+ this.metrics?.readBytes.inc(buf.length);
211
+ results.push(uncompress(buf));
212
+ }
213
+ return results;
214
+ }
215
+ finally {
216
+ await fd.close();
217
+ }
218
+ }
219
+ async delete(slot, rootHex) {
220
+ await observeFlatFileStoreOperation(this.metrics, FlatFileStoreOperation.delete, async () => {
221
+ const release = await this.acquireMutationLock(slot);
222
+ try {
223
+ await fs.promises.rm(this.filePath(slot, rootHex), { force: true });
224
+ }
225
+ finally {
226
+ release();
227
+ }
228
+ });
229
+ }
230
+ }
231
+ function validateDcolHeader(header, slot, rootHex) {
232
+ if (header.slot !== slot) {
233
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.SLOT_MISMATCH, headerSlot: header.slot, pathSlot: slot }, `Dcol slot mismatch: header=${header.slot} path=${slot}`);
234
+ }
235
+ const headerRoot = toRootHex(header.blockRoot);
236
+ if (headerRoot !== rootHex) {
237
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.ROOT_MISMATCH, headerRoot, pathRoot: rootHex }, `Dcol block root mismatch: header=${headerRoot} path=${rootHex}`);
238
+ }
239
+ }
240
+ async function readExactly(fd, buffer, position) {
241
+ let totalRead = 0;
242
+ while (totalRead < buffer.length) {
243
+ const { bytesRead } = await fd.read(buffer, totalRead, buffer.length - totalRead, position + totalRead);
244
+ if (bytesRead === 0) {
245
+ const offset = position + totalRead;
246
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.UNEXPECTED_EOF, offset }, `Unexpected end of dcol file at offset ${offset}`);
247
+ }
248
+ totalRead += bytesRead;
249
+ }
250
+ }
251
+ //# sourceMappingURL=flatFileStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flatFileStore.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/flatFileStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { FlatFileStore } from "./flatFileStore.js";
2
+ export type { IFlatFileStore } from "./interface.js";
3
+ export type { FlatFileStoreMetrics } from "./metrics.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { FlatFileStore } from "./flatFileStore.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { DataColumnSidecar, RootHex, Slot } from "@lodestar/types";
2
+ /**
3
+ * Flat file storage interface for data columns.
4
+ *
5
+ * No hot/cold distinction — data is always keyed by (slot, blockRoot).
6
+ * All filesystem operations are crash-safe via atomic writes.
7
+ *
8
+ */
9
+ export interface IFlatFileStore {
10
+ init(): Promise<void>;
11
+ close(): Promise<void>;
12
+ getDataColumns(slot: Slot, blockRoot: RootHex): Promise<DataColumnSidecar[]>;
13
+ /** Returns null if the file is absent, and undefined entries for columns missing from an existing file. */
14
+ getDataColumnsBinary(slot: Slot, blockRoot: RootHex, indices: number[]): Promise<(Uint8Array | undefined)[] | null>;
15
+ putDataColumnsBinary(slot: Slot, blockRoot: RootHex, columns: {
16
+ index: number;
17
+ data: Uint8Array;
18
+ }[]): Promise<void>;
19
+ deleteMany(items: {
20
+ slot: Slot;
21
+ blockRoot: RootHex;
22
+ }[]): Promise<void>;
23
+ pruneBefore(slot: Slot): Promise<Slot[]>;
24
+ }
25
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,iBAAiB,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC7E,2GAA2G;IAC3G,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACpH,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElH,UAAU,CAAC,KAAK,EAAE;QAAC,IAAI,EAAE,IAAI,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;CAC1C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import type { Counter, GaugeExtra, Histogram } from "@lodestar/utils";
2
+ export declare const FlatFileStoreOperation: {
3
+ readonly read: "read";
4
+ readonly write: "write";
5
+ readonly delete: "delete";
6
+ readonly prune: "prune";
7
+ };
8
+ export type FlatFileStoreOperation = (typeof FlatFileStoreOperation)[keyof typeof FlatFileStoreOperation];
9
+ type OperationLabels = {
10
+ operation: FlatFileStoreOperation;
11
+ };
12
+ export type FlatFileStoreMetrics = {
13
+ operationDuration: Record<FlatFileStoreOperation, Histogram>;
14
+ operationErrors: Counter<OperationLabels>;
15
+ readBytes: Counter;
16
+ writeBytes: Counter;
17
+ prunedDirectories: Counter;
18
+ slotIndexSize: GaugeExtra;
19
+ startupDuration: Histogram;
20
+ startupErrors: Counter;
21
+ };
22
+ export declare function observeFlatFileStoreOperation<T>(metrics: FlatFileStoreMetrics | null, operation: FlatFileStoreOperation, fn: () => Promise<T>): Promise<T>;
23
+ export {};
24
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAGpE,eAAO,MAAM,sBAAsB;aACjC,IAAI,EAAE,MAAM;aACZ,KAAK,EAAE,OAAO;aACd,MAAM,EAAE,QAAQ;aAChB,KAAK,EAAE,OAAO;CACN,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,OAAO,sBAAsB,CAAC,CAAC;AAE1G,KAAK,eAAe,GAAG;IAAC,SAAS,EAAE,sBAAsB,CAAA;CAAC,CAAC;AAE3D,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,MAAM,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IAC7D,eAAe,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,UAAU,CAAC;IAC1B,eAAe,EAAE,SAAS,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,wBAAsB,6BAA6B,CAAC,CAAC,EACnD,OAAO,EAAE,oBAAoB,GAAG,IAAI,EACpC,SAAS,EAAE,sBAAsB,EACjC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAkBZ"}
@@ -0,0 +1,25 @@
1
+ import { DataColumnStoreError, DataColumnStoreErrorCode } from "./errors.js";
2
+ export const FlatFileStoreOperation = {
3
+ read: "read",
4
+ write: "write",
5
+ delete: "delete",
6
+ prune: "prune",
7
+ };
8
+ export async function observeFlatFileStoreOperation(metrics, operation, fn) {
9
+ const labels = { operation };
10
+ const endTimer = metrics?.operationDuration[operation].startTimer();
11
+ try {
12
+ return await fn();
13
+ }
14
+ catch (e) {
15
+ metrics?.operationErrors.inc(labels);
16
+ if (e instanceof DataColumnStoreError) {
17
+ throw e;
18
+ }
19
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.OPERATION_FAILED, operation }, `Flat file store ${operation} operation failed`, e);
20
+ }
21
+ finally {
22
+ endTimer?.();
23
+ }
24
+ }
25
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/metrics.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,oBAAoB,EAAE,wBAAwB,EAAC,MAAM,aAAa,CAAC;AAE3E,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACN,CAAC;AAiBX,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAoC,EACpC,SAAiC,EACjC,EAAoB;IAEpB,MAAM,MAAM,GAAG,EAAC,SAAS,EAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;IACpE,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,oBAAoB,EAAE,CAAC;YACtC,MAAM,CAAC,CAAC;QACV,CAAC;QACD,MAAM,IAAI,oBAAoB,CAC5B,EAAC,IAAI,EAAE,wBAAwB,CAAC,gBAAgB,EAAE,SAAS,EAAC,EAC5D,mBAAmB,SAAS,mBAAmB,EAC/C,CAAC,CACF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,QAAQ,EAAE,EAAE,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { RootHex } from "@lodestar/types";
2
+ export declare function isValidRootHex(rootHex: string): rootHex is RootHex;
3
+ export declare function assertValidRootHex(rootHex: string): asserts rootHex is RootHex;
4
+ /**
5
+ * Zero-pad a slot number to 12 digits for lexicographic ordering in directory names.
6
+ * Twelve digits covers many centuries of Ethereum; larger safe integers remain untruncated.
7
+ */
8
+ export declare function padSlot(slot: number): string;
9
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAK7C,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,OAAO,CAElE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAO9E;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5C"}
@@ -0,0 +1,21 @@
1
+ import { DataColumnStoreError, DataColumnStoreErrorCode } from "./errors.js";
2
+ const ROOT_HEX_PATTERN = /^0x[0-9a-f]{64}$/;
3
+ export function isValidRootHex(rootHex) {
4
+ return ROOT_HEX_PATTERN.test(rootHex);
5
+ }
6
+ export function assertValidRootHex(rootHex) {
7
+ if (!isValidRootHex(rootHex)) {
8
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.INVALID_ROOT, root: rootHex }, `Invalid flat file root: ${rootHex}`);
9
+ }
10
+ }
11
+ /**
12
+ * Zero-pad a slot number to 12 digits for lexicographic ordering in directory names.
13
+ * Twelve digits covers many centuries of Ethereum; larger safe integers remain untruncated.
14
+ */
15
+ export function padSlot(slot) {
16
+ if (!Number.isSafeInteger(slot) || slot < 0) {
17
+ throw new DataColumnStoreError({ code: DataColumnStoreErrorCode.INVALID_SLOT, slot }, `Invalid flat file slot: ${slot}`);
18
+ }
19
+ return String(slot).padStart(12, "0");
20
+ }
21
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/path.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,oBAAoB,EAAE,wBAAwB,EAAC,MAAM,aAAa,CAAC;AAE3E,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAE5C,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,oBAAoB,CAC5B,EAAC,IAAI,EAAE,wBAAwB,CAAC,YAAY,EAAE,IAAI,EAAE,OAAO,EAAC,EAC5D,2BAA2B,OAAO,EAAE,CACrC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,oBAAoB,CAC5B,EAAC,IAAI,EAAE,wBAAwB,CAAC,YAAY,EAAE,IAAI,EAAC,EACnD,2BAA2B,IAAI,EAAE,CAClC,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { Slot } from "@lodestar/types";
2
+ export type SlotIndexRebuildStats = {
3
+ slots: number;
4
+ ignoredEntries: number;
5
+ };
6
+ export declare class SlotIndex {
7
+ private readonly slots;
8
+ get size(): number;
9
+ add(slot: Slot): void;
10
+ remove(slot: Slot): void;
11
+ getBefore(minSlot: Slot): Slot[];
12
+ rebuildFromDisk(columnsDir: string): Promise<SlotIndexRebuildStats>;
13
+ }
14
+ //# sourceMappingURL=slotIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slotIndex.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/slotIndex.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,iBAAiB,CAAC;AAIrC,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IAEzC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAEpB;IAED,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAEvB;IAED,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,EAAE,CAM/B;IAEK,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAqBxE;CACF"}
@@ -0,0 +1,46 @@
1
+ import fs from "node:fs";
2
+ import { isFsNotFoundError } from "./errors.js";
3
+ import { padSlot } from "./path.js";
4
+ export class SlotIndex {
5
+ slots = new Set();
6
+ get size() {
7
+ return this.slots.size;
8
+ }
9
+ add(slot) {
10
+ this.slots.add(slot);
11
+ }
12
+ remove(slot) {
13
+ this.slots.delete(slot);
14
+ }
15
+ getBefore(minSlot) {
16
+ const slots = [];
17
+ for (const slot of this.slots) {
18
+ if (slot < minSlot)
19
+ slots.push(slot);
20
+ }
21
+ return slots;
22
+ }
23
+ async rebuildFromDisk(columnsDir) {
24
+ this.slots.clear();
25
+ let entries;
26
+ try {
27
+ entries = await fs.promises.readdir(columnsDir, { withFileTypes: true });
28
+ }
29
+ catch (e) {
30
+ if (!isFsNotFoundError(e))
31
+ throw e;
32
+ return { slots: 0, ignoredEntries: 0 };
33
+ }
34
+ let ignoredEntries = 0;
35
+ for (const entry of entries) {
36
+ const slot = Number(entry.name);
37
+ if (!entry.isDirectory() || !Number.isSafeInteger(slot) || slot < 0 || entry.name !== padSlot(slot)) {
38
+ ignoredEntries++;
39
+ continue;
40
+ }
41
+ this.slots.add(slot);
42
+ }
43
+ return { slots: this.slots.size, ignoredEntries };
44
+ }
45
+ }
46
+ //# sourceMappingURL=slotIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slotIndex.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/slotIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAOlC,MAAM,OAAO,SAAS;IACH,KAAK,GAAG,IAAI,GAAG,EAAQ,CAAC;IAEzC,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,IAAU;QACZ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,IAAU;QACf,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,SAAS,CAAC,OAAa;QACrB,MAAM,KAAK,GAAW,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,GAAG,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAAkB;QACtC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,OAAoB,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAC,aAAa,EAAE,IAAI,EAAC,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,CAAC;YACnC,OAAO,EAAC,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAC,CAAC;QACvC,CAAC;QAED,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpG,cAAc,EAAE,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,EAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,EAAC,CAAC;IAClD,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export declare function compress(data: Uint8Array): Uint8Array;
2
+ export declare function uncompress(data: Uint8Array): Uint8Array;
3
+ //# sourceMappingURL=snappy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snappy.d.ts","sourceRoot":"","sources":["../../../src/db/flatFileStore/snappy.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAErD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAGvD"}
@@ -0,0 +1,12 @@
1
+ import { compressSync, uncompressSync } from "snappy";
2
+ export function compress(data) {
3
+ return compressSync(toBuffer(data));
4
+ }
5
+ export function uncompress(data) {
6
+ const result = uncompressSync(toBuffer(data), { asBuffer: true });
7
+ return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
8
+ }
9
+ function toBuffer(data) {
10
+ return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
11
+ }
12
+ //# sourceMappingURL=snappy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snappy.js","sourceRoot":"","sources":["../../../src/db/flatFileStore/snappy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,cAAc,EAAC,MAAM,QAAQ,CAAC;AAEpD,MAAM,UAAU,QAAQ,CAAC,IAAgB;IACvC,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAW,CAAC;IAC1E,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,QAAQ,CAAC,IAAgB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;AACpE,CAAC"}
package/lib/db/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { BeaconDb } from "./beacon.js";
2
2
  export { Bucket } from "./buckets.js";
3
+ export type { DataColumnKey, IDataColumnStore, IndexedDataColumnBytes } from "./dataColumnStore.js";
3
4
  export type { IBeaconDb } from "./interface.js";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,YAAY,EAAC,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAC,MAAM,sBAAsB,CAAC;AAClG,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC"}