@lodestar/beacon-node 1.40.0-dev.9defa5c09b → 1.40.0-dev.b87b37f4d0

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 (263) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +15 -9
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  5. package/lib/api/impl/lodestar/index.js +24 -0
  6. package/lib/api/impl/lodestar/index.js.map +1 -1
  7. package/lib/api/impl/validator/index.d.ts.map +1 -1
  8. package/lib/api/impl/validator/index.js.map +1 -1
  9. package/lib/api/rest/base.d.ts.map +1 -1
  10. package/lib/api/rest/base.js +2 -2
  11. package/lib/api/rest/base.js.map +1 -1
  12. package/lib/chain/ColumnReconstructionTracker.d.ts +2 -0
  13. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  14. package/lib/chain/ColumnReconstructionTracker.js +7 -3
  15. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  16. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  17. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +2 -1
  18. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  19. package/lib/chain/blocks/blockInput/blockInput.d.ts +28 -0
  20. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  21. package/lib/chain/blocks/blockInput/blockInput.js +38 -3
  22. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  23. package/lib/chain/blocks/importBlock.js +1 -1
  24. package/lib/chain/blocks/importBlock.js.map +1 -1
  25. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  26. package/lib/chain/blocks/verifyBlock.js +1 -1
  27. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  28. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  29. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  30. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  31. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  32. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  33. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -2
  34. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  35. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  36. package/lib/chain/blocks/writeBlockInputToDb.js +8 -0
  37. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  38. package/lib/chain/bls/multithread/index.d.ts +3 -1
  39. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  40. package/lib/chain/bls/multithread/index.js +5 -3
  41. package/lib/chain/bls/multithread/index.js.map +1 -1
  42. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  43. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  44. package/lib/chain/bls/multithread/jobItem.js +2 -2
  45. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  46. package/lib/chain/bls/singleThread.d.ts +4 -2
  47. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  48. package/lib/chain/bls/singleThread.js +4 -2
  49. package/lib/chain/bls/singleThread.js.map +1 -1
  50. package/lib/chain/bls/utils.d.ts +2 -2
  51. package/lib/chain/bls/utils.d.ts.map +1 -1
  52. package/lib/chain/bls/utils.js +9 -6
  53. package/lib/chain/bls/utils.js.map +1 -1
  54. package/lib/chain/chain.d.ts +1 -1
  55. package/lib/chain/chain.d.ts.map +1 -1
  56. package/lib/chain/chain.js +19 -31
  57. package/lib/chain/chain.js.map +1 -1
  58. package/lib/chain/initState.d.ts.map +1 -1
  59. package/lib/chain/initState.js +2 -2
  60. package/lib/chain/initState.js.map +1 -1
  61. package/lib/chain/lightClient/index.d.ts.map +1 -1
  62. package/lib/chain/lightClient/index.js +1 -2
  63. package/lib/chain/lightClient/index.js.map +1 -1
  64. package/lib/chain/options.d.ts +0 -1
  65. package/lib/chain/options.d.ts.map +1 -1
  66. package/lib/chain/options.js +0 -1
  67. package/lib/chain/options.js.map +1 -1
  68. package/lib/chain/regen/interface.d.ts +1 -1
  69. package/lib/chain/regen/queued.d.ts +1 -1
  70. package/lib/chain/regen/queued.d.ts.map +1 -1
  71. package/lib/chain/regen/queued.js.map +1 -1
  72. package/lib/chain/regen/regen.d.ts +2 -0
  73. package/lib/chain/regen/regen.d.ts.map +1 -1
  74. package/lib/chain/regen/regen.js +4 -1
  75. package/lib/chain/regen/regen.js.map +1 -1
  76. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  77. package/lib/chain/seenCache/seenGossipBlockInput.js +3 -3
  78. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  79. package/lib/chain/serializeState.d.ts.map +1 -1
  80. package/lib/chain/serializeState.js +2 -1
  81. package/lib/chain/serializeState.js.map +1 -1
  82. package/lib/chain/stateCache/index.d.ts +0 -2
  83. package/lib/chain/stateCache/index.d.ts.map +1 -1
  84. package/lib/chain/stateCache/index.js +0 -2
  85. package/lib/chain/stateCache/index.js.map +1 -1
  86. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +2 -1
  87. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  88. package/lib/chain/stateCache/persistentCheckpointsCache.js +3 -0
  89. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  90. package/lib/chain/validation/aggregateAndProof.js +3 -4
  91. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  92. package/lib/chain/validation/attestation.d.ts +2 -2
  93. package/lib/chain/validation/attestation.d.ts.map +1 -1
  94. package/lib/chain/validation/attestation.js +4 -4
  95. package/lib/chain/validation/attestation.js.map +1 -1
  96. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  97. package/lib/chain/validation/attesterSlashing.js +1 -1
  98. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  99. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  100. package/lib/chain/validation/blobSidecar.js +4 -4
  101. package/lib/chain/validation/blobSidecar.js.map +1 -1
  102. package/lib/chain/validation/block.d.ts.map +1 -1
  103. package/lib/chain/validation/block.js +2 -3
  104. package/lib/chain/validation/block.js.map +1 -1
  105. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  106. package/lib/chain/validation/dataColumnSidecar.js +4 -4
  107. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  108. package/lib/chain/validation/executionPayloadBid.js +4 -3
  109. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  110. package/lib/chain/validation/payloadAttestationMessage.js +1 -1
  111. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  112. package/lib/chain/validation/proposerSlashing.js +1 -1
  113. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  114. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
  115. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
  116. package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
  117. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  118. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  119. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  120. package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
  121. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  122. package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
  123. package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
  124. package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
  125. package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
  126. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  127. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  128. package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
  129. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  130. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  131. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  132. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  133. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  134. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  135. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  136. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  137. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  138. package/lib/chain/validation/syncCommittee.js +1 -1
  139. package/lib/chain/validation/syncCommittee.js.map +1 -1
  140. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  141. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
  142. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  143. package/lib/chain/validation/voluntaryExit.js +1 -1
  144. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  145. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  146. package/lib/chain/validatorMonitor.js +7 -4
  147. package/lib/chain/validatorMonitor.js.map +1 -1
  148. package/lib/network/core/networkCore.d.ts +3 -0
  149. package/lib/network/core/networkCore.d.ts.map +1 -1
  150. package/lib/network/core/networkCore.js +9 -0
  151. package/lib/network/core/networkCore.js.map +1 -1
  152. package/lib/network/core/networkCoreWorker.js +3 -0
  153. package/lib/network/core/networkCoreWorker.js.map +1 -1
  154. package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -0
  155. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  156. package/lib/network/core/networkCoreWorkerHandler.js +9 -0
  157. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  158. package/lib/network/core/types.d.ts +3 -0
  159. package/lib/network/core/types.d.ts.map +1 -1
  160. package/lib/network/gossip/gossipsub.d.ts +34 -0
  161. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  162. package/lib/network/gossip/gossipsub.js +123 -0
  163. package/lib/network/gossip/gossipsub.js.map +1 -1
  164. package/lib/network/network.d.ts +3 -0
  165. package/lib/network/network.d.ts.map +1 -1
  166. package/lib/network/network.js +9 -0
  167. package/lib/network/network.js.map +1 -1
  168. package/lib/network/options.d.ts +6 -0
  169. package/lib/network/options.d.ts.map +1 -1
  170. package/lib/network/options.js.map +1 -1
  171. package/lib/network/peers/peerManager.d.ts.map +1 -1
  172. package/lib/network/peers/peerManager.js +9 -0
  173. package/lib/network/peers/peerManager.js.map +1 -1
  174. package/lib/network/processor/gossipHandlers.js +1 -1
  175. package/lib/network/processor/gossipHandlers.js.map +1 -1
  176. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  177. package/lib/sync/backfill/backfill.js +3 -4
  178. package/lib/sync/backfill/backfill.js.map +1 -1
  179. package/lib/sync/backfill/verify.d.ts +1 -2
  180. package/lib/sync/backfill/verify.d.ts.map +1 -1
  181. package/lib/sync/backfill/verify.js +2 -2
  182. package/lib/sync/backfill/verify.js.map +1 -1
  183. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  184. package/lib/sync/utils/downloadByRange.js +2 -2
  185. package/lib/sync/utils/downloadByRange.js.map +1 -1
  186. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  187. package/lib/sync/utils/downloadByRoot.js +1 -2
  188. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  189. package/package.json +16 -16
  190. package/src/api/impl/beacon/blocks/index.ts +31 -19
  191. package/src/api/impl/lodestar/index.ts +29 -0
  192. package/src/api/impl/validator/index.ts +2 -1
  193. package/src/api/rest/base.ts +4 -4
  194. package/src/chain/ColumnReconstructionTracker.ts +8 -4
  195. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +2 -1
  196. package/src/chain/blocks/blockInput/blockInput.ts +47 -4
  197. package/src/chain/blocks/importBlock.ts +1 -1
  198. package/src/chain/blocks/verifyBlock.ts +0 -1
  199. package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
  200. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -2
  201. package/src/chain/blocks/writeBlockInputToDb.ts +9 -0
  202. package/src/chain/bls/multithread/index.ts +7 -4
  203. package/src/chain/bls/multithread/jobItem.ts +7 -3
  204. package/src/chain/bls/singleThread.ts +5 -3
  205. package/src/chain/bls/utils.ts +15 -7
  206. package/src/chain/chain.ts +24 -35
  207. package/src/chain/initState.ts +2 -2
  208. package/src/chain/lightClient/index.ts +1 -2
  209. package/src/chain/options.ts +0 -2
  210. package/src/chain/regen/interface.ts +1 -1
  211. package/src/chain/regen/queued.ts +1 -2
  212. package/src/chain/regen/regen.ts +6 -1
  213. package/src/chain/seenCache/seenGossipBlockInput.ts +3 -3
  214. package/src/chain/serializeState.ts +2 -1
  215. package/src/chain/stateCache/index.ts +0 -2
  216. package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
  217. package/src/chain/validation/aggregateAndProof.ts +3 -4
  218. package/src/chain/validation/attestation.ts +9 -13
  219. package/src/chain/validation/attesterSlashing.ts +1 -6
  220. package/src/chain/validation/blobSidecar.ts +3 -8
  221. package/src/chain/validation/block.ts +2 -3
  222. package/src/chain/validation/dataColumnSidecar.ts +3 -8
  223. package/src/chain/validation/executionPayloadBid.ts +5 -4
  224. package/src/chain/validation/payloadAttestationMessage.ts +1 -1
  225. package/src/chain/validation/proposerSlashing.ts +1 -6
  226. package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
  227. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
  228. package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
  229. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
  230. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
  231. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
  232. package/src/chain/validation/syncCommittee.ts +1 -1
  233. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
  234. package/src/chain/validation/voluntaryExit.ts +1 -1
  235. package/src/chain/validatorMonitor.ts +10 -5
  236. package/src/network/core/networkCore.ts +12 -0
  237. package/src/network/core/networkCoreWorker.ts +3 -0
  238. package/src/network/core/networkCoreWorkerHandler.ts +9 -0
  239. package/src/network/core/types.ts +6 -0
  240. package/src/network/gossip/gossipsub.ts +147 -1
  241. package/src/network/network.ts +12 -0
  242. package/src/network/options.ts +6 -0
  243. package/src/network/peers/peerManager.ts +11 -0
  244. package/src/network/processor/gossipHandlers.ts +1 -1
  245. package/src/sync/backfill/backfill.ts +3 -4
  246. package/src/sync/backfill/verify.ts +2 -3
  247. package/src/sync/utils/downloadByRange.ts +2 -2
  248. package/src/sync/utils/downloadByRoot.ts +1 -2
  249. package/lib/chain/stateCache/blockStateCacheImpl.d.ts +0 -54
  250. package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +0 -1
  251. package/lib/chain/stateCache/blockStateCacheImpl.js +0 -130
  252. package/lib/chain/stateCache/blockStateCacheImpl.js.map +0 -1
  253. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +0 -60
  254. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +0 -1
  255. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +0 -156
  256. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +0 -1
  257. package/lib/util/bytes.d.ts +0 -3
  258. package/lib/util/bytes.d.ts.map +0 -1
  259. package/lib/util/bytes.js +0 -11
  260. package/lib/util/bytes.js.map +0 -1
  261. package/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
  262. package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
  263. package/src/util/bytes.ts +0 -11
