@lodestar/beacon-node 1.41.0-rc.2 → 1.42.0-dev.5f2fffc2ce

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 (99) hide show
  1. package/lib/api/impl/beacon/state/utils.d.ts +2 -2
  2. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  3. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  4. package/lib/api/impl/validator/index.d.ts.map +1 -1
  5. package/lib/api/impl/validator/index.js +5 -1
  6. package/lib/api/impl/validator/index.js.map +1 -1
  7. package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
  8. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  9. package/lib/chain/archiveStore/archiveStore.js +0 -9
  10. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  11. package/lib/chain/archiveStore/interface.d.ts +4 -4
  12. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  13. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  14. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +4 -1
  16. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  17. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  18. package/lib/chain/archiveStore/utils/archiveBlocks.js +38 -0
  19. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  20. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  21. package/lib/chain/blocks/importBlock.js +11 -7
  22. package/lib/chain/blocks/importBlock.js.map +1 -1
  23. package/lib/chain/blocks/verifyBlocksSignatures.js +1 -1
  24. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  25. package/lib/chain/chain.d.ts +3 -3
  26. package/lib/chain/chain.d.ts.map +1 -1
  27. package/lib/chain/chain.js +16 -7
  28. package/lib/chain/chain.js.map +1 -1
  29. package/lib/chain/interface.d.ts +2 -2
  30. package/lib/chain/interface.d.ts.map +1 -1
  31. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  32. package/lib/chain/prepareNextSlot.js +6 -2
  33. package/lib/chain/prepareNextSlot.js.map +1 -1
  34. package/lib/chain/regen/errors.d.ts +11 -1
  35. package/lib/chain/regen/errors.d.ts.map +1 -1
  36. package/lib/chain/regen/errors.js +2 -0
  37. package/lib/chain/regen/errors.js.map +1 -1
  38. package/lib/chain/regen/interface.d.ts +12 -6
  39. package/lib/chain/regen/interface.d.ts.map +1 -1
  40. package/lib/chain/regen/queued.d.ts +11 -6
  41. package/lib/chain/regen/queued.d.ts.map +1 -1
  42. package/lib/chain/regen/queued.js +40 -8
  43. package/lib/chain/regen/queued.js.map +1 -1
  44. package/lib/chain/regen/regen.d.ts +5 -0
  45. package/lib/chain/regen/regen.d.ts.map +1 -1
  46. package/lib/chain/regen/regen.js +33 -6
  47. package/lib/chain/regen/regen.js.map +1 -1
  48. package/lib/chain/stateCache/datastore/db.d.ts +4 -5
  49. package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
  50. package/lib/chain/stateCache/datastore/db.js +32 -10
  51. package/lib/chain/stateCache/datastore/db.js.map +1 -1
  52. package/lib/chain/stateCache/datastore/file.d.ts +1 -1
  53. package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
  54. package/lib/chain/stateCache/datastore/file.js +5 -5
  55. package/lib/chain/stateCache/datastore/file.js.map +1 -1
  56. package/lib/chain/stateCache/datastore/types.d.ts +1 -1
  57. package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
  58. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +7 -4
  59. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  60. package/lib/chain/stateCache/fifoBlockStateCache.js +8 -3
  61. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  62. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +33 -14
  63. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  64. package/lib/chain/stateCache/persistentCheckpointsCache.js +217 -119
  65. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  66. package/lib/chain/stateCache/types.d.ts +15 -8
  67. package/lib/chain/stateCache/types.d.ts.map +1 -1
  68. package/lib/chain/stateCache/types.js.map +1 -1
  69. package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
  70. package/lib/chain/validation/voluntaryExit.js +2 -2
  71. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  72. package/package.json +15 -15
  73. package/src/api/impl/beacon/state/utils.ts +2 -2
  74. package/src/api/impl/validator/index.ts +7 -3
  75. package/src/chain/archiveStore/archiveStore.ts +0 -10
  76. package/src/chain/archiveStore/interface.ts +4 -4
  77. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +8 -5
  78. package/src/chain/archiveStore/utils/archiveBlocks.ts +59 -1
  79. package/src/chain/blocks/importBlock.ts +11 -6
  80. package/src/chain/blocks/verifyBlocksSignatures.ts +1 -1
  81. package/src/chain/chain.ts +23 -12
  82. package/src/chain/interface.ts +2 -2
  83. package/src/chain/prepareNextSlot.ts +6 -2
  84. package/src/chain/regen/errors.ts +6 -1
  85. package/src/chain/regen/interface.ts +12 -6
  86. package/src/chain/regen/queued.ts +48 -12
  87. package/src/chain/regen/regen.ts +37 -7
  88. package/src/chain/stateCache/datastore/db.ts +33 -10
  89. package/src/chain/stateCache/datastore/file.ts +6 -5
  90. package/src/chain/stateCache/datastore/types.ts +3 -2
  91. package/src/chain/stateCache/fifoBlockStateCache.ts +10 -4
  92. package/src/chain/stateCache/persistentCheckpointsCache.ts +248 -139
  93. package/src/chain/stateCache/types.ts +18 -8
  94. package/src/chain/validation/voluntaryExit.ts +2 -1
  95. package/lib/chain/archiveStore/utils/archivePayloads.d.ts +0 -7
  96. package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +0 -1
  97. package/lib/chain/archiveStore/utils/archivePayloads.js +0 -10
  98. package/lib/chain/archiveStore/utils/archivePayloads.js.map +0 -1
  99. package/src/chain/archiveStore/utils/archivePayloads.ts +0 -15
@@ -1,9 +1,14 @@
1
1
  import { routes } from "@lodestar/api";
2
2
  import { CachedBeaconStateAllForks } from "@lodestar/state-transition";
3
3
  import { Epoch, RootHex, phase0 } from "@lodestar/types";
