@lodestar/beacon-node 1.39.0-dev.aceb5b7416 → 1.39.0-dev.ad129ced66

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 (246) hide show
  1. package/README.md +1 -1
  2. package/lib/api/impl/beacon/state/utils.d.ts +2 -7
  3. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  4. package/lib/api/impl/beacon/state/utils.js +0 -12
  5. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  6. package/lib/api/impl/lodestar/index.js +1 -1
  7. package/lib/api/impl/lodestar/index.js.map +1 -1
  8. package/lib/api/impl/proof/index.d.ts.map +1 -1
  9. package/lib/api/impl/proof/index.js +1 -2
  10. package/lib/api/impl/proof/index.js.map +1 -1
  11. package/lib/api/impl/validator/index.d.ts.map +1 -1
  12. package/lib/api/impl/validator/index.js +1 -3
  13. package/lib/api/impl/validator/index.js.map +1 -1
  14. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  15. package/lib/chain/blocks/importBlock.js +8 -2
  16. package/lib/chain/blocks/importBlock.js.map +1 -1
  17. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  18. package/lib/chain/blocks/verifyBlock.js +1 -1
  19. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  20. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  21. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -2
  22. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  23. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -1
  24. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  25. package/lib/chain/blocks/verifyBlocksSignatures.js +3 -2
  26. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  27. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  28. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -0
  29. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  30. package/lib/chain/chain.d.ts +11 -11
  31. package/lib/chain/chain.d.ts.map +1 -1
  32. package/lib/chain/chain.js +36 -40
  33. package/lib/chain/chain.js.map +1 -1
  34. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  35. package/lib/chain/forkChoice/index.js +3 -3
  36. package/lib/chain/forkChoice/index.js.map +1 -1
  37. package/lib/chain/interface.d.ts +6 -9
  38. package/lib/chain/interface.d.ts.map +1 -1
  39. package/lib/chain/interface.js.map +1 -1
  40. package/lib/chain/lightClient/proofs.d.ts.map +1 -1
  41. package/lib/chain/lightClient/proofs.js +0 -2
  42. package/lib/chain/lightClient/proofs.js.map +1 -1
  43. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +6 -7
  44. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  45. package/lib/chain/opPools/aggregatedAttestationPool.js +8 -133
  46. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  47. package/lib/chain/opPools/opPool.d.ts +3 -0
  48. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  49. package/lib/chain/opPools/opPool.js +9 -8
  50. package/lib/chain/opPools/opPool.js.map +1 -1
  51. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  52. package/lib/chain/prepareNextSlot.js +4 -7
  53. package/lib/chain/prepareNextSlot.js.map +1 -1
  54. package/lib/chain/produceBlock/produceBlockBody.js +3 -3
  55. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  56. package/lib/chain/regen/interface.d.ts +1 -5
  57. package/lib/chain/regen/interface.d.ts.map +1 -1
  58. package/lib/chain/regen/queued.d.ts +4 -7
  59. package/lib/chain/regen/queued.d.ts.map +1 -1
  60. package/lib/chain/regen/queued.js +15 -25
  61. package/lib/chain/regen/queued.js.map +1 -1
  62. package/lib/chain/regen/regen.d.ts +1 -1
  63. package/lib/chain/regen/regen.d.ts.map +1 -1
  64. package/lib/chain/regen/regen.js +13 -17
  65. package/lib/chain/regen/regen.js.map +1 -1
  66. package/lib/chain/shufflingCache.d.ts +5 -12
  67. package/lib/chain/shufflingCache.d.ts.map +1 -1
  68. package/lib/chain/shufflingCache.js +12 -50
  69. package/lib/chain/shufflingCache.js.map +1 -1
  70. package/lib/chain/stateCache/blockStateCacheImpl.d.ts +1 -2
  71. package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +1 -1
  72. package/lib/chain/stateCache/blockStateCacheImpl.js +2 -2
  73. package/lib/chain/stateCache/blockStateCacheImpl.js.map +1 -1
  74. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +1 -2
  75. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  76. package/lib/chain/stateCache/fifoBlockStateCache.js +4 -4
  77. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  78. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +4 -5
  79. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +1 -1
  80. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +9 -10
  81. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +1 -1
  82. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +9 -7
  83. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  84. package/lib/chain/stateCache/persistentCheckpointsCache.js +21 -19
  85. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  86. package/lib/chain/stateCache/types.d.ts +5 -6
  87. package/lib/chain/stateCache/types.d.ts.map +1 -1
  88. package/lib/chain/stateCache/types.js.map +1 -1
  89. package/lib/chain/validation/aggregateAndProof.js +9 -0
  90. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  91. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  92. package/lib/chain/validation/attesterSlashing.js +2 -2
  93. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  94. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  95. package/lib/chain/validation/blobSidecar.js +2 -3
  96. package/lib/chain/validation/blobSidecar.js.map +1 -1
  97. package/lib/chain/validation/block.d.ts.map +1 -1
  98. package/lib/chain/validation/block.js +3 -3
  99. package/lib/chain/validation/block.js.map +1 -1
  100. package/lib/chain/validation/blsToExecutionChange.d.ts.map +1 -1
  101. package/lib/chain/validation/blsToExecutionChange.js +10 -3
  102. package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
  103. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  104. package/lib/chain/validation/dataColumnSidecar.js +2 -3
  105. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  106. package/lib/chain/validation/proposerSlashing.js +3 -2
  107. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  108. package/lib/chain/validation/signatureSets/aggregateAndProof.js +1 -1
  109. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  110. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -1
  111. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  112. package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -2
  113. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  114. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -1
  115. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  116. package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
  117. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  118. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -1
  119. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  120. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  121. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  122. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -1
  123. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  124. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -2
  125. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  126. package/lib/chain/validation/syncCommittee.js +1 -1
  127. package/lib/chain/validation/syncCommittee.js.map +1 -1
  128. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  129. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -3
  130. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  131. package/lib/chain/validation/voluntaryExit.js +1 -1
  132. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  133. package/lib/db/beacon.d.ts +2 -0
  134. package/lib/db/beacon.d.ts.map +1 -1
  135. package/lib/db/beacon.js +32 -0
  136. package/lib/db/beacon.js.map +1 -1
  137. package/lib/db/buckets.d.ts +12 -0
  138. package/lib/db/buckets.d.ts.map +1 -1
  139. package/lib/db/buckets.js +12 -6
  140. package/lib/db/buckets.js.map +1 -1
  141. package/lib/db/interface.d.ts +1 -0
  142. package/lib/db/interface.d.ts.map +1 -1
  143. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  144. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  145. package/lib/db/repositories/stateArchive.d.ts +1 -1
  146. package/lib/db/repositories/stateArchive.d.ts.map +1 -1
  147. package/lib/db/repositories/stateArchive.js +2 -2
  148. package/lib/db/repositories/stateArchive.js.map +1 -1
  149. package/lib/execution/engine/mock.d.ts +9 -6
  150. package/lib/execution/engine/mock.d.ts.map +1 -1
  151. package/lib/execution/engine/mock.js +34 -7
  152. package/lib/execution/engine/mock.js.map +1 -1
  153. package/lib/metrics/metrics/lodestar.d.ts +1 -6
  154. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  155. package/lib/metrics/metrics/lodestar.js +3 -17
  156. package/lib/metrics/metrics/lodestar.js.map +1 -1
  157. package/lib/network/peers/discover.d.ts.map +1 -1
  158. package/lib/network/peers/discover.js.map +1 -1
  159. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +1 -1
  160. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  161. package/lib/node/nodejs.d.ts +6 -3
  162. package/lib/node/nodejs.d.ts.map +1 -1
  163. package/lib/node/nodejs.js +30 -3
  164. package/lib/node/nodejs.js.map +1 -1
  165. package/lib/node/notifier.d.ts.map +1 -1
  166. package/lib/node/notifier.js +9 -6
  167. package/lib/node/notifier.js.map +1 -1
  168. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  169. package/lib/sync/backfill/backfill.js +2 -4
  170. package/lib/sync/backfill/backfill.js.map +1 -1
  171. package/lib/sync/backfill/verify.d.ts +2 -2
  172. package/lib/sync/backfill/verify.d.ts.map +1 -1
  173. package/lib/sync/backfill/verify.js +3 -3
  174. package/lib/sync/backfill/verify.js.map +1 -1
  175. package/lib/util/sszBytes.js +1 -1
  176. package/lib/util/sszBytes.js.map +1 -1
  177. package/package.json +28 -20
  178. package/src/api/impl/beacon/state/utils.ts +2 -22
  179. package/src/api/impl/lodestar/index.ts +1 -1
  180. package/src/api/impl/proof/index.ts +1 -2
  181. package/src/api/impl/validator/index.ts +1 -3
  182. package/src/chain/blocks/importBlock.ts +9 -2
  183. package/src/chain/blocks/verifyBlock.ts +1 -0
  184. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
  185. package/src/chain/blocks/verifyBlocksSignatures.ts +13 -3
  186. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -0
  187. package/src/chain/chain.ts +50 -48
  188. package/src/chain/forkChoice/index.ts +3 -2
  189. package/src/chain/interface.ts +6 -8
  190. package/src/chain/lightClient/proofs.ts +0 -2
  191. package/src/chain/opPools/aggregatedAttestationPool.ts +12 -187
  192. package/src/chain/opPools/opPool.ts +8 -8
  193. package/src/chain/prepareNextSlot.ts +2 -6
  194. package/src/chain/produceBlock/produceBlockBody.ts +3 -3
  195. package/src/chain/regen/interface.ts +1 -5
  196. package/src/chain/regen/queued.ts +15 -34
  197. package/src/chain/regen/regen.ts +12 -18
  198. package/src/chain/shufflingCache.ts +15 -61
  199. package/src/chain/stateCache/blockStateCacheImpl.ts +2 -3
  200. package/src/chain/stateCache/fifoBlockStateCache.ts +4 -5
  201. package/src/chain/stateCache/inMemoryCheckpointsCache.ts +9 -15
  202. package/src/chain/stateCache/persistentCheckpointsCache.ts +32 -27
  203. package/src/chain/stateCache/types.ts +5 -10
  204. package/src/chain/validation/aggregateAndProof.ts +12 -0
  205. package/src/chain/validation/attesterSlashing.ts +14 -2
  206. package/src/chain/validation/blobSidecar.ts +3 -3
  207. package/src/chain/validation/block.ts +3 -2
  208. package/src/chain/validation/blsToExecutionChange.ts +10 -8
  209. package/src/chain/validation/dataColumnSidecar.ts +3 -3
  210. package/src/chain/validation/proposerSlashing.ts +8 -2
  211. package/src/chain/validation/signatureSets/aggregateAndProof.ts +1 -1
  212. package/src/chain/validation/signatureSets/contributionAndProof.ts +3 -1
  213. package/src/chain/validation/signatureSets/syncCommittee.ts +3 -1
  214. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +3 -1
  215. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -1
  216. package/src/chain/validation/syncCommittee.ts +1 -1
  217. package/src/chain/validation/syncCommitteeContributionAndProof.ts +8 -3
  218. package/src/chain/validation/voluntaryExit.ts +1 -1
  219. package/src/db/beacon.ts +38 -1
  220. package/src/db/buckets.ts +12 -6
  221. package/src/db/interface.ts +2 -0
  222. package/src/db/repositories/stateArchive.ts +2 -2
  223. package/src/execution/engine/mock.ts +40 -13
  224. package/src/metrics/metrics/lodestar.ts +3 -17
  225. package/src/network/peers/discover.ts +3 -3
  226. package/src/network/reqresp/utils/dataColumnResponseValidation.ts +1 -1
  227. package/src/node/nodejs.ts +37 -4
  228. package/src/node/notifier.ts +13 -7
  229. package/src/sync/backfill/backfill.ts +2 -9
  230. package/src/sync/backfill/verify.ts +3 -8
  231. package/src/util/sszBytes.ts +1 -1
  232. package/lib/chain/rewards/attestationsRewards.d.ts +0 -7
  233. package/lib/chain/rewards/attestationsRewards.d.ts.map +0 -1
  234. package/lib/chain/rewards/attestationsRewards.js +0 -112
  235. package/lib/chain/rewards/attestationsRewards.js.map +0 -1
  236. package/lib/chain/rewards/blockRewards.d.ts +0 -14
  237. package/lib/chain/rewards/blockRewards.d.ts.map +0 -1
  238. package/lib/chain/rewards/blockRewards.js +0 -94
  239. package/lib/chain/rewards/blockRewards.js.map +0 -1
  240. package/lib/chain/rewards/syncCommitteeRewards.d.ts +0 -6
  241. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +0 -1
  242. package/lib/chain/rewards/syncCommitteeRewards.js +0 -36
  243. package/lib/chain/rewards/syncCommitteeRewards.js.map +0 -1
  244. package/src/chain/rewards/attestationsRewards.ts +0 -197
  245. package/src/chain/rewards/blockRewards.ts +0 -150
  246. package/src/chain/rewards/syncCommitteeRewards.ts +0 -58