@@ -1,5 +1,5 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
- import {CachedBeaconStateAllForks, Index2PubkeyCache, getBlockSignatureSets} from "@lodestar/state-transition";
2
+ import {CachedBeaconStateAllForks, getBlockSignatureSets} from "@lodestar/state-transition";
3
3
  import {IndexedAttestation, SignedBeaconBlock} from "@lodestar/types";
4
4
  import {Logger} from "@lodestar/utils";
5
5
  import {Metrics} from "../../metrics/metrics.js";
@@ -17,7 +17,6 @@ import {ImportBlockOpts} from "./types.js";
17
17
  */
18
18
  export async function verifyBlocksSignatures(
19
19
  config: BeaconConfig,
20
- index2pubkey: Index2PubkeyCache,
21
20
  bls: IBlsVerifier,
22
21
  logger: Logger,
23
22
  metrics: Metrics | null,
@@ -42,16 +41,9 @@ export async function verifyBlocksSignatures(
42
41
  : //
43
42
  // Verify signatures per block to track which block is invalid
44
43
  bls.verifySignatureSets(
45
- getBlockSignatureSets(
46
- config,
47
- index2pubkey,
48
- currentSyncCommitteeIndexed,
49
- block,
50
- indexedAttestationsByBlock[i],
51
- {
52
- skipProposerSignature: opts.validProposerSignature,
53
- }
54
- )
44
+ getBlockSignatureSets(config, currentSyncCommitteeIndexed, block, indexedAttestationsByBlock[i], {
45
+ skipProposerSignature: opts.validProposerSignature,
46
+ })
55
47
  );
56
48
 
57
49
  // getBlockSignatureSets() takes 45ms in benchmarks for 2022Q2 mainnet blocks (100 sigs). When syncing a 32 blocks
@@ -5,9 +5,8 @@ import {
5
5
  StateHashTreeRootSource,
6
6
  stateTransition,
7
7
  } from "@lodestar/state-transition";
8
- import {ErrorAborted, Logger} from "@lodestar/utils";
8
+ import {ErrorAborted, Logger, byteArrayEquals} from "@lodestar/utils";
9
9
  import {Metrics} from "../../metrics/index.js";
10
- import {byteArrayEquals} from "../../util/bytes.js";
11
10
  import {nextEventLoop} from "../../util/eventLoop.js";
12
11
  import {BlockError, BlockErrorCode} from "../errors/index.js";
13
12
  import {BlockProcessOpts} from "../options.js";
@@ -44,6 +44,15 @@ export async function writeBlockInputToDb(this: BeaconChain, blocksInputs: IBloc
44
44
 
45
45
  // NOTE: Old data is pruned on archive
46
46
  if (isBlockInputColumns(blockInput)) {
47
+ if (!blockInput.hasComputedAllData()) {
48
+ // Supernodes may only have a subset of the data columns by the time the block begins to be imported
49
+ // because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
50
+ // Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
51
+ await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
52
+ this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
53
+ });
54
+ }
55
+
47
56
  const {custodyColumns} = this.custodyConfig;
48
57
  const blobsLen = (block.message as fulu.BeaconBlock).body.blobKzgCommitments.length;
49
58
  let dataColumnsLen: number;
@@ -7,7 +7,7 @@ import {Worker, spawn} from "@chainsafe/threads";
7
7
  self = undefined;
8
8
 
9
9
  import {PublicKey} from "@chainsafe/blst";
10
- import {ISignatureSet} from "@lodestar/state-transition";
10
+ import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
11
11
  import {Logger} from "@lodestar/utils";
12
12
  import {Metrics} from "../../../metrics/index.js";
13
13
  import {LinkedList} from "../../../util/array.js";
@@ -34,6 +34,7 @@ const workerDir = process.env.NODE_ENV === "test" ? "../../../../lib/chain/bls/m
34
34
  export type BlsMultiThreadWorkerPoolModules = {
35
35
  logger: Logger;
36
36
  metrics: Metrics | null;
37
+ index2pubkey: Index2PubkeyCache;
37
38
  };
38
39
 
39
40
  export type BlsMultiThreadWorkerPoolOptions = {
@@ -113,6 +114,7 @@ type WorkerDescriptor = {
113
114
  export class BlsMultiThreadWorkerPool implements IBlsVerifier {
114
115
  private readonly logger: Logger;
115
116
  private readonly metrics: Metrics | null;
117
+ private readonly index2pubkey: Index2PubkeyCache;
116
118
 
117
119
  private readonly workers: WorkerDescriptor[];
118
120
  private readonly jobs = new LinkedList<JobQueueItem>();
@@ -128,9 +130,10 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
128
130
  private workersBusy = 0;
129
131
 
130
132
  constructor(options: BlsMultiThreadWorkerPoolOptions, modules: BlsMultiThreadWorkerPoolModules) {
131
- const {logger, metrics} = modules;
133
+ const {logger, metrics, index2pubkey} = modules;
132
134
  this.logger = logger;
133
135
  this.metrics = metrics;
136
+ this.index2pubkey = index2pubkey;
134
137
  this.blsVerifyAllMultiThread = options.blsVerifyAllMultiThread ?? false;
135
138
 
136
139
  // Use compressed for herumi for now.
@@ -170,7 +173,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
170
173
  try {
171
174
  return verifySignatureSetsMaybeBatch(
172
175
  sets.map((set) => ({
173
- publicKey: getAggregatedPubkey(set),
176
+ publicKey: getAggregatedPubkey(set, this.index2pubkey),
174
177
  message: set.signingRoot.valueOf(),
175
178
  signature: set.signature,
176
179
  }))
@@ -395,7 +398,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
395
398
  try {
396
399
  // Note: This can throw, must be handled per-job.
397
400
  // Pubkey and signature aggregation is defered here
398
- workReq = await jobItemWorkReq(job, this.metrics);
401
+ workReq = await jobItemWorkReq(job, this.index2pubkey, this.metrics);
399
402
  } catch (e) {
400
403
  this.metrics?.blsThreadPool.errorAggregateSignatureSetsCount.inc({type: job.type});
401
404
 
@@ -1,5 +1,5 @@
1
1
  import {PublicKey, asyncAggregateWithRandomness} from "@chainsafe/blst";
2
- import {ISignatureSet, SignatureSetType} from "@lodestar/state-transition";
2
+ import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../../metrics/metrics.js";
4
4
  import {LinkedList} from "../../../util/array.js";
5
5
  import {VerifySignatureOpts} from "../interface.js";
@@ -48,14 +48,18 @@ export function jobItemSigSets(job: JobQueueItem): number {
48
48
  * Prepare BlsWorkReq from JobQueueItem
49
49
  * WARNING: May throw with untrusted user input
50
50
  */
51
- export async function jobItemWorkReq(job: JobQueueItem, metrics: Metrics | null): Promise<BlsWorkReq> {
51
+ export async function jobItemWorkReq(
52
+ job: JobQueueItem,
53
+ index2pubkey: Index2PubkeyCache,
54
+ metrics: Metrics | null
55
+ ): Promise<BlsWorkReq> {
52
56
  switch (job.type) {
53
57
  case JobQueueItemType.default:
54
58
  return {
55
59
  opts: job.opts,
56
60
  sets: job.sets.map((set) => ({
57
61
  // this can throw, handled in the consumer code
58
- publicKey: getAggregatedPubkey(set, metrics).toBytes(),
62
+ publicKey: getAggregatedPubkey(set, index2pubkey, metrics).toBytes(),
59
63
  signature: set.signature,
60
64
  message: set.signingRoot,
61
65
  })),
@@ -1,5 +1,5 @@
1
1
  import {PublicKey, Signature, aggregatePublicKeys, aggregateSignatures, verify} from "@chainsafe/blst";
2
- import {ISignatureSet} from "@lodestar/state-transition";
2
+ import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../metrics/index.js";
4
4
  import {IBlsVerifier} from "./interface.js";
5
5
  import {verifySignatureSetsMaybeBatch} from "./maybeBatch.js";
@@ -7,16 +7,18 @@ import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
7
7
 
8
8
  export class BlsSingleThreadVerifier implements IBlsVerifier {
9
9
  private readonly metrics: Metrics | null;
10
+ private readonly index2pubkey: Index2PubkeyCache;
10
11
 
11
- constructor({metrics = null}: {metrics: Metrics | null}) {
12
+ constructor({metrics = null, index2pubkey}: {metrics: Metrics | null; index2pubkey: Index2PubkeyCache}) {
12
13
  this.metrics = metrics;
14
+ this.index2pubkey = index2pubkey;
13
15
  }
14
16
 
15
17
  async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
16
18
  this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
17
19
 
18
20
  const setsAggregated = sets.map((set) => ({
19
- publicKey: getAggregatedPubkey(set),
21
+ publicKey: getAggregatedPubkey(set, this.index2pubkey, this.metrics),
20
22
  message: set.signingRoot,
21
23
  signature: set.signature,
22
24
  }));
@@ -1,17 +1,25 @@
1
1
  import {PublicKey, aggregatePublicKeys} from "@chainsafe/blst";
2
- import {ISignatureSet, SignatureSetType} from "@lodestar/state-transition";
2
+ import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../metrics/metrics.js";
4
4
 
5
- export function getAggregatedPubkey(signatureSet: ISignatureSet, metrics: Metrics | null = null): PublicKey {
5
+ export function getAggregatedPubkey(
6
+ signatureSet: ISignatureSet,
7
+ index2pubkey: Index2PubkeyCache,
8
+ metrics: Metrics | null = null
9
+ ): PublicKey {
6
10
  switch (signatureSet.type) {
7
11
  case SignatureSetType.single:
8
12
  return signatureSet.pubkey;
9
13
 
14
+ case SignatureSetType.indexed:
15
+ return index2pubkey[signatureSet.index];
16
+
10
17
  case SignatureSetType.aggregate: {
11
18
  const timer = metrics?.blsThreadPool.pubkeysAggregationMainThreadDuration.startTimer();
12
- const pubkeys = aggregatePublicKeys(signatureSet.pubkeys);
19
+ const pubkeys = signatureSet.indices.map((i) => index2pubkey[i]);
20
+ const aggregated = aggregatePublicKeys(pubkeys);
13
21
  timer?.();
14
- return pubkeys;
22
+ return aggregated;
15
23
  }
16
24
 
17
25
  default:
@@ -20,11 +28,11 @@ export function getAggregatedPubkey(signatureSet: ISignatureSet, metrics: Metric
20
28
  }
21
29
 
22
30
  export function getAggregatedPubkeysCount(signatureSets: ISignatureSet[]): number {
23
- let pubkeysConut = 0;
31
+ let pubkeysCount = 0;
24
32
  for (const set of signatureSets) {
25
33
  if (set.type === SignatureSetType.aggregate) {
26
- pubkeysConut += set.pubkeys.length;
34
+ pubkeysCount += set.indices.length;
27
35
  }
28
36
  }
29
- return pubkeysConut;
37
+ return pubkeysCount;
30
38
  }
@@ -107,12 +107,10 @@ import {SeenAttestationDatas} from "./seenCache/seenAttestationData.js";
107
107
  import {SeenBlockAttesters} from "./seenCache/seenBlockAttesters.js";
108
108
  import {SeenBlockInput} from "./seenCache/seenGossipBlockInput.js";
109
109
  import {ShufflingCache} from "./shufflingCache.js";
110
- import {BlockStateCacheImpl} from "./stateCache/blockStateCacheImpl.js";
111
110
  import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datastore/db.js";
112
111
  import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
113
112
  import {CPStateDatastore} from "./stateCache/datastore/types.js";
114
113
  import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
115
- import {InMemoryCheckpointStateCache} from "./stateCache/inMemoryCheckpointsCache.js";
116
114
  import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
117
115
  import {CheckpointStateCache} from "./stateCache/types.js";
118
116
  import {ValidatorMonitor} from "./validatorMonitor.js";
@@ -142,7 +140,7 @@ export class BeaconChain implements IBeaconChain {
142
140
  readonly logger: Logger;
143
141
  readonly metrics: Metrics | null;
144
142
  readonly validatorMonitor: ValidatorMonitor | null;
145
- readonly bufferPool: BufferPool | null;
143
+ readonly bufferPool: BufferPool;
146
144
 
147
145
  readonly anchorStateLatestBlockSlot: Slot;
148
146
 
@@ -278,8 +276,8 @@ export class BeaconChain implements IBeaconChain {
278
276
  const emitter = new ChainEventEmitter();
279
277
  // by default, verify signatures on both main threads and worker threads
280
278
  const bls = opts.blsVerifyAllMainThread
281
- ? new BlsSingleThreadVerifier({metrics})
282
- : new BlsMultiThreadWorkerPool(opts, {logger, metrics});
279
+ ? new BlsSingleThreadVerifier({metrics, index2pubkey})
280
+ : new BlsMultiThreadWorkerPool(opts, {logger, metrics, index2pubkey});
283
281
 
284
282
  if (!clock) clock = new Clock({config, genesisTime: this.genesisTime, signal});
285
283
 
@@ -339,32 +337,22 @@ export class BeaconChain implements IBeaconChain {
339
337
  this.index2pubkey = index2pubkey;
340
338
 
341
339
  const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
342
- const blockStateCache = this.opts.nHistoricalStates
343
- ? new FIFOBlockStateCache(this.opts, {metrics})
344
- : new BlockStateCacheImpl({metrics});
345
- this.bufferPool = this.opts.nHistoricalStates
346
- ? new BufferPool(anchorState.type.tree_serializedSize(anchorState.node), metrics)
347
- : null;
348
-
349
- let checkpointStateCache: CheckpointStateCache;
350
- this.cpStateDatastore = undefined;
351
- if (this.opts.nHistoricalStates) {
352
- this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
353
- checkpointStateCache = new PersistentCheckpointStateCache(
354
- {
355
- config,
356
- metrics,
357
- logger,
358
- clock,
359
- blockStateCache,
360
- bufferPool: this.bufferPool,
361
- datastore: this.cpStateDatastore,
362
- },
363
- this.opts
364
- );
365
- } else {
366
- checkpointStateCache = new InMemoryCheckpointStateCache({metrics});
367
- }
340
+ const blockStateCache = new FIFOBlockStateCache(this.opts, {metrics});
341
+ this.bufferPool = new BufferPool(anchorState.type.tree_serializedSize(anchorState.node), metrics);
342
+
343
+ this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
344
+ const checkpointStateCache: CheckpointStateCache = new PersistentCheckpointStateCache(
345
+ {
346
+ config,
347
+ metrics,
348
+ logger,
349
+ clock,
350
+ blockStateCache,
351
+ bufferPool: this.bufferPool,
352
+ datastore: this.cpStateDatastore,
353
+ },
354
+ this.opts
355
+ );
368
356
 
369
357
  const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
370
358
  blockStateCache.add(anchorState);
@@ -387,6 +375,7 @@ export class BeaconChain implements IBeaconChain {
387
375
  forkChoice,
388
376
  blockStateCache,
389
377
  checkpointStateCache,
378
+ seenBlockInputCache: this.seenBlockInputCache,
390
379
  db,
391
380
  metrics,
392
381
  validatorMonitor,
@@ -1368,13 +1357,13 @@ export class BeaconChain implements IBeaconChain {
1368
1357
  // TODO: Improve using regen here
1369
1358
  const {blockRoot, stateRoot, slot} = this.forkChoice.getHead();
1370
1359
  const headState = this.regen.getStateSync(stateRoot);
1371
- const headBlock = await this.db.block.get(fromHex(blockRoot));
1372
- if (headBlock == null) {
1373
- throw Error(`Head block ${slot} ${headBlock} is not available in database`);
1360
+ const blockResult = await this.getBlockByRoot(blockRoot);
1361
+ if (blockResult == null) {
1362
+ throw Error(`Head block for ${slot} is not available in cache or database`);
1374
1363
  }
1375
1364
 
1376
1365
  if (headState) {
1377
- this.opPool.pruneAll(headBlock, headState);
1366
+ this.opPool.pruneAll(blockResult.block, headState);
1378
1367
  }
1379
1368
 
1380
1369
  if (headState === null) {
@@ -2,7 +2,7 @@ import {ChainForkConfig} from "@lodestar/config";
2
2
  import {ZERO_HASH} from "@lodestar/params";
3
3
  import {BeaconStateAllForks, computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
4
4
  import {SignedBeaconBlock, ssz} from "@lodestar/types";
5
- import {Logger, toHex, toRootHex} from "@lodestar/utils";
5
+ import {Logger, byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
6
6
  import {GENESIS_SLOT} from "../constants/index.js";
7
7
  import {IBeaconDb} from "../db/index.js";
8
8
  import {Metrics} from "../metrics/index.js";
@@ -26,7 +26,7 @@ export async function persistAnchorState(
26
26
 
27
27
  const latestBlockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(latestBlockHeader);
28
28
 
29
- if (Buffer.compare(blockRoot, latestBlockRoot) !== 0) {
29
+ if (!byteArrayEquals(blockRoot, latestBlockRoot)) {
30
30
  throw Error(
31
31
  `Genesis block root ${toRootHex(blockRoot)} does not match genesis state latest block root ${toRootHex(latestBlockRoot)}`
32
32
  );
@@ -46,12 +46,11 @@ import {
46
46
  ssz,
47
47
  sszTypesFor,
48
48
  } from "@lodestar/types";
49
- import {Logger, MapDef, pruneSetToMax, toRootHex} from "@lodestar/utils";
49
+ import {Logger, MapDef, byteArrayEquals, pruneSetToMax, toRootHex} from "@lodestar/utils";
50
50
  import {ZERO_HASH} from "../../constants/index.js";
51
51
  import {IBeaconDb} from "../../db/index.js";
52
52
  import {NUM_WITNESS, NUM_WITNESS_ELECTRA} from "../../db/repositories/lightclientSyncCommitteeWitness.js";
53
53
  import {Metrics} from "../../metrics/index.js";
54
- import {byteArrayEquals} from "../../util/bytes.js";
55
54
  import {IClock} from "../../util/clock.js";
56
55
  import {ChainEventEmitter} from "../emitter.js";
57
56
  import {LightClientServerError, LightClientServerErrorCode} from "../errors/lightClientError.js";
@@ -45,7 +45,6 @@ export type IChainOptions = BlockProcessOpts &
45
45
  broadcastValidationStrictness?: string;
46
46
  minSameMessageSignatureSetsToBatch: number;
47
47
  archiveDateEpochs?: number;
48
- nHistoricalStates?: boolean;
49
48
  nHistoricalStatesFileDataStore?: boolean;
50
49
  };
51
50
 
@@ -119,7 +118,6 @@ export const defaultChainOptions: IChainOptions = {
119
118
  // batching too much may block the I/O thread so if useWorker=false, suggest this value to be 32
120
119
  // since this batch attestation work is designed to work with useWorker=true, make this the lowest value
121
120
  minSameMessageSignatureSetsToBatch: 2,
122
- nHistoricalStates: true,
123
121
  // as of Feb 2025, this option turned out to be very useful:
124
122
  // - it allows to share a persisted checkpoint state to other nodes
125
123
  // - users can prune the persisted checkpoint state files manually to save disc space
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
2
2
  import {ProtoBlock} from "@lodestar/fork-choice";
3
3
  import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
4
4
  import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
- import {CheckpointHex} from "../stateCache/index.js";
5
+ import {CheckpointHex} from "../stateCache/types.js";
6
6
 
7
7
  export enum RegenCaller {
8
8
  getDuties = "getDuties",
@@ -5,8 +5,7 @@ import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
5
  import {Logger, toRootHex} from "@lodestar/utils";
6
6
  import {Metrics} from "../../metrics/index.js";
7
7
  import {JobItemQueue} from "../../util/queue/index.js";
8
- import {CheckpointHex} from "../stateCache/index.js";
9
- import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
8
+ import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
10
9
  import {RegenError, RegenErrorCode} from "./errors.js";
11
10
  import {
12
11
  IStateRegenerator,
@@ -18,6 +18,7 @@ import {Metrics} from "../../metrics/index.js";
18
18
  import {nextEventLoop} from "../../util/eventLoop.js";
19
19
  import {getCheckpointFromState} from "../blocks/utils/checkpoint.js";
20
20
  import {ChainEvent, ChainEventEmitter} from "../emitter.js";
21
+ import {SeenBlockInput} from "../seenCache/seenGossipBlockInput.js";
21
22
  import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
22
23
  import {ValidatorMonitor} from "../validatorMonitor.js";
23
24
  import {RegenError, RegenErrorCode} from "./errors.js";
@@ -28,6 +29,7 @@ export type RegenModules = {
28
29
  forkChoice: IForkChoice;
29
30
  blockStateCache: BlockStateCache;
30
31
  checkpointStateCache: CheckpointStateCache;
32
+ seenBlockInputCache: SeenBlockInput;
31
33
  config: ChainForkConfig;
32
34
  emitter: ChainEventEmitter;
33
35
  logger: Logger;
@@ -191,7 +193,10 @@ export class StateRegenerator implements IStateRegeneratorInternal {
191
193
  const protoBlocksAsc = blocksToReplay.reverse();
192
194
  for (const [i, protoBlock] of protoBlocksAsc.entries()) {
193
195
  replaySlots[i] = protoBlock.slot;
194
- blockPromises[i] = this.modules.db.block.get(fromHex(protoBlock.blockRoot));
196
+ const blockInput = this.modules.seenBlockInputCache.get(protoBlock.blockRoot);
197
+ blockPromises[i] = blockInput?.hasBlock()
198
+ ? Promise.resolve(blockInput.getBlock())
199
+ : this.modules.db.block.get(fromHex(protoBlock.blockRoot));
195
200
  }
196
201
 
197
202
  const logCtx = {stateRoot, caller, replaySlots: replaySlots.join(",")};
@@ -3,7 +3,7 @@ import {CheckpointWithHex} from "@lodestar/fork-choice";
3
3
  import {ForkName, ForkPostFulu, ForkPreGloas, isForkPostDeneb, isForkPostFulu, isForkPostGloas} from "@lodestar/params";
4
4
  import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
5
5
  import {BLSSignature, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
6
- import {LodestarError, Logger, pruneSetToMax} from "@lodestar/utils";
6
+ import {LodestarError, Logger, byteArrayEquals, pruneSetToMax} from "@lodestar/utils";
7
7
  import {Metrics} from "../../metrics/metrics.js";
8
8
  import {IClock} from "../../util/clock.js";
9
9
  import {CustodyConfig} from "../../util/dataColumns.js";
@@ -344,7 +344,7 @@ export class SeenBlockInput {
344
344
  return false;
345
345
  }
346
346
  // Only consider verified if the signature matches
347
- return Buffer.compare(cachedSignature, signature) === 0;
347
+ return byteArrayEquals(cachedSignature, signature);
348
348
  }
349
349
 
350
350
  /**
@@ -379,7 +379,7 @@ export class SeenBlockInput {
379
379
  let itemsToDelete = this.blockInputs.size - MAX_BLOCK_INPUT_CACHE_SIZE;
380
380
 
381
381
  if (itemsToDelete > 0) {
382
- const sorted = [...this.blockInputs.entries()].sort((a, b) => b[1].slot - a[1].slot);
382
+ const sorted = [...this.blockInputs.entries()].sort((a, b) => a[1].slot - b[1].slot);
383
383
  for (const [rootHex] of sorted) {
384
384
  this.blockInputs.delete(rootHex);
385
385
  itemsToDelete--;
@@ -20,7 +20,8 @@ export async function serializeState<T>(
20
20
  stateBytes = bufferWithKey.buffer;
21
21
  const dataView = new DataView(stateBytes.buffer, stateBytes.byteOffset, stateBytes.byteLength);
22
22
  state.serializeToBytes({uint8Array: stateBytes, dataView}, 0);
23
- return processFn(stateBytes);
23
+ // Await to ensure buffer is not released back to pool until processFn completes
24
+ return await processFn(stateBytes);
24
25
  }
25
26
  // release the buffer back to the pool automatically
26
27
  }
@@ -1,3 +1 @@
1
- export * from "./blockStateCacheImpl.js";
2
1
  export * from "./fifoBlockStateCache.js";
3
- export * from "./inMemoryCheckpointsCache.js";
@@ -31,7 +31,7 @@ type PersistentCheckpointStateCacheModules = {
31
31
  signal?: AbortSignal;
32
32
  datastore: CPStateDatastore;
33
33
  blockStateCache: BlockStateCache;
34
- bufferPool?: BufferPool | null;
34
+ bufferPool?: BufferPool;
35
35
  };
36
36
 
37
37
  /** checkpoint serialized as a string */
@@ -119,7 +119,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
119
119
  private readonly maxEpochsOnDisk: number;
120
120
  private readonly datastore: CPStateDatastore;
121
121
  private readonly blockStateCache: BlockStateCache;
122
- private readonly bufferPool?: BufferPool | null;
122
+ private readonly bufferPool?: BufferPool;
123
123
 
124
124
  constructor(
125
125
  {
@@ -851,6 +851,10 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
851
851
  };
852
852
  }
853
853
 
854
+ export function toCheckpointKey(cp: CheckpointHex): string {
855
+ return `${cp.rootHex}:${cp.epoch}`;
856
+ }
857
+
854
858
  function toCacheKey(cp: CheckpointHex | phase0.Checkpoint): CacheKey {
855
859
  if (isCheckpointHex(cp)) {
856
860
  return `${cp.rootHex}_${cp.epoch}`;
@@ -239,16 +239,15 @@ async function validateAggregateAndProof(
239
239
  // by the validator with index aggregate_and_proof.aggregator_index.
240
240
  // [REJECT] The aggregator signature, signed_aggregate_and_proof.signature, is valid.
241
241
  // [REJECT] The signature of aggregate is valid.
242
- const aggregator = chain.index2pubkey[aggregateAndProof.aggregatorIndex];
243
242
  const signingRoot = cachedAttData ? cachedAttData.signingRoot : getAttestationDataSigningRoot(chain.config, attData);
244
243
  const indexedAttestationSignatureSet = createAggregateSignatureSetFromComponents(
245
- indexedAttestation.attestingIndices.map((i) => chain.index2pubkey[i]),
244
+ indexedAttestation.attestingIndices,
246
245
  signingRoot,
247
246
  indexedAttestation.signature
248
247
  );
249
248
  const signatureSets = [
250
- getSelectionProofSignatureSet(chain.config, attSlot, aggregator, signedAggregateAndProof),
251
- getAggregateAndProofSignatureSet(chain.config, attEpoch, aggregator, signedAggregateAndProof),
249
+ getSelectionProofSignatureSet(chain.config, attSlot, aggregatorIndex, signedAggregateAndProof),
250
+ getAggregateAndProofSignatureSet(chain.config, attEpoch, aggregatorIndex, signedAggregateAndProof),
252
251
  indexedAttestationSignatureSet,
253
252
  ];
254
253
  // no need to write to SeenAttestationDatas
@@ -14,13 +14,13 @@ import {
14
14
  } from "@lodestar/params";
15
15
  import {
16
16
  EpochShuffling,
17
+ IndexedSignatureSet,
17
18
  ShufflingError,
18
19
  ShufflingErrorCode,
19
- SingleSignatureSet,
20
20
  computeEpochAtSlot,
21
21
  computeSigningRoot,
22
22
  computeStartSlotAtEpoch,
23
- createSingleSignatureSetFromComponents,
23
+ createIndexedSignatureSetFromComponents,
24
24
  } from "@lodestar/state-transition";
25
25
  import {
26
26
  CommitteeIndex,
@@ -90,7 +90,7 @@ export type GossipAttestation = {
90
90
  };
91
91
 
92
92
  export type Step0Result = AttestationValidationResult & {
93
- signatureSet: SingleSignatureSet;
93
+ signatureSet: IndexedSignatureSet;
94
94
  validatorIndex: number;
95
95
  };
96
96
 
@@ -125,7 +125,7 @@ export async function validateGossipAttestationsSameAttData(
125
125
  // step1: verify signatures of all valid attestations
126
126
  // map new index to index in resultOrErrors
127
127
  const newIndexToOldIndex = new Map<number, number>();
128
- const signatureSets: SingleSignatureSet[] = [];
128
+ const signatureSets: IndexedSignatureSet[] = [];
129
129
  let newIndex = 0;
130
130
  const step0Results: Step0Result[] = [];
131
131
  for (const [i, resultOrError] of step0ResultOrErrors.entries()) {
@@ -143,7 +143,7 @@ export async function validateGossipAttestationsSameAttData(
143
143
  if (batchableBls) {
144
144
  // all signature sets should have same signing root since we filtered in network processor
145
145
  signatureValids = await chain.bls.verifySignatureSetsSameMessage(
146
- signatureSets.map((set) => ({publicKey: set.pubkey, signature: set.signature})),
146
+ signatureSets.map((set) => ({publicKey: chain.index2pubkey[set.index], signature: set.signature})),
147
147
  signatureSets[0].signingRoot
148
148
  );
149
149
  } else {
@@ -498,7 +498,7 @@ async function validateAttestationNoSignatureCheck(
498
498
 
499
499
  // [REJECT] The signature of attestation is valid.
500
500
  const attestingIndices = [validatorIndex];
501
- let signatureSet: SingleSignatureSet;
501
+ let signatureSet: IndexedSignatureSet;
502
502
  let attDataRootHex: RootHex;
503
503
  const signature = attestationOrCache.attestation
504
504
  ? attestationOrCache.attestation.signature
@@ -513,18 +513,14 @@ async function validateAttestationNoSignatureCheck(
513
513
 
514
514
  if (attestationOrCache.cache) {
515
515
  // there could be up to 6% of cpu time to compute signing root if we don't clone the signature set
516
- signatureSet = createSingleSignatureSetFromComponents(
517
- chain.index2pubkey[validatorIndex],
516
+ signatureSet = createIndexedSignatureSetFromComponents(
517
+ validatorIndex,
518
518
  attestationOrCache.cache.signingRoot,
519
519
  signature
520
520
  );
521
521
  attDataRootHex = attestationOrCache.cache.attDataRootHex;
522
522
  } else {
523
- signatureSet = createSingleSignatureSetFromComponents(
524
- chain.index2pubkey[validatorIndex],
525
- getSigningRoot(),
526
- signature
527
- );
523
+ signatureSet = createIndexedSignatureSetFromComponents(validatorIndex, getSigningRoot(), signature);
528
524
 
529
525
  // add cached attestation data before verifying signature
530
526
  attDataRootHex = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(attData));
@@ -58,12 +58,7 @@ export async function validateAttesterSlashing(
58
58
  });
59
59
  }
60
60
 
61
- const signatureSets = getAttesterSlashingSignatureSets(
62
- chain.config,
63
- chain.index2pubkey,
64
- state.slot,
65
- attesterSlashing
66
- );
61
+ const signatureSets = getAttesterSlashingSignatureSets(chain.config, state.slot, attesterSlashing);
67
62
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
68
63
  throw new AttesterSlashingError(GossipAction.REJECT, {
69
64
  code: AttesterSlashingErrorCode.INVALID,
@@ -12,7 +12,7 @@ import {
12
12
  getBlockHeaderProposerSignatureSetByParentStateSlot,
13
13
  } from "@lodestar/state-transition";
14
14
  import {BlobIndex, Root, Slot, SubnetID, deneb, ssz} from "@lodestar/types";
15
- import {toRootHex, verifyMerkleBranch} from "@lodestar/utils";
15
+ import {byteArrayEquals, toRootHex, verifyMerkleBranch} from "@lodestar/utils";
16
16
  import {kzg} from "../../util/kzg.js";
17
17
  import {BlobSidecarErrorCode, BlobSidecarGossipError, BlobSidecarValidationError} from "../errors/blobSidecarError.js";
18
18
  import {GossipAction} from "../errors/gossipValidation.js";
@@ -139,7 +139,6 @@ export async function validateGossipBlobSidecar(
139
139
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blobSlot, blockHex, signature)) {
140
140
  const signatureSet = getBlockHeaderProposerSignatureSetByParentStateSlot(
141
141
  chain.config,
142
- chain.index2pubkey,
143
142
  blockState.slot,
144
143
  blobSidecar.signedBlockHeader
145
144
  );
@@ -227,7 +226,7 @@ export async function validateBlockBlobSidecars(
227
226
  const firstSidecarSignedBlockHeader = blobSidecars[0].signedBlockHeader;
228
227
  const firstSidecarBlockHeader = firstSidecarSignedBlockHeader.message;
229
228
  const firstBlockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(firstSidecarBlockHeader);
230
- if (Buffer.compare(blockRoot, firstBlockRoot) !== 0) {
229
+ if (!byteArrayEquals(blockRoot, firstBlockRoot)) {
231
230
  throw new BlobSidecarValidationError(
232
231
  {
233
232
  code: BlobSidecarErrorCode.INCORRECT_BLOCK,
@@ -244,11 +243,7 @@ export async function validateBlockBlobSidecars(
244
243
  const blockRootHex = toRootHex(blockRoot);
245
244
  const signature = firstSidecarSignedBlockHeader.signature;
246
245
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockSlot, blockRootHex, signature)) {
247
- const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(
248
- chain.config,
249
- chain.index2pubkey,
250
- firstSidecarSignedBlockHeader
251
- );
246
+ const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(chain.config, firstSidecarSignedBlockHeader);
252
247
 
253
248
  if (
254
249
  !(await chain.bls.verifySignatureSets([signatureSet], {