4
- export type CheckpointHex = {
4
+ /**
5
+ * Checkpoint hex representation for state cache keys.
6
+ * Extends CheckpointWithHex (from fork-choice) with payloadPresent.
7
+ */
8
+ export type CheckpointHexPayload = {
5
9
  epoch: Epoch;
6
10
  rootHex: RootHex;
11
+ payloadPresent: boolean;
7
12
  };
8
13
  /**
9
14
  * Lodestar currently keeps two state caches around.
@@ -31,6 +36,8 @@ export interface BlockStateCache {
31
36
  size: number;
32
37
  prune(headStateRootHex: RootHex): void;
33
38
  deleteAllBeforeEpoch(finalizedEpoch: Epoch): void;
39
+ /** Upgrade cache capacity for Gloas fork (2x states for block + payload states) */
40
+ upgradeToGloas(): void;
34
41
  dumpSummary(): routes.lodestar.StateCacheItem[];
35
42
  /** Expose beacon states stored in cache. Use with caution */
36
43
  getStates(): IterableIterator<CachedBeaconStateAllForks>;
@@ -58,13 +65,13 @@ export interface BlockStateCache {
58
65
  */
59
66
  export interface CheckpointStateCache {
60
67
  init?: () => Promise<void>;
61
- getOrReload(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | null>;
62
- getStateOrBytes(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | Uint8Array | null>;
63
- get(cpOrKey: CheckpointHex | string): CachedBeaconStateAllForks | null;
64
- add(cp: phase0.Checkpoint, state: CachedBeaconStateAllForks): void;
65
- getLatest(rootHex: RootHex, maxEpoch: Epoch): CachedBeaconStateAllForks | null;
66
- getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<CachedBeaconStateAllForks | null>;
67
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
68
+ getOrReload(cp: CheckpointHexPayload): Promise<CachedBeaconStateAllForks | null>;
69
+ getStateOrBytes(cp: CheckpointHexPayload): Promise<CachedBeaconStateAllForks | Uint8Array | null>;
70
+ get(cpOrKey: CheckpointHexPayload | string): CachedBeaconStateAllForks | null;
71
+ add(cp: phase0.Checkpoint, state: CachedBeaconStateAllForks, payloadPresent: boolean): void;
72
+ getLatest(rootHex: RootHex, maxEpoch: Epoch, payloadPresent: boolean): CachedBeaconStateAllForks | null;
73
+ getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch, payloadPresent: boolean): Promise<CachedBeaconStateAllForks | null>;
74
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null;
68
75
  prune(finalizedEpoch: Epoch, justifiedEpoch: Epoch): void;
69
76
  pruneFinalized(finalizedEpoch: Epoch): void;
70
77
  processState(blockRootHex: RootHex, state: CachedBeaconStateAllForks): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/chain/stateCache/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,CAAC;AAE7D;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,IAAI,CAAC;IACxD,GAAG,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC3C,YAAY,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3D;;OAEG;IACH,YAAY,IAAI,yBAAyB,CAAC;IAC1C,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,oBAAoB,CAAC,cAAc,EAAE,KAAK,GAAG,IAAI,CAAC;IAClD,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChD,6DAA6D;IAC7D,SAAS,IAAI,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,WAAW,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;IAC1E,eAAe,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,yBAAyB,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;IAC3F,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,yBAAyB,GAAG,IAAI,CAAC;IACvE,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;IACnE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,GAAG,yBAAyB,GAAG,IAAI,CAAC;IAC/E,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;IAChG,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3E,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,GAAG,IAAI,CAAC;IAC1D,cAAc,CAAC,cAAc,EAAE,KAAK,GAAG,IAAI,CAAC;IAC5C,YAAY,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvF,KAAK,IAAI,IAAI,CAAC;IACd,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChD,6DAA6D;IAC7D,SAAS,IAAI,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;CAC1D;AAED,oBAAY,aAAa;IACvB,SAAS,cAAc;IACvB,QAAQ,cAAc;CACvB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/chain/stateCache/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAC,CAAC;AAE7F;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,IAAI,CAAC;IACxD,GAAG,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC3C,YAAY,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3D;;OAEG;IACH,YAAY,IAAI,yBAAyB,CAAC;IAC1C,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,oBAAoB,CAAC,cAAc,EAAE,KAAK,GAAG,IAAI,CAAC;IAClD,mFAAmF;IACnF,cAAc,IAAI,IAAI,CAAC;IACvB,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChD,6DAA6D;IAC7D,SAAS,IAAI,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,WAAW,CAAC,EAAE,EAAE,oBAAoB,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;IACjF,eAAe,CAAC,EAAE,EAAE,oBAAoB,GAAG,OAAO,CAAC,yBAAyB,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;IAClG,GAAG,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,GAAG,yBAAyB,GAAG,IAAI,CAAC;IAC9E,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,yBAAyB,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5F,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,GAAG,yBAAyB,GAAG,IAAI,CAAC;IACxG,iBAAiB,CACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,KAAK,EACf,cAAc,EAAE,OAAO,GACtB,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;IAC7C,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACpG,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,GAAG,IAAI,CAAC;IAC1D,cAAc,CAAC,cAAc,EAAE,KAAK,GAAG,IAAI,CAAC;IAC5C,YAAY,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvF,KAAK,IAAI,IAAI,CAAC;IACd,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChD,6DAA6D;IAC7D,SAAS,IAAI,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;CAC1D;AAED,oBAAY,aAAa;IACvB,SAAS,cAAc;IACvB,QAAQ,cAAc;CACvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/chain/stateCache/types.ts"],"names":[],"mappings":"SA6EY,aAAa;AAAzB,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,wCAAuB,CAAA;IACvB,uCAAsB,CAAA;AAAC,CACzB,EAHY,aAAa,KAAb,aAAa,QAGxB"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/chain/stateCache/types.ts"],"names":[],"mappings":"SAuFY,aAAa;AAAzB,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,wCAAuB,CAAA;IACvB,uCAAsB,CAAA;AAAC,CACzB,EAHY,aAAa,KAAb,aAAa,QAGxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"voluntaryExit.d.ts","sourceRoot":"","sources":["../../../src/chain/validation/voluntaryExit.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAOvC,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAGzC,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,YAAY,EACnB,aAAa,EAAE,MAAM,CAAC,mBAAmB,GACxC,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,YAAY,EACnB,aAAa,EAAE,MAAM,CAAC,mBAAmB,GACxC,OAAO,CAAC,IAAI,CAAC,CAEf"}
1
+ {"version":3,"file":"voluntaryExit.d.ts","sourceRoot":"","sources":["../../../src/chain/validation/voluntaryExit.ts"],"names":[],"mappings":"AAMA,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAOvC,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAGzC,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,YAAY,EACnB,aAAa,EAAE,MAAM,CAAC,mBAAmB,GACxC,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,YAAY,EACnB,aAAa,EAAE,MAAM,CAAC,mBAAmB,GACxC,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -1,4 +1,4 @@
1
- import { VoluntaryExitValidity, getVoluntaryExitSignatureSet, getVoluntaryExitValidity, } from "@lodestar/state-transition";
1
+ import { BeaconStateView, VoluntaryExitValidity, getVoluntaryExitSignatureSet, getVoluntaryExitValidity, } from "@lodestar/state-transition";
2
2
  import { GossipAction, VoluntaryExitError, VoluntaryExitErrorCode, voluntaryExitValidityToErrorCode, } from "../errors/index.js";
3
3
  import { RegenCaller } from "../regen/index.js";
4
4
  export async function validateApiVoluntaryExit(chain, voluntaryExit) {
@@ -32,7 +32,7 @@ async function validateVoluntaryExit(chain, voluntaryExit, prioritizeBls = false
32
32
  code: voluntaryExitValidityToErrorCode(validity),
33
33
  });
34
34
  }
35
- const signatureSet = getVoluntaryExitSignatureSet(chain.config, state.slot, voluntaryExit);
35
+ const signatureSet = getVoluntaryExitSignatureSet(chain.config, new BeaconStateView(state), voluntaryExit);
36
36
  if (!(await chain.bls.verifySignatureSets([signatureSet], { batchable: true, priority: prioritizeBls }))) {
37
37
  throw new VoluntaryExitError(GossipAction.REJECT, {
38
38
  code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
@@ -1 +1 @@
1
- {"version":3,"file":"voluntaryExit.js","sourceRoot":"","sources":["../../../src/chain/validation/voluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,gCAAgC,GACjC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAmB,EACnB,aAAyC,EAC1B;IACf,MAAM,aAAa,GAAG,IAAI,CAAC;IAC3B,OAAO,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;AAAA,CACnE;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAmB,EACnB,aAAyC,EAC1B;IACf,OAAO,qBAAqB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAAA,CACpD;AAED,KAAK,UAAU,qBAAqB,CAClC,KAAmB,EACnB,aAAyC,EACzC,aAAa,GAAG,KAAK,EACN;IACf,sGAAsG;IACtG,iDAAiD;IACjD,IAAI,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,sBAAsB,CAAC,cAAc;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,wDAAwD;IACxD,EAAE;IACF,gFAAgF;IAChF,6DAA6D;IAC7D,sGAAsG;IACtG,kGAAkG;IAClG,6CAA6C;IAC7C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,0BAA0B,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC;IAE9F,gFAAgF;IAChF,mDAAmD;IACnD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IAC5G,IAAI,QAAQ,KAAK,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAC7C,MAAM,IAAI,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,gCAAgC,CAAC,QAAQ,CAAC;SACjD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,4BAA4B,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC3F,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAAE,EAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,sBAAsB,CAAC,iBAAiB;SAC/C,CAAC,CAAC;IACL,CAAC;AAAA,CACF"}
1
+ {"version":3,"file":"voluntaryExit.js","sourceRoot":"","sources":["../../../src/chain/validation/voluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,gCAAgC,GACjC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAmB,EACnB,aAAyC,EAC1B;IACf,MAAM,aAAa,GAAG,IAAI,CAAC;IAC3B,OAAO,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;AAAA,CACnE;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAmB,EACnB,aAAyC,EAC1B;IACf,OAAO,qBAAqB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAAA,CACpD;AAED,KAAK,UAAU,qBAAqB,CAClC,KAAmB,EACnB,aAAyC,EACzC,aAAa,GAAG,KAAK,EACN;IACf,sGAAsG;IACtG,iDAAiD;IACjD,IAAI,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,sBAAsB,CAAC,cAAc;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,wDAAwD;IACxD,EAAE;IACF,gFAAgF;IAChF,6DAA6D;IAC7D,sGAAsG;IACtG,kGAAkG;IAClG,6CAA6C;IAC7C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,0BAA0B,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC;IAE9F,gFAAgF;IAChF,mDAAmD;IACnD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IAC5G,IAAI,QAAQ,KAAK,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAC7C,MAAM,IAAI,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,gCAAgC,CAAC,QAAQ,CAAC;SACjD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,4BAA4B,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC;IAC3G,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAAE,EAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,IAAI,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE;YAChD,IAAI,EAAE,sBAAsB,CAAC,iBAAiB;SAC/C,CAAC,CAAC;IACL,CAAC;AAAA,CACF"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.41.0-rc.2",
14
+ "version": "1.42.0-dev.5f2fffc2ce",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -135,18 +135,18 @@
135
135
  "@libp2p/peer-id": "^6.0.4",
136
136
  "@libp2p/prometheus-metrics": "^5.0.14",
137
137
  "@libp2p/tcp": "^11.0.13",
138
- "@lodestar/api": "^1.41.0-rc.2",
139
- "@lodestar/config": "^1.41.0-rc.2",
140
- "@lodestar/db": "^1.41.0-rc.2",
141
- "@lodestar/fork-choice": "^1.41.0-rc.2",
142
- "@lodestar/light-client": "^1.41.0-rc.2",
143
- "@lodestar/logger": "^1.41.0-rc.2",
144
- "@lodestar/params": "^1.41.0-rc.2",
145
- "@lodestar/reqresp": "^1.41.0-rc.2",
146
- "@lodestar/state-transition": "^1.41.0-rc.2",
147
- "@lodestar/types": "^1.41.0-rc.2",
148
- "@lodestar/utils": "^1.41.0-rc.2",
149
- "@lodestar/validator": "^1.41.0-rc.2",
138
+ "@lodestar/api": "^1.42.0-dev.5f2fffc2ce",
139
+ "@lodestar/config": "^1.42.0-dev.5f2fffc2ce",
140
+ "@lodestar/db": "^1.42.0-dev.5f2fffc2ce",
141
+ "@lodestar/fork-choice": "^1.42.0-dev.5f2fffc2ce",
142
+ "@lodestar/light-client": "^1.42.0-dev.5f2fffc2ce",
143
+ "@lodestar/logger": "^1.42.0-dev.5f2fffc2ce",
144
+ "@lodestar/params": "^1.42.0-dev.5f2fffc2ce",
145
+ "@lodestar/reqresp": "^1.42.0-dev.5f2fffc2ce",
146
+ "@lodestar/state-transition": "^1.42.0-dev.5f2fffc2ce",
147
+ "@lodestar/types": "^1.42.0-dev.5f2fffc2ce",
148
+ "@lodestar/utils": "^1.42.0-dev.5f2fffc2ce",
149
+ "@lodestar/validator": "^1.42.0-dev.5f2fffc2ce",
150
150
  "@multiformats/multiaddr": "^13.0.1",
151
151
  "datastore-core": "^11.0.2",
152
152
  "datastore-fs": "^11.0.2",
@@ -169,7 +169,7 @@
169
169
  "@libp2p/interface-internal": "^3.0.13",
170
170
  "@libp2p/logger": "^6.2.2",
171
171
  "@libp2p/utils": "^7.0.13",
172
- "@lodestar/spec-test-util": "^1.41.0-rc.2",
172
+ "@lodestar/spec-test-util": "^1.42.0-dev.5f2fffc2ce",
173
173
  "@types/js-yaml": "^4.0.5",
174
174
  "@types/qs": "^6.9.7",
175
175
  "@types/tmp": "^0.2.3",
@@ -186,5 +186,5 @@
186
186
  "beacon",
187
187
  "blockchain"
188
188
  ],
189
- "gitHead": "2e49073e97b7449c7a70b60e144275497799ea7e"
189
+ "gitHead": "6190f82ce7dc565e0878bd4b743b13870465469e"
190
190
  }
@@ -1,5 +1,5 @@
1
1
  import {routes} from "@lodestar/api";
2
- import {CheckpointWithHex, IForkChoice} from "@lodestar/fork-choice";
2
+ import {CheckpointWithPayloadStatus, IForkChoice} from "@lodestar/fork-choice";
3
3
  import {GENESIS_SLOT} from "@lodestar/params";
4
4
  import {BeaconStateAllForks, CachedBeaconStateAllForks, PubkeyCache} from "@lodestar/state-transition";
5
5
  import {
@@ -19,7 +19,7 @@ import {ApiError, ValidationError} from "../../errors.js";
19
19
  export function resolveStateId(
20
20
  forkChoice: IForkChoice,
21
21
  stateId: routes.beacon.StateId
22
- ): RootHex | Slot | CheckpointWithHex {
22
+ ): RootHex | Slot | CheckpointWithPayloadStatus {
23
23
  if (stateId === "head") {
24
24
  return forkChoice.getHead().stateRoot;
25
25
  }
@@ -74,7 +74,7 @@ import {ChainEvent, CommonBlockBody} from "../../../chain/index.js";
74
74
  import {PREPARE_NEXT_SLOT_BPS} from "../../../chain/prepareNextSlot.js";
75
75
  import {BlockType, ProduceFullDeneb, ProduceFullGloas} from "../../../chain/produceBlock/index.js";
76
76
  import {RegenCaller} from "../../../chain/regen/index.js";
77
- import {CheckpointHex} from "../../../chain/stateCache/types.js";
77
+ import {CheckpointHexPayload} from "../../../chain/stateCache/types.js";
78
78
  import {validateApiAggregateAndProof} from "../../../chain/validation/index.js";
79
79
  import {validateSyncCommitteeGossipContributionAndProof} from "../../../chain/validation/syncCommitteeContributionAndProof.js";
80
80
  import {ZERO_HASH} from "../../../constants/index.js";
@@ -303,7 +303,7 @@ export function getValidatorApi(
303
303
  * |
304
304
  * prepareNextSlot (4s before next slot)
305
305
  */
306
- async function waitForCheckpointState(cpHex: CheckpointHex): Promise<CachedBeaconStateAllForks | null> {
306
+ async function waitForCheckpointState(cpHex: CheckpointHexPayload): Promise<CachedBeaconStateAllForks | null> {
307
307
  const cpState = chain.regen.getCheckpointStateSync(cpHex);
308
308
  if (cpState) {
309
309
  return cpState;
@@ -1112,7 +1112,11 @@ export function getValidatorApi(
1112
1112
  // this is to avoid missed block proposal due to 0 epoch look ahead
1113
1113
  if (epoch === nextEpoch && toNextEpochMs < prepareNextSlotLookAheadMs) {
1114
1114
  // wait for maximum 1 slot for cp state which is the timeout of validator api
1115
- const cpState = await waitForCheckpointState({rootHex: head.blockRoot, epoch});
1115
+ const cpState = await waitForCheckpointState({
1116
+ rootHex: head.blockRoot,
1117
+ epoch,
1118
+ payloadPresent: head.payloadStatus === PayloadStatus.FULL,
1119
+ });
1116
1120
  if (cpState) {
1117
1121
  state = cpState;
1118
1122
  metrics?.duties.requestNextEpochProposalDutiesHit.inc();
@@ -1,6 +1,5 @@
1
1
  import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
2
2
  import {LoggerNode} from "@lodestar/logger/node";
3
- import {ForkSeq} from "@lodestar/params";
4
3
  import {Checkpoint} from "@lodestar/types/phase0";
5
4
  import {callFnWhenAwait} from "@lodestar/utils";
6
5
  import {IBeaconDb} from "../../db/index.js";
@@ -14,7 +13,6 @@ import {HistoricalStateRegen} from "./historicalState/historicalStateRegen.js";
14
13
  import {ArchiveMode, ArchiveStoreOpts, StateArchiveStrategy} from "./interface.js";
15
14
  import {FrequencyStateArchiveStrategy} from "./strategies/frequencyStateArchiveStrategy.js";
16
15
  import {archiveBlocks} from "./utils/archiveBlocks.js";
17
- import {archiveExecutionPayloadEnvelopes} from "./utils/archivePayloads.js";
18
16
  import {pruneHistory} from "./utils/pruneHistory.js";
19
17
  import {updateBackfillRange} from "./utils/updateBackfillRange.js";
20
18
 
@@ -29,7 +27,6 @@ type ArchiveStoreInitOpts = ArchiveStoreOpts & {dbName: string; anchorState: {fi
29
27
 
30
28
  export enum ArchiveStoreTask {
31
29
  ArchiveBlocks = "archive_blocks",
32
- ArchivePayloads = "archive_payloads",
33
30
  PruneHistory = "prune_history",
34
31
  OnFinalizedCheckpoint = "on_finalized_checkpoint",
35
32
  MaybeArchiveState = "maybe_archive_state",
@@ -192,7 +189,6 @@ export class ArchiveStore {
192
189
  private processFinalizedCheckpoint = async (finalized: CheckpointWithPayloadStatus): Promise<void> => {
193
190
  try {
194
191
  const finalizedEpoch = finalized.epoch;
195
- const finalizedFork = this.chain.config.getForkSeqAtEpoch(finalizedEpoch);
196
192
  this.logger.verbose("Start processing finalized checkpoint", {epoch: finalizedEpoch, rootHex: finalized.rootHex});
197
193
 
198
194
  let timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
@@ -210,12 +206,6 @@ export class ArchiveStore {
210
206
  );
211
207
  timer?.({source: ArchiveStoreTask.ArchiveBlocks});
212
208
 
213
- if (finalizedFork >= ForkSeq.gloas) {
214
- timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
215
- await archiveExecutionPayloadEnvelopes(this.chain, finalized);
216
- timer?.({source: ArchiveStoreTask.ArchivePayloads});
217
- }
218
-
219
209
  if (this.opts.pruneHistory) {
220
210
  timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
221
211
  await pruneHistory(
@@ -1,4 +1,4 @@
1
- import {CheckpointWithHex} from "@lodestar/fork-choice";
1
+ import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
2
2
  import {RootHex} from "@lodestar/types";
3
3
  import {Metrics} from "../../metrics/metrics.js";
4
4
 
@@ -44,9 +44,9 @@ export type FinalizedStats = {
44
44
 
45
45
  export interface StateArchiveStrategy {
46
46
  onCheckpoint(stateRoot: RootHex, metrics?: Metrics | null): Promise<void>;
47
- onFinalizedCheckpoint(finalized: CheckpointWithHex, metrics?: Metrics | null): Promise<void>;
48
- maybeArchiveState(finalized: CheckpointWithHex, metrics?: Metrics | null): Promise<void>;
49
- archiveState(finalized: CheckpointWithHex, metrics?: Metrics | null): Promise<void>;
47
+ onFinalizedCheckpoint(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void>;
48
+ maybeArchiveState(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void>;
49
+ archiveState(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void>;
50
50
  }
51
51
 
52
52
  export interface IArchiveStore {
@@ -1,4 +1,4 @@
1
- import {CheckpointWithHex} from "@lodestar/fork-choice";
1
+ import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
2
2
  import {SLOTS_PER_EPOCH} from "@lodestar/params";
3
3
  import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
4
4
  import {Epoch, RootHex, Slot} from "@lodestar/types";
@@ -9,6 +9,7 @@ import {AllocSource, BufferPool} from "../../../util/bufferPool.js";
9
9
  import {getStateSlotFromBytes} from "../../../util/multifork.js";
10
10
  import {IStateRegenerator} from "../../regen/interface.js";
11
11
  import {serializeState} from "../../serializeState.js";
12
+ import {fcCheckpointToHexPayload} from "../../stateCache/persistentCheckpointsCache.js";
12
13
  import {StateArchiveStrategy, StatesArchiveOpts} from "../interface.js";
13
14
 
14
15
  /**
@@ -40,7 +41,7 @@ export class FrequencyStateArchiveStrategy implements StateArchiveStrategy {
40
41
  private readonly bufferPool?: BufferPool | null
41
42
  ) {}
42
43
 
43
- async onFinalizedCheckpoint(_finalized: CheckpointWithHex, _metrics?: Metrics | null): Promise<void> {}
44
+ async onFinalizedCheckpoint(_finalized: CheckpointWithPayloadStatus, _metrics?: Metrics | null): Promise<void> {}
44
45
  async onCheckpoint(_stateRoot: RootHex, _metrics?: Metrics | null): Promise<void> {}
45
46
 
46
47
  /**
@@ -55,7 +56,7 @@ export class FrequencyStateArchiveStrategy implements StateArchiveStrategy {
55
56
  * epoch - 1024*2 epoch - 1024 epoch - 32 epoch
56
57
  * ```
57
58
  */
58
- async maybeArchiveState(finalized: CheckpointWithHex, metrics?: Metrics | null): Promise<void> {
59
+ async maybeArchiveState(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void> {
59
60
  let timer = metrics?.processFinalizedCheckpoint.frequencyStateArchive.startTimer();
60
61
  const lastStoredSlot = await this.db.stateArchive.lastKey();
61
62
  timer?.({step: FrequencyStateArchiveStep.LoadLastStoredSlot});
@@ -104,10 +105,12 @@ export class FrequencyStateArchiveStrategy implements StateArchiveStrategy {
104
105
  * Archives finalized states from active bucket to archive bucket.
105
106
  * Only the new finalized state is stored to disk
106
107
  */
107
- async archiveState(finalized: CheckpointWithHex, metrics?: Metrics | null): Promise<void> {
108
+ async archiveState(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void> {
108
109
  // starting from Mar 2024, the finalized state could be from disk or in memory
109
110
  let timer = metrics?.processFinalizedCheckpoint.frequencyStateArchive.startTimer();
110
- const finalizedStateOrBytes = await this.regen.getCheckpointStateOrBytes(finalized);
111
+ // Convert fork-choice checkpoint to beacon-node checkpoint with payloadPresent
112
+ const finalizedHexPayload = fcCheckpointToHexPayload(finalized);
113
+ const finalizedStateOrBytes = await this.regen.getCheckpointStateOrBytes(finalizedHexPayload);
111
114
  timer?.({step: FrequencyStateArchiveStep.GetFinalizedState});
112
115
 
113
116
  const {rootHex} = finalized;
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
3
  import {KeyValue} from "@lodestar/db";
4
- import {CheckpointWithPayloadStatus, IForkChoice} from "@lodestar/fork-choice";
4
+ import {CheckpointWithPayloadStatus, IForkChoice, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
5
5
  import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
6
6
  import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
7
7
  import {Epoch, Slot} from "@lodestar/types";
@@ -66,6 +66,7 @@ export async function archiveBlocks(
66
66
  // NOTE: The finalized block will be exactly the first block of `epoch` or previous
67
67
  const finalizedPostDeneb = finalizedCheckpoint.epoch >= config.DENEB_FORK_EPOCH;
68
68
  const finalizedPostFulu = finalizedCheckpoint.epoch >= config.FULU_FORK_EPOCH;
69
+ const finalizedPostGloas = finalizedCheckpoint.epoch >= config.GLOAS_FORK_EPOCH;
69
70
 
70
71
  const finalizedCanonicalBlockRoots: BlockRootSlot[] = finalizedCanonicalBlocks.map((block) => ({
71
72
  slot: block.slot,
@@ -103,6 +104,16 @@ export async function archiveBlocks(
103
104
  );
104
105
  logger.verbose("Migrated dataColumnSidecars from hot DB to cold DB", {...logCtx, migratedEntries});
105
106
  }
107
+
108
+ if (finalizedPostGloas) {
109
+ const migratedEntries = await migrateExecutionPayloadEnvelopesFromHotToColdDb(
110
+ config,
111
+ db,
112
+ logger,
113
+ finalizedCanonicalBlocks
114
+ );
115
+ logger.verbose("Migrated executionPayloadEnvelopes from hot DB to cold DB", {...logCtx, migratedEntries});
116
+ }
106
117
  }
107
118
 
108
119
  // deleteNonCanonicalBlocks
@@ -144,6 +155,11 @@ export async function archiveBlocks(
144
155
  await db.dataColumnSidecar.deleteMany(nonCanonicalBlockRoots);
145
156
  logger.verbose("Deleted non canonical dataColumnSidecars from hot DB", logCtx);
146
157
  }
158
+
159
+ if (finalizedPostGloas) {
160
+ await db.executionPayloadEnvelope.batchDelete(nonCanonicalBlockRoots);
161
+ logger.verbose("Deleted non canonical executionPayloadEnvelopes from hot DB", logCtx);
162
+ }
147
163
  }
148
164
 
149
165
  // Delete expired blobs
@@ -372,6 +388,48 @@ async function migrateDataColumnSidecarsFromHotToColdDb(
372
388
  return migratedWrappedDataColumns;
373
389
  }
374
390
 
391
+ async function migrateExecutionPayloadEnvelopesFromHotToColdDb(
392
+ config: ChainForkConfig,
393
+ db: IBeaconDb,
394
+ logger: Logger,
395
+ canonicalBlocks: ProtoBlock[]
396
+ ): Promise<number> {
397
+ let migratedEnvelopes = 0;
398
+
399
+ const payloadBlocks = canonicalBlocks.filter(
400
+ (block) => config.getForkSeq(block.slot) >= ForkSeq.gloas && block.payloadStatus === PayloadStatus.FULL
401
+ );
402
+ if (payloadBlocks.length === 0) return 0;
403
+ const blocks = payloadBlocks.map((block) => ({slot: block.slot, root: fromHex(block.blockRoot)}));
404
+
405
+ const envelopeEntries: KeyValue<Slot, Uint8Array>[] = [];
406
+ const migratedRoots: Uint8Array[] = [];
407
+
408
+ const envelopeBytesArray = await Promise.all(
409
+ blocks.map((block) => db.executionPayloadEnvelope.getBinary(block.root))
410
+ );
411
+
412
+ for (let i = 0; i < blocks.length; i++) {
413
+ const bytes = envelopeBytesArray[i];
414
+ if (bytes !== null) {
415
+ envelopeEntries.push({key: blocks[i].slot, value: bytes});
416
+ migratedRoots.push(blocks[i].root);
417
+ } else {
418
+ logger.debug("Payload in forkchoice but missing in db", {slot: blocks[i].slot, root: toRootHex(blocks[i].root)});
419
+ }
420
+ }
421
+
422
+ if (envelopeEntries.length > 0) {
423
+ await Promise.all([
424
+ db.executionPayloadEnvelopeArchive.batchPutBinary(envelopeEntries),
425
+ db.executionPayloadEnvelope.batchDelete(migratedRoots),
426
+ ]);
427
+ migratedEnvelopes = envelopeEntries.length;
428
+ }
429
+
430
+ return migratedEnvelopes;
431
+ }
432
+
375
433
  /**
376
434
  * ```
377
435
  * class SignedBeaconBlock(Container):
@@ -7,6 +7,7 @@ import {
7
7
  ForkChoiceErrorCode,
8
8
  NotReorgedReason,
9
9
  getSafeExecutionBlockHash,
10
+ isGloasBlock,
10
11
  } from "@lodestar/fork-choice";
11
12
  import {ForkPostAltair, ForkPostElectra, ForkSeq, MAX_SEED_LOOKAHEAD, SLOTS_PER_EPOCH} from "@lodestar/params";
12
13
  import {
@@ -30,7 +31,7 @@ import type {BeaconChain} from "../chain.js";
30
31
  import {ChainEvent, ReorgEventData} from "../emitter.js";
31
32
  import {ForkchoiceCaller} from "../forkChoice/index.js";
32
33
  import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_SEC} from "../reprocess.js";
33
- import {toCheckpointHex} from "../stateCache/persistentCheckpointsCache.js";
34
+ import {toCheckpointHexPayload} from "../stateCache/persistentCheckpointsCache.js";
34
35
  import {isBlockInputBlobs, isBlockInputColumns} from "./blockInput/blockInput.js";
35
36
  import {AttestationImportOpt, FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
36
37
  import {getCheckpointFromState} from "./utils/checkpoint.js";
@@ -116,7 +117,11 @@ export async function importBlock(
116
117
 
117
118
  // This adds the state necessary to process the next block
118
119
  // Some block event handlers require state being in state cache so need to do this before emitting EventType.block
119
- this.regen.processState(blockRootHex, postState);
120
+ // Pre-Gloas: blockSummary.payloadStatus is always FULL, payloadPresent = true
121
+ // Post-Gloas: blockSummary.payloadStatus is always PENDING, so payloadPresent = false (block state only, no payload processing yet)
122
+ const payloadPresent = !isGloasBlock(blockSummary);
123
+ // processState manages both block state and payload state variants together for memory/disk management
124
+ this.regen.processBlockState(blockRootHex, postState);
120
125
 
121
126
  this.metrics?.importBlock.bySource.inc({source: source.source});
122
127
  this.logger.verbose("Added block to forkchoice and state cache", {slot: blockSlot, root: blockRootHex});
@@ -456,12 +461,12 @@ export async function importBlock(
456
461
  // Cache state to preserve epoch transition work
457
462
  const checkpointState = postState;
458
463
  const cp = getCheckpointFromState(checkpointState);
459
- this.regen.addCheckpointState(cp, checkpointState);
464
+ this.regen.addCheckpointState(cp, checkpointState, payloadPresent);
460
465
  // consumers should not mutate state ever
461
466
  this.emitter.emit(ChainEvent.checkpoint, cp, checkpointState);
462
467
 
463
468
  // Note: in-lined code from previos handler of ChainEvent.checkpoint
464
- this.logger.verbose("Checkpoint processed", toCheckpointHex(cp));
469
+ this.logger.verbose("Checkpoint processed", toCheckpointHexPayload(cp, payloadPresent));
465
470
 
466
471
  const activeValidatorsCount = checkpointState.epochCtx.currentShuffling.activeIndices.length;
467
472
  this.metrics?.currentActiveValidators.set(activeValidatorsCount);
@@ -479,7 +484,7 @@ export async function importBlock(
479
484
  const justifiedEpoch = justifiedCheckpoint.epoch;
480
485
  const preJustifiedEpoch = parentBlockSummary.justifiedEpoch;
481
486
  if (justifiedEpoch > preJustifiedEpoch) {
482
- this.logger.verbose("Checkpoint justified", toCheckpointHex(justifiedCheckpoint));
487
+ this.logger.verbose("Checkpoint justified", toCheckpointHexPayload(justifiedCheckpoint, payloadPresent));
483
488
  this.metrics?.previousJustifiedEpoch.set(checkpointState.previousJustifiedCheckpoint.epoch);
484
489
  this.metrics?.currentJustifiedEpoch.set(justifiedCheckpoint.epoch);
485
490
  }
@@ -493,7 +498,7 @@ export async function importBlock(
493
498
  state: toRootHex(checkpointState.hashTreeRoot()),
494
499
  executionOptimistic: false,
495
500
  });
496
- this.logger.verbose("Checkpoint finalized", toCheckpointHex(finalizedCheckpoint));
501
+ this.logger.verbose("Checkpoint finalized", toCheckpointHexPayload(finalizedCheckpoint, payloadPresent));
497
502
  this.metrics?.finalizedEpoch.set(finalizedCheckpoint.epoch);
498
503
  }
499
504
  }
@@ -41,7 +41,7 @@ export async function verifyBlocksSignatures(
41
41
  : //
42
42
  // Verify signatures per block to track which block is invalid
43
43
  bls.verifySignatureSets(
44
- getBlockSignatureSets(config, currentSyncCommitteeIndexed, block, indexedAttestationsByBlock[i], {
44
+ getBlockSignatureSets(config, currentSyncCommitteeIndexed, preState0, block, indexedAttestationsByBlock[i], {
45
45
  skipProposerSignature: opts.validProposerSignature,
46
46
  })
47
47
  );
@@ -3,11 +3,12 @@ import {PrivateKey} from "@libp2p/interface";
3
3
  import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
4
4
  import {BeaconConfig} from "@lodestar/config";
5
5
  import {
6
- CheckpointWithHex,
7
6
  CheckpointWithPayloadStatus,
8
7
  IForkChoice,
8
+ PayloadStatus,
9
9
  ProtoBlock,
10
10
  UpdateHeadOpt,
11
+ getCheckpointPayloadStatus,
11
12
  } from "@lodestar/fork-choice";
12
13
  import {LoggerNode} from "@lodestar/logger/node";
13
14
  import {
@@ -126,7 +127,7 @@ import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datasto
126
127
  import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
127
128
  import {CPStateDatastore} from "./stateCache/datastore/types.js";
128
129
  import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
129
- import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
130
+ import {PersistentCheckpointStateCache, fcCheckpointToHexPayload} from "./stateCache/persistentCheckpointsCache.js";
130
131
  import {CheckpointStateCache} from "./stateCache/types.js";
131
132
  import {ValidatorMonitor} from "./validatorMonitor.js";
132
133
 
@@ -375,7 +376,8 @@ export class BeaconChain implements IBeaconChain {
375
376
  const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
376
377
  blockStateCache.add(anchorState);
377
378
  blockStateCache.setHeadState(anchorState);
378
- checkpointStateCache.add(checkpoint, anchorState);
379
+ const payloadPresent = getCheckpointPayloadStatus(anchorState, checkpoint.epoch) === PayloadStatus.FULL;
380
+ checkpointStateCache.add(checkpoint, anchorState, payloadPresent);
379
381
 
380
382
  const forkChoice = initializeForkChoice(
381
383
  config,
@@ -648,15 +650,18 @@ export class BeaconChain implements IBeaconChain {
648
650
  return this.cpStateDatastore.readLatestSafe();
649
651
  }
650
652
 
651
- const persistedKey = checkpointToDatastoreKey(checkpoint);
653
+ // TODO GLOAS: Need to revisit the design of this api. Currently we just retrieve FULL state of the checkpoint for backwards compatibility.
654
+ // because pre-gloas we always store FULL checkpoint state.
655
+ const persistedKey = checkpointToDatastoreKey(checkpoint, true);
652
656
  return this.cpStateDatastore.read(persistedKey);
653
657
  }
654
658
 
655
659
  getStateByCheckpoint(
656
- checkpoint: CheckpointWithHex
660
+ checkpoint: CheckpointWithPayloadStatus
657
661
  ): {state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null {
658
662
  // finalized or justified checkpoint states maynot be available with PersistentCheckpointStateCache, use getCheckpointStateOrBytes() api to get Uint8Array
659
- const cachedStateCtx = this.regen.getCheckpointStateSync(checkpoint);
663
+ const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
664
+ const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHexPayload);
660
665
  if (cachedStateCtx) {
661
666
  const block = this.forkChoice.getBlockDefaultStatus(cachedStateCtx.latestBlockHeader.hashTreeRoot());
662
667
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
@@ -671,9 +676,10 @@ export class BeaconChain implements IBeaconChain {
671
676
  }
672
677
 
673
678
  async getStateOrBytesByCheckpoint(
674
- checkpoint: CheckpointWithHex
679
+ checkpoint: CheckpointWithPayloadStatus
675
680
  ): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
676
- const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpoint);
681
+ const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
682
+ const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHexPayload);
677
683
  if (cachedStateCtx) {
678
684
  const block = this.forkChoice.getBlockDefaultStatus(checkpoint.root);
679
685
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
@@ -1236,7 +1242,8 @@ export class BeaconChain implements IBeaconChain {
1236
1242
  checkpoint: CheckpointWithPayloadStatus,
1237
1243
  blockState: CachedBeaconStateAllForks
1238
1244
  ): {state: CachedBeaconStateAllForks; stateId: string; shouldWarn: boolean} {
1239
- const state = this.regen.getCheckpointStateSync(checkpoint);
1245
+ const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
1246
+ const state = this.regen.getCheckpointStateSync(checkpointHexPayload);
1240
1247
  if (state) {
1241
1248
  return {state, stateId: "checkpoint_state", shouldWarn: false};
1242
1249
  }
@@ -1363,6 +1370,10 @@ export class BeaconChain implements IBeaconChain {
1363
1370
  private onClockEpoch(epoch: Epoch): void {
1364
1371
  this.metrics?.clockEpoch.set(epoch);
1365
1372
 
1373
+ if (epoch === this.config.GLOAS_FORK_EPOCH) {
1374
+ this.regen.upgradeForGloas(epoch);
1375
+ }
1376
+
1366
1377
  this.seenAttesters.prune(epoch);
1367
1378
  this.seenAggregators.prune(epoch);
1368
1379
  this.seenPayloadAttesters.prune(epoch);
@@ -1376,7 +1387,7 @@ export class BeaconChain implements IBeaconChain {
1376
1387
  this.seenContributionAndProof.prune(head.slot);
1377
1388
  }
1378
1389
 
1379
- private onForkChoiceJustified(this: BeaconChain, cp: CheckpointWithHex): void {
1390
+ private onForkChoiceJustified(this: BeaconChain, cp: CheckpointWithPayloadStatus): void {
1380
1391
  this.logger.verbose("Fork choice justified", {epoch: cp.epoch, root: cp.rootHex});
1381
1392
  }
1382
1393
 
@@ -1387,7 +1398,7 @@ export class BeaconChain implements IBeaconChain {
1387
1398
  });
1388
1399
  }
1389
1400
 
1390
- private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithHex): Promise<void> {
1401
+ private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithPayloadStatus): Promise<void> {
1391
1402
  this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
1392
1403
  const finalizedSlot = computeStartSlotAtEpoch(cp.epoch);
1393
1404
  this.seenBlockProposers.prune(finalizedSlot);
@@ -1429,7 +1440,7 @@ export class BeaconChain implements IBeaconChain {
1429
1440
  }
1430
1441
  }
1431
1442
 
1432
- private async updateValidatorsCustodyRequirement(finalizedCheckpoint: CheckpointWithHex): Promise<void> {
1443
+ private async updateValidatorsCustodyRequirement(finalizedCheckpoint: CheckpointWithPayloadStatus): Promise<void> {
1433
1444
  if (this.custodyConfig.targetCustodyGroupCount === this.config.NUMBER_OF_CUSTODY_GROUPS) {
1434
1445
  // Custody requirements can only be increased, we can disable dynamic custody updates
1435
1446
  // if the node already maintains custody of all custody groups in case it is configured
@@ -1,6 +1,6 @@
1
1
  import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
- import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
3
+ import {CheckpointWithHex, CheckpointWithPayloadStatus, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
4
4
  import {BeaconStateAllForks, CachedBeaconStateAllForks, EpochShuffling, PubkeyCache} from "@lodestar/state-transition";
5
5
  import {
6
6
  BeaconBlock,
@@ -192,7 +192,7 @@ export interface IBeaconChain {
192
192
  ): {state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null;
193
193
  /** Return state bytes by checkpoint */
194
194
  getStateOrBytesByCheckpoint(
195
- checkpoint: CheckpointWithHex
195
+ checkpoint: CheckpointWithPayloadStatus
196
196
  ): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null>;
197
197
 
198
198
  /**
@@ -1,6 +1,6 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
- import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
3
+ import {PayloadStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
4
4
  import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
5
5
  import {
6
6
  CachedBeaconStateAllForks,
@@ -211,7 +211,11 @@ export class PrepareNextSlotScheduler {
211
211
  // + if next slot is a skipped slot, it'd help getting target checkpoint state faster to validate attestations
212
212
  if (isEpochTransition) {
213
213
  this.metrics?.precomputeNextEpochTransition.count.inc({result: "success"}, 1);
214
- const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch);
214
+ // Determine payloadPresent from head block's payload status
215
+ // Pre-Gloas: payloadStatus is always FULL → payloadPresent = true
216
+ // Post-Gloas: FULL → true, EMPTY → false, PENDING → false (conservative, treat as block state)
217
+ const payloadPresent = headBlock.payloadStatus === PayloadStatus.FULL;
218
+ const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch, payloadPresent);
215
219
  if (previousHits === 0) {
216
220
  this.metrics?.precomputeNextEpochTransition.waste.inc();
217
221
  }