@@ -1040,9 +1040,7 @@ export function getValidatorApi(
1040
1040
  const res = await getStateResponseWithRegen(chain, startSlot);
1041
1041
 
1042
1042
  const stateViewDU =
1043
- res.state instanceof Uint8Array
1044
- ? loadState(config, chain.getHeadState(), res.state).state
1045
- : res.state.clone();
1043
+ res.state instanceof Uint8Array ? loadState(config, chain.getHeadState(), res.state).state : res.state;
1046
1044
 
1047
1045
  state = createCachedBeaconState(
1048
1046
  stateViewDU,
@@ -418,13 +418,20 @@ export async function importBlock(
418
418
  this.logger.verbose("After importBlock caching postState without SSZ cache", {slot: postState.slot});
419
419
  }
420
420
 
421
+ // Cache shufflings when crossing an epoch boundary
422
+ const parentEpoch = computeEpochAtSlot(parentBlockSlot);
423
+ if (parentEpoch < blockEpoch) {
424
+ this.shufflingCache.processState(postState);
425
+ this.logger.verbose("Processed shuffling for next epoch", {parentEpoch, blockEpoch, slot: blockSlot});
426
+ }
427
+
421
428
  if (blockSlot % SLOTS_PER_EPOCH === 0) {
422
429
  // Cache state to preserve epoch transition work
423
430
  const checkpointState = postState;
424
431
  const cp = getCheckpointFromState(checkpointState);
425
432
  this.regen.addCheckpointState(cp, checkpointState);
426
- // consumers should not mutate or get the transfered cache
427
- this.emitter.emit(ChainEvent.checkpoint, cp, checkpointState.clone(true));
433
+ // consumers should not mutate state ever
434
+ this.emitter.emit(ChainEvent.checkpoint, cp, checkpointState);
428
435
 
429
436
  // Note: in-lined code from previos handler of ChainEvent.checkpoint
430
437
  this.logger.verbose("Checkpoint processed", toCheckpointHex(cp));
@@ -139,6 +139,7 @@ export async function verifyBlocksInEpoch(
139
139
  // All signatures at once
140
140
  opts.skipVerifyBlockSignatures !== true
141
141
  ? verifyBlocksSignatures(
142
+ this.config,
142
143
  this.index2pubkey,
143
144
  this.bls,
144
145
  this.logger,
@@ -8,7 +8,12 @@ import {
8
8
  ProtoBlock,
9
9
  } from "@lodestar/fork-choice";
10
10
  import {ForkSeq} from "@lodestar/params";
11
- import {CachedBeaconStateAllForks, isExecutionBlockBodyType, isExecutionStateType} from "@lodestar/state-transition";
11
+ import {
12
+ CachedBeaconStateAllForks,
13
+ isExecutionBlockBodyType,
14
+ isExecutionEnabled,
15
+ isExecutionStateType,
16
+ } from "@lodestar/state-transition";
12
17
  import {bellatrix, electra} from "@lodestar/types";
13
18
  import {ErrorAborted, Logger, toRootHex} from "@lodestar/utils";
14
19
  import {ExecutionPayloadStatus, IExecutionEngine} from "../../execution/engine/interface.js";
@@ -145,7 +150,9 @@ export async function verifyBlockExecutionPayload(
145
150
  const block = blockInput.getBlock();
146
151
  /** Not null if execution is enabled */
147
152
  const executionPayloadEnabled =
148
- isExecutionStateType(preState0) && isExecutionBlockBodyType(block.message.body)
153
+ isExecutionStateType(preState0) &&
154
+ isExecutionBlockBodyType(block.message.body) &&
155
+ isExecutionEnabled(preState0, block.message)
149
156
  ? block.message.body.executionPayload
150
157
  : null;
151
158
 
@@ -1,3 +1,4 @@
1
+ import {BeaconConfig} from "@lodestar/config";
1
2
  import {CachedBeaconStateAllForks, Index2PubkeyCache, getBlockSignatureSets} from "@lodestar/state-transition";
2
3
  import {IndexedAttestation, SignedBeaconBlock} from "@lodestar/types";
3
4
  import {Logger} from "@lodestar/utils";
@@ -15,6 +16,7 @@ import {ImportBlockOpts} from "./types.js";
15
16
  * Since all data is known in advance all signatures are verified at once in parallel.
16
17
  */
17
18
  export async function verifyBlocksSignatures(
19
+ config: BeaconConfig,
18
20
  index2pubkey: Index2PubkeyCache,
19
21
  bls: IBlsVerifier,
20
22
  logger: Logger,
@@ -26,6 +28,7 @@ export async function verifyBlocksSignatures(
26
28
  ): Promise<{verifySignaturesTime: number}> {
27
29
  const isValidPromises: Promise<boolean>[] = [];
28
30
  const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
31
+ const currentSyncCommitteeIndexed = preState0.epochCtx.currentSyncCommitteeIndexed;
29
32
 
30
33
  // Verifies signatures after running state transition, so all SyncCommittee signed roots are known at this point.
31
34
  // We must ensure block.slot <= state.slot before running getAllBlockSignatureSets().
@@ -39,9 +42,16 @@ export async function verifyBlocksSignatures(
39
42
  : //
40
43
  // Verify signatures per block to track which block is invalid
41
44
  bls.verifySignatureSets(
42
- getBlockSignatureSets(index2pubkey, preState0, block, indexedAttestationsByBlock[i], {
43
- skipProposerSignature: opts.validProposerSignature,
44
- })
45
+ getBlockSignatureSets(
46
+ config,
47
+ index2pubkey,
48
+ currentSyncCommitteeIndexed,
49
+ block,
50
+ indexedAttestationsByBlock[i],
51
+ {
52
+ skipProposerSignature: opts.validProposerSignature,
53
+ }
54
+ )
45
55
  );
46
56
 
47
57
  // getBlockSignatureSets() takes 45ms in benchmarks for 2022Q2 mainnet blocks (100 sigs). When syncing a 32 blocks
@@ -59,6 +59,7 @@ export async function verifyBlocksStateTransitionOnly(
59
59
  // if block is trusted don't verify proposer or op signature
60
60
  verifyProposer: !useBlsBatchVerify && !validSignatures && !validProposerSignature,
61
61
  verifySignatures: !useBlsBatchVerify && !validSignatures,
62
+ dontTransferCache: false,
62
63
  },
63
64
  {metrics, validatorMonitor}
64
65
  );
@@ -14,13 +14,14 @@ import {
14
14
  EpochShuffling,
15
15
  Index2PubkeyCache,
16
16
  computeAnchorCheckpoint,
17
+ computeAttestationsRewards,
18
+ computeBlockRewards,
17
19
  computeEndSlotAtEpoch,
18
20
  computeEpochAtSlot,
19
21
  computeStartSlotAtEpoch,
20
- createCachedBeaconState,
22
+ computeSyncCommitteeRewards,
21
23
  getEffectiveBalanceIncrementsZeroInactive,
22
24
  getEffectiveBalancesFromStateBytes,
23
- isCachedBeaconState,
24
25
  processSlots,
25
26
  } from "@lodestar/state-transition";
26
27
  import {
@@ -38,6 +39,7 @@ import {
38
39
  Wei,
39
40
  isBlindedBeaconBlock,
40
41
  phase0,
42
+ rewards,
41
43
  } from "@lodestar/types";
42
44
  import {Logger, fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRootHex} from "@lodestar/utils";
43
45
  import {ProcessShutdownCallback} from "@lodestar/validator";
@@ -50,6 +52,7 @@ import {computeNodeIdFromPrivateKey} from "../network/subnets/interface.js";
50
52
  import {BufferPool} from "../util/bufferPool.js";
51
53
  import {Clock, ClockEvent, IClock} from "../util/clock.js";
52
54
  import {CustodyConfig, getValidatorsCustodyRequirement} from "../util/dataColumns.js";
55
+ import {callInNextEventLoop} from "../util/eventLoop.js";
53
56
  import {ensureDir, writeIfNotExist} from "../util/file.js";
54
57
  import {isOptimisticBlock} from "../util/forkChoice.js";
55
58
  import {SerializedCache} from "../util/serializedCache.js";
@@ -79,9 +82,6 @@ import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index
79
82
  import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
80
83
  import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
81
84
  import {ReprocessController} from "./reprocess.js";
82
- import {AttestationsRewards, computeAttestationsRewards} from "./rewards/attestationsRewards.js";
83
- import {BlockRewards, computeBlockRewards} from "./rewards/blockRewards.js";
84
- import {SyncCommitteeRewards, computeSyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js";
85
85
  import {
86
86
  SeenAggregators,
87
87
  SeenAttesters,
@@ -142,7 +142,7 @@ export class BeaconChain implements IBeaconChain {
142
142
  readonly aggregatedAttestationPool: AggregatedAttestationPool;
143
143
  readonly syncCommitteeMessagePool: SyncCommitteeMessagePool;
144
144
  readonly syncContributionAndProofPool;
145
- readonly opPool = new OpPool();
145
+ readonly opPool: OpPool;
146
146
 
147
147
  // Gossip seen cache
148
148
  readonly seenAttesters = new SeenAttesters();
@@ -204,6 +204,8 @@ export class BeaconChain implements IBeaconChain {
204
204
  {
205
205
  privateKey,
206
206
  config,
207
+ pubkey2index,
208
+ index2pubkey,
207
209
  db,
208
210
  dbName,
209
211
  dataDir,
@@ -219,6 +221,8 @@ export class BeaconChain implements IBeaconChain {
219
221
  }: {
220
222
  privateKey: PrivateKey;
221
223
  config: BeaconConfig;
224
+ pubkey2index: PubkeyIndexMap;
225
+ index2pubkey: Index2PubkeyCache;
222
226
  db: IBeaconDb;
223
227
  dbName: string;
224
228
  dataDir: string;
@@ -228,7 +232,7 @@ export class BeaconChain implements IBeaconChain {
228
232
  clock?: IClock;
229
233
  metrics: Metrics | null;
230
234
  validatorMonitor: ValidatorMonitor | null;
231
- anchorState: BeaconStateAllForks;
235
+ anchorState: CachedBeaconStateAllForks;
232
236
  isAnchorStateFinalized: boolean;
233
237
  executionEngine: IExecutionEngine;
234
238
  executionBuilder?: IExecutionBuilder;
@@ -260,6 +264,7 @@ export class BeaconChain implements IBeaconChain {
260
264
  this.aggregatedAttestationPool = new AggregatedAttestationPool(this.config, metrics);
261
265
  this.syncCommitteeMessagePool = new SyncCommitteeMessagePool(config, clock, this.opts?.preaggregateSlotDistance);
262
266
  this.syncContributionAndProofPool = new SyncContributionAndProofPool(config, clock, metrics, logger);
267
+ this.opPool = new OpPool(config);
263
268
 
264
269
  this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
265
270
  this.seenContributionAndProof = new SeenContributionAndProof(metrics);
@@ -286,39 +291,26 @@ export class BeaconChain implements IBeaconChain {
286
291
  logger,
287
292
  });
288
293
 
289
- // Restore state caches
290
- // anchorState may already by a CachedBeaconState. If so, don't create the cache again, since deserializing all
291
- // pubkeys takes ~30 seconds for 350k keys (mainnet 2022Q2).
292
- // When the BeaconStateCache is created in initializeBeaconStateFromEth1 it may be incorrect. Until we can ensure that
293
- // it's safe to re-use _ANY_ BeaconStateCache, this option is disabled by default and only used in tests.
294
- const cachedState =
295
- isCachedBeaconState(anchorState) && opts.skipCreateStateCacheIfAvailable
296
- ? anchorState
297
- : createCachedBeaconState(anchorState, {
298
- config,
299
- pubkey2index: new PubkeyIndexMap(),
300
- index2pubkey: [],
301
- });
302
- this._earliestAvailableSlot = cachedState.slot;
303
-
304
- this.shufflingCache = cachedState.epochCtx.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
294
+ this._earliestAvailableSlot = anchorState.slot;
295
+
296
+ this.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
305
297
  {
306
- shuffling: cachedState.epochCtx.previousShuffling,
307
- decisionRoot: cachedState.epochCtx.previousDecisionRoot,
298
+ shuffling: anchorState.epochCtx.previousShuffling,
299
+ decisionRoot: anchorState.epochCtx.previousDecisionRoot,
308
300
  },
309
301
  {
310
- shuffling: cachedState.epochCtx.currentShuffling,
311
- decisionRoot: cachedState.epochCtx.currentDecisionRoot,
302
+ shuffling: anchorState.epochCtx.currentShuffling,
303
+ decisionRoot: anchorState.epochCtx.currentDecisionRoot,
312
304
  },
313
305
  {
314
- shuffling: cachedState.epochCtx.nextShuffling,
315
- decisionRoot: cachedState.epochCtx.nextDecisionRoot,
306
+ shuffling: anchorState.epochCtx.nextShuffling,
307
+ decisionRoot: anchorState.epochCtx.nextDecisionRoot,
316
308
  },
317
309
  ]);
318
310
 
319
- // Persist single global instance of state caches
320
- this.pubkey2index = cachedState.epochCtx.pubkey2index;
321
- this.index2pubkey = cachedState.epochCtx.index2pubkey;
311
+ // Global cache of validators pubkey/index mapping
312
+ this.pubkey2index = pubkey2index;
313
+ this.index2pubkey = index2pubkey;
322
314
 
323
315
  const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
324
316
  const blockStateCache = this.opts.nHistoricalStates
@@ -334,6 +326,7 @@ export class BeaconChain implements IBeaconChain {
334
326
  this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
335
327
  checkpointStateCache = new PersistentCheckpointStateCache(
336
328
  {
329
+ config,
337
330
  metrics,
338
331
  logger,
339
332
  clock,
@@ -348,15 +341,15 @@ export class BeaconChain implements IBeaconChain {
348
341
  }
349
342
 
350
343
  const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
351
- blockStateCache.add(cachedState);
352
- blockStateCache.setHeadState(cachedState);
353
- checkpointStateCache.add(checkpoint, cachedState);
344
+ blockStateCache.add(anchorState);
345
+ blockStateCache.setHeadState(anchorState);
346
+ checkpointStateCache.add(checkpoint, anchorState);
354
347
 
355
348
  const forkChoice = initializeForkChoice(
356
349
  config,
357
350
  emitter,
358
351
  clock.currentSlot,
359
- cachedState,
352
+ anchorState,
360
353
  isAnchorStateFinalized,
361
354
  opts,
362
355
  this.justifiedBalancesGetter.bind(this),
@@ -426,6 +419,7 @@ export class BeaconChain implements IBeaconChain {
426
419
  clock.addListener(ClockEvent.epoch, this.onClockEpoch.bind(this));
427
420
  emitter.addListener(ChainEvent.forkChoiceFinalized, this.onForkChoiceFinalized.bind(this));
428
421
  emitter.addListener(ChainEvent.forkChoiceJustified, this.onForkChoiceJustified.bind(this));
422
+ emitter.addListener(ChainEvent.checkpoint, this.onCheckpoint.bind(this));
429
423
  }
430
424
 
431
425
  async init(): Promise<void> {
@@ -513,7 +507,7 @@ export class BeaconChain implements IBeaconChain {
513
507
  async getStateBySlot(
514
508
  slot: Slot,
515
509
  opts?: StateGetOpts
516
- ): Promise<{state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null> {
510
+ ): Promise<{state: CachedBeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null> {
517
511
  const finalizedBlock = this.forkChoice.getFinalizedBlock();
518
512
 
519
513
  if (slot < finalizedBlock.slot) {
@@ -568,7 +562,7 @@ export class BeaconChain implements IBeaconChain {
568
562
  async getStateByStateRoot(
569
563
  stateRoot: RootHex,
570
564
  opts?: StateGetOpts
571
- ): Promise<{state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null> {
565
+ ): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
572
566
  if (opts?.allowRegen) {
573
567
  const state = await this.regen.getState(stateRoot, RegenCaller.restApi);
574
568
  const block = this.forkChoice.getBlock(state.latestBlockHeader.hashTreeRoot());
@@ -596,7 +590,8 @@ export class BeaconChain implements IBeaconChain {
596
590
  };
597
591
  }
598
592
 
599
- const data = await this.db.stateArchive.getByRoot(fromHex(stateRoot));
593
+ // this is mostly useful for a node with `--chain.archiveStateEpochFrequency 1`
594
+ const data = await this.db.stateArchive.getBinaryByRoot(fromHex(stateRoot));
600
595
  return data && {state: data, executionOptimistic: false, finalized: true};
601
596
  }
602
597
 
@@ -989,8 +984,8 @@ export class BeaconChain implements IBeaconChain {
989
984
  this.metrics?.gossipAttestation.useHeadBlockState.inc({caller: regenCaller});
990
985
  state = await this.regen.getState(attHeadBlock.stateRoot, regenCaller);
991
986
  }
992
-
993
- // should always be the current epoch of the active context so no need to await a result from the ShufflingCache
987
+ // resolve the promise to unblock other calls of the same epoch and dependent root
988
+ this.shufflingCache.processState(state);
994
989
  return state.epochCtx.getShufflingAtEpoch(attEpoch);
995
990
  }
996
991
 
@@ -1174,6 +1169,13 @@ export class BeaconChain implements IBeaconChain {
1174
1169
  this.logger.verbose("Fork choice justified", {epoch: cp.epoch, root: cp.rootHex});
1175
1170
  }
1176
1171
 
1172
+ private onCheckpoint(this: BeaconChain, _checkpoint: phase0.Checkpoint, state: CachedBeaconStateAllForks): void {
1173
+ // Defer to not block other checkpoint event handlers, which can cause lightclient update delays
1174
+ callInNextEventLoop(() => {
1175
+ this.shufflingCache.processState(state);
1176
+ });
1177
+ }
1178
+
1177
1179
  private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithHex): Promise<void> {
1178
1180
  this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
1179
1181
  this.seenBlockProposers.prune(computeStartSlotAtEpoch(cp.epoch));
@@ -1295,7 +1297,7 @@ export class BeaconChain implements IBeaconChain {
1295
1297
  }
1296
1298
  }
1297
1299
 
1298
- async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards> {
1300
+ async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards> {
1299
1301
  let preState = this.regen.getPreStateSync(block);
1300
1302
 
1301
1303
  if (preState === null) {
@@ -1304,15 +1306,15 @@ export class BeaconChain implements IBeaconChain {
1304
1306
 
1305
1307
  preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
1306
1308
 
1307
- const postState = this.regen.getStateSync(toRootHex(block.stateRoot)) ?? undefined;
1309
+ const proposerRewards = this.regen.getStateSync(toRootHex(block.stateRoot))?.proposerRewards ?? undefined;
1308
1310
 
1309
- return computeBlockRewards(block, preState.clone(), postState?.clone());
1311
+ return computeBlockRewards(this.config, block, preState, proposerRewards);
1310
1312
  }
1311
1313
 
1312
1314
  async getAttestationsRewards(
1313
1315
  epoch: Epoch,
1314
1316
  validatorIds?: (ValidatorIndex | string)[]
1315
- ): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}> {
1317
+ ): Promise<{rewards: rewards.AttestationsRewards; executionOptimistic: boolean; finalized: boolean}> {
1316
1318
  // We use end slot of (epoch + 1) to ensure we have seen all attestations. On-time or late. Any late attestation beyond this slot is not considered
1317
1319
  const slot = computeEndSlotAtEpoch(epoch + 1);
1318
1320
  const stateResult = await this.getStateBySlot(slot, {allowRegen: false}); // No regen if state not in cache
@@ -1330,7 +1332,7 @@ export class BeaconChain implements IBeaconChain {
1330
1332
  throw Error(`State is not in cache for slot ${slot}`);
1331
1333
  }
1332
1334
 
1333
- const rewards = await computeAttestationsRewards(this.pubkey2index, cachedState, validatorIds);
1335
+ const rewards = await computeAttestationsRewards(this.config, this.pubkey2index, cachedState, validatorIds);
1334
1336
 
1335
1337
  return {rewards, executionOptimistic, finalized};
1336
1338
  }
@@ -1338,7 +1340,7 @@ export class BeaconChain implements IBeaconChain {
1338
1340
  async getSyncCommitteeRewards(
1339
1341
  block: BeaconBlock | BlindedBeaconBlock,
1340
1342
  validatorIds?: (ValidatorIndex | string)[]
1341
- ): Promise<SyncCommitteeRewards> {
1343
+ ): Promise<rewards.SyncCommitteeRewards> {
1342
1344
  let preState = this.regen.getPreStateSync(block);
1343
1345
 
1344
1346
  if (preState === null) {
@@ -1347,6 +1349,6 @@ export class BeaconChain implements IBeaconChain {
1347
1349
 
1348
1350
  preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
1349
1351
 
1350
- return computeSyncCommitteeRewards(this.index2pubkey, block, preState.clone(), validatorIds);
1352
+ return computeSyncCommitteeRewards(this.config, this.index2pubkey, block, preState, validatorIds);
1351
1353
  }
1352
1354
  }
@@ -18,6 +18,7 @@ import {
18
18
  getBlockRootAtSlot,
19
19
  getEffectiveBalanceIncrementsZeroInactive,
20
20
  isExecutionStateType,
21
+ isMergeTransitionComplete,
21
22
  } from "@lodestar/state-transition";
22
23
  import {Slot, ssz} from "@lodestar/types";
23
24
  import {Logger, toRootHex} from "@lodestar/utils";
@@ -134,7 +135,7 @@ export function initializeForkChoiceFromFinalizedState(
134
135
  unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
135
136
  unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
136
137
 
137
- ...(isExecutionStateType(state)
138
+ ...(isExecutionStateType(state) && isMergeTransitionComplete(state)
138
139
  ? {
139
140
  executionPayloadBlockHash: toRootHex(state.latestExecutionPayloadHeader.blockHash),
140
141
  executionPayloadNumber: state.latestExecutionPayloadHeader.blockNumber,
@@ -215,7 +216,7 @@ export function initializeForkChoiceFromUnfinalizedState(
215
216
  unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
216
217
  unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
217
218
 
218
- ...(isExecutionStateType(unfinalizedState)
219
+ ...(isExecutionStateType(unfinalizedState) && isMergeTransitionComplete(unfinalizedState)
219
220
  ? {
220
221
  executionPayloadBlockHash: toRootHex(unfinalizedState.latestExecutionPayloadHeader.blockHash),
221
222
  executionPayloadNumber: unfinalizedState.latestExecutionPayloadHeader.blockNumber,
@@ -23,6 +23,7 @@ import {
23
23
  altair,
24
24
  capella,
25
25
  phase0,
26
+ rewards,
26
27
  } from "@lodestar/types";
27
28
  import {Logger} from "@lodestar/utils";
28
29
  import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
@@ -48,9 +49,6 @@ import {IChainOptions} from "./options.js";
48
49
  import {AssembledBlockType, BlockAttributes, BlockType, ProduceResult} from "./produceBlock/produceBlockBody.js";
49
50
  import {IStateRegenerator, RegenCaller} from "./regen/index.js";
50
51
  import {ReprocessController} from "./reprocess.js";
51
- import {AttestationsRewards} from "./rewards/attestationsRewards.js";
52
- import {BlockRewards} from "./rewards/blockRewards.js";
53
- import {SyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js";
54
52
  import {
55
53
  SeenAggregators,
56
54
  SeenAttesters,
@@ -170,12 +168,12 @@ export interface IBeaconChain {
170
168
  getStateBySlot(
171
169
  slot: Slot,
172
170
  opts?: StateGetOpts
173
- ): Promise<{state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null>;
171
+ ): Promise<{state: CachedBeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null>;
174
172
  /** Returns a local state by state root */
175
173
  getStateByStateRoot(
176
174
  stateRoot: RootHex,
177
175
  opts?: StateGetOpts
178
- ): Promise<{state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null>;
176
+ ): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null>;
179
177
  /** Return serialized bytes of a persisted checkpoint state */
180
178
  getPersistedCheckpointState(checkpoint?: phase0.Checkpoint): Promise<Uint8Array | null>;
181
179
  /** Returns a cached state by checkpoint */
@@ -255,15 +253,15 @@ export interface IBeaconChain {
255
253
  regenCanAcceptWork(): boolean;
256
254
  blsThreadPoolCanAcceptWork(): boolean;
257
255
 
258
- getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards>;
256
+ getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards>;
259
257
  getAttestationsRewards(
260
258
  epoch: Epoch,
261
259
  validatorIds?: (ValidatorIndex | string)[]
262
- ): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
260
+ ): Promise<{rewards: rewards.AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
263
261
  getSyncCommitteeRewards(
264
262
  blockRef: BeaconBlock | BlindedBeaconBlock,
265
263
  validatorIds?: (ValidatorIndex | string)[]
266
- ): Promise<SyncCommitteeRewards>;
264
+ ): Promise<rewards.SyncCommitteeRewards>;
267
265
  }
268
266
 
269
267
  export type SSZObjectType =
@@ -12,7 +12,6 @@ import {BeaconBlockBody, SSZTypesFor, ssz} from "@lodestar/types";
12
12
  import {SyncCommitteeWitness} from "./types.js";
13
13
 
14
14
  export function getSyncCommitteesWitness(fork: ForkName, state: BeaconStateAllForks): SyncCommitteeWitness {
15
- state.commit();
16
15
  const n1 = state.node;
17
16
  let witness: Uint8Array[];
18
17
  let currentSyncCommitteeRoot: Uint8Array;
@@ -71,7 +70,6 @@ export function getCurrentSyncCommitteeBranch(syncCommitteesWitness: SyncCommitt
71
70
  }
72
71
 
73
72
  export function getFinalizedRootProof(state: CachedBeaconStateAllForks): Uint8Array[] {
74
- state.commit();
75
73
  const finalizedRootGindex = state.epochCtx.isPostElectra() ? FINALIZED_ROOT_GINDEX_ELECTRA : FINALIZED_ROOT_GINDEX;
76
74
  return new Tree(state.node).getSingleProof(BigInt(finalizedRootGindex));
77
75
  }