@lodestar/beacon-node 1.46.0 → 1.47.0-dev.02d2dbea03
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +6 -8
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +25 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -1
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/events/index.d.ts +1 -1
- package/lib/api/impl/events/index.d.ts.map +1 -1
- package/lib/api/impl/events/index.js +12 -3
- package/lib/api/impl/events/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +12 -13
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +12 -22
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/impl/validator/utils.d.ts +5 -0
- package/lib/api/impl/validator/utils.d.ts.map +1 -1
- package/lib/api/impl/validator/utils.js +18 -12
- package/lib/api/impl/validator/utils.js.map +1 -1
- package/lib/api/rest/base.d.ts.map +1 -1
- package/lib/api/rest/base.js +7 -0
- package/lib/api/rest/base.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.js +21 -0
- package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +3 -8
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +3 -2
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +12 -10
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +17 -11
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +2 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +6 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +14 -5
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.js +5 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +11 -16
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +22 -12
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/bls/index.d.ts +1 -1
- package/lib/chain/bls/index.d.ts.map +1 -1
- package/lib/chain/bls/interface.d.ts +5 -5
- package/lib/chain/bls/interface.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +5 -11
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +116 -101
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +5 -19
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +10 -65
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/multithread/types.d.ts +29 -8
- package/lib/chain/bls/multithread/types.d.ts.map +1 -1
- package/lib/chain/bls/multithread/types.js +12 -0
- package/lib/chain/bls/multithread/types.js.map +1 -1
- package/lib/chain/bls/multithread/utils.d.ts +4 -0
- package/lib/chain/bls/multithread/utils.d.ts.map +1 -1
- package/lib/chain/bls/multithread/utils.js +10 -0
- package/lib/chain/bls/multithread/utils.js.map +1 -1
- package/lib/chain/bls/multithread/worker.js +49 -23
- package/lib/chain/bls/multithread/worker.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -10
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +8 -45
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +4 -4
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +18 -19
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/builderCircuitBreaker.d.ts +6 -5
- package/lib/chain/builderCircuitBreaker.d.ts.map +1 -1
- package/lib/chain/builderCircuitBreaker.js +28 -15
- package/lib/chain/builderCircuitBreaker.js.map +1 -1
- package/lib/chain/chain.d.ts +5 -3
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +24 -8
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +2 -0
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +6 -1
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +6 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -1
- package/lib/chain/errors/proposerPreferences.js +1 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/attestationPool.d.ts +1 -1
- package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/attestationPool.js +1 -1
- package/lib/chain/opPools/attestationPool.js.map +1 -1
- package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts +16 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts.map +1 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.js +57 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.js.map +1 -0
- package/lib/chain/opPools/index.d.ts +1 -0
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js +1 -0
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +3 -3
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +1 -1
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +1 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/options.d.ts +1 -3
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +2 -2
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +2 -0
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +8 -3
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +4 -2
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +2 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +2 -2
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +5 -5
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/seenCache/seenAttesters.d.ts +9 -5
- package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
- package/lib/chain/seenCache/seenAttesters.js +25 -4
- package/lib/chain/seenCache/seenAttesters.js.map +1 -1
- package/lib/chain/seenCache/seenBlockProposers.d.ts +5 -1
- package/lib/chain/seenCache/seenBlockProposers.d.ts.map +1 -1
- package/lib/chain/seenCache/seenBlockProposers.js +17 -7
- package/lib/chain/seenCache/seenBlockProposers.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +28 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +121 -13
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +5 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +6 -0
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +47 -5
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +117 -7
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +3 -3
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +1 -4
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +21 -7
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +1 -2
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +5 -14
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -1
- package/lib/chain/validation/proposerPreferences.js +13 -4
- package/lib/chain/validation/proposerPreferences.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts +9 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +46 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/execution/builder/http.d.ts +10 -7
- package/lib/execution/builder/http.d.ts.map +1 -1
- package/lib/execution/builder/http.js +11 -8
- package/lib/execution/builder/http.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +3 -3
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +9 -9
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +71 -22
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +126 -52
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +13 -0
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +37 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +10 -2
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +22 -43
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +37 -6
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +5 -11
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/util.d.ts +0 -1
- package/lib/network/util.d.ts.map +1 -1
- package/lib/network/util.js +0 -4
- package/lib/network/util.js.map +1 -1
- package/lib/node/deferredVoluntaryExitPublisher.d.ts +15 -0
- package/lib/node/deferredVoluntaryExitPublisher.d.ts.map +1 -0
- package/lib/node/deferredVoluntaryExitPublisher.js +38 -0
- package/lib/node/deferredVoluntaryExitPublisher.js.map +1 -0
- package/lib/node/nodejs.d.ts +2 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +2 -0
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/batch.d.ts +23 -5
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +62 -23
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +2 -1
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +23 -10
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/utils/hashBlocks.d.ts +16 -4
- package/lib/sync/range/utils/hashBlocks.d.ts.map +1 -1
- package/lib/sync/range/utils/hashBlocks.js +49 -18
- package/lib/sync/range/utils/hashBlocks.js.map +1 -1
- package/lib/sync/types.d.ts +32 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +33 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +9 -0
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +187 -47
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +16 -11
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +3 -1
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/package.json +37 -37
- package/src/api/impl/beacon/blocks/index.ts +7 -8
- package/src/api/impl/beacon/pool/index.ts +27 -2
- package/src/api/impl/beacon/state/utils.ts +2 -1
- package/src/api/impl/events/index.ts +12 -4
- package/src/api/impl/lodestar/index.ts +12 -13
- package/src/api/impl/validator/index.ts +22 -27
- package/src/api/impl/validator/utils.ts +30 -15
- package/src/api/rest/base.ts +7 -0
- package/src/chain/archiveStore/archiveStore.ts +1 -1
- package/src/chain/archiveStore/historicalState/metrics.ts +22 -0
- package/src/chain/blocks/importBlock.ts +2 -7
- package/src/chain/blocks/importExecutionPayload.ts +13 -12
- package/src/chain/blocks/index.ts +21 -11
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +8 -2
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +17 -4
- package/src/chain/blocks/verifyBlock.ts +21 -25
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +25 -16
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +1 -9
- package/src/chain/bls/index.ts +1 -1
- package/src/chain/bls/interface.ts +7 -3
- package/src/chain/bls/multithread/index.ts +148 -120
- package/src/chain/bls/multithread/jobItem.ts +12 -82
- package/src/chain/bls/multithread/types.ts +33 -8
- package/src/chain/bls/multithread/utils.ts +11 -0
- package/src/chain/bls/multithread/worker.ts +85 -27
- package/src/chain/bls/singleThread.ts +11 -55
- package/src/chain/bls/utils.ts +23 -24
- package/src/chain/builderCircuitBreaker.ts +31 -17
- package/src/chain/chain.ts +25 -7
- package/src/chain/errors/blockError.ts +9 -3
- package/src/chain/errors/proposerPreferences.ts +7 -0
- package/src/chain/interface.ts +4 -1
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/opPools/attestationPool.ts +1 -1
- package/src/chain/opPools/deferredVoluntaryExitPool.ts +65 -0
- package/src/chain/opPools/index.ts +1 -0
- package/src/chain/opPools/payloadAttestationPool.ts +3 -3
- package/src/chain/opPools/syncCommitteeMessagePool.ts +1 -1
- package/src/chain/opPools/syncContributionAndProofPool.ts +1 -1
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/options.ts +1 -3
- package/src/chain/prepareNextSlot.ts +2 -2
- package/src/chain/produceBlock/produceBlockBody.ts +15 -2
- package/src/chain/regen/interface.ts +4 -2
- package/src/chain/regen/queued.ts +5 -5
- package/src/chain/seenCache/seenAttesters.ts +31 -5
- package/src/chain/seenCache/seenBlockProposers.ts +24 -7
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +143 -14
- package/src/chain/stateCache/fifoBlockStateCache.ts +8 -1
- package/src/chain/stateCache/persistentCheckpointsCache.ts +133 -8
- package/src/chain/stateCache/types.ts +3 -3
- package/src/chain/validation/attestation.ts +1 -7
- package/src/chain/validation/attesterSlashing.ts +1 -8
- package/src/chain/validation/block.ts +21 -7
- package/src/chain/validation/executionPayloadBid.ts +1 -2
- package/src/chain/validation/executionPayloadEnvelope.ts +0 -1
- package/src/chain/validation/payloadAttestationMessage.ts +6 -17
- package/src/chain/validation/proposerPreferences.ts +15 -5
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/voluntaryExit.ts +59 -2
- package/src/execution/builder/http.ts +11 -11
- package/src/metrics/metrics/beacon.ts +9 -9
- package/src/metrics/metrics/lodestar.ts +138 -57
- package/src/network/gossip/topic.ts +38 -0
- package/src/network/libp2p/index.ts +11 -2
- package/src/network/network.ts +27 -55
- package/src/network/processor/gossipHandlers.ts +40 -4
- package/src/network/reqresp/score.ts +5 -11
- package/src/network/util.ts +0 -5
- package/src/node/deferredVoluntaryExitPublisher.ts +54 -0
- package/src/node/nodejs.ts +5 -1
- package/src/sync/range/batch.ts +84 -29
- package/src/sync/range/chain.ts +26 -11
- package/src/sync/range/utils/hashBlocks.ts +56 -21
- package/src/sync/types.ts +36 -1
- package/src/sync/unknownBlock.ts +212 -53
- package/src/sync/utils/downloadByRange.ts +21 -12
- package/src/sync/utils/downloadByRoot.ts +3 -1
- package/lib/chain/bls/maybeBatch.d.ts +0 -12
- package/lib/chain/bls/maybeBatch.d.ts.map +0 -1
- package/lib/chain/bls/maybeBatch.js +0 -35
- package/lib/chain/bls/maybeBatch.js.map +0 -1
- package/src/chain/bls/maybeBatch.ts +0 -45
|
@@ -17,3 +17,14 @@ export function chunkifyMaximizeChunkSize<T>(arr: T[], minPerChunk: number): T[]
|
|
|
17
17
|
|
|
18
18
|
return arrArr;
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Splits an array into chunks that do not exceed a maximum size.
|
|
23
|
+
*/
|
|
24
|
+
export function chunkifyMaxChunkSize<T>(arr: T[], maxPerChunk: number): T[][] {
|
|
25
|
+
const chunks: T[][] = [];
|
|
26
|
+
for (let i = 0; i < arr.length; i += maxPerChunk) {
|
|
27
|
+
chunks.push(arr.slice(i, i + maxPerChunk));
|
|
28
|
+
}
|
|
29
|
+
return chunks;
|
|
30
|
+
}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import worker from "node:worker_threads";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type BlsSignatureSet,
|
|
4
|
+
verifySignatureSets,
|
|
5
|
+
verifySignatureSetsSameMessage,
|
|
6
|
+
} from "@chainsafe/lodestar-z/bls-verifier";
|
|
3
7
|
import {expose} from "@chainsafe/threads/worker";
|
|
4
|
-
import {
|
|
5
|
-
|
|
8
|
+
import {
|
|
9
|
+
BlsWorkReq,
|
|
10
|
+
BlsWorkResult,
|
|
11
|
+
JobQueueItemType,
|
|
12
|
+
VerificationCall,
|
|
13
|
+
VerificationCallOperation,
|
|
14
|
+
WorkResult,
|
|
15
|
+
WorkResultCode,
|
|
16
|
+
WorkerData,
|
|
17
|
+
} from "./types.js";
|
|
6
18
|
import {chunkifyMaximizeChunkSize} from "./utils.js";
|
|
7
19
|
|
|
8
20
|
/**
|
|
@@ -27,23 +39,45 @@ expose({
|
|
|
27
39
|
|
|
28
40
|
function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
29
41
|
const [startSec, startNs] = process.hrtime();
|
|
30
|
-
const results: WorkResult<boolean>[] = [];
|
|
42
|
+
const results: WorkResult<boolean[]>[] = [];
|
|
43
|
+
const verificationCalls: VerificationCall[] = [];
|
|
31
44
|
let batchRetries = 0;
|
|
32
45
|
let batchSigsSuccess = 0;
|
|
33
46
|
|
|
34
47
|
// If there are multiple batchable sets attempt batch verification with them
|
|
35
|
-
const batchableSets: {idx: number; sets:
|
|
36
|
-
const nonBatchableSets: {
|
|
48
|
+
const batchableSets: {idx: number; sets: BlsSignatureSet[]}[] = [];
|
|
49
|
+
const nonBatchableSets: {
|
|
50
|
+
idx: number;
|
|
51
|
+
sets: BlsSignatureSet[];
|
|
52
|
+
operation: VerificationCallOperation.single | VerificationCallOperation.fallback;
|
|
53
|
+
}[] = [];
|
|
37
54
|
|
|
38
55
|
// Split sets between batchable and non-batchable preserving their original index in the req array
|
|
39
56
|
for (let i = 0; i < workReqArr.length; i++) {
|
|
40
57
|
const workReq = workReqArr[i];
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
switch (workReq.type) {
|
|
59
|
+
case JobQueueItemType.default: {
|
|
60
|
+
const {sets} = workReq;
|
|
61
|
+
if (workReq.opts.batchable) {
|
|
62
|
+
batchableSets.push({idx: i, sets});
|
|
63
|
+
} else {
|
|
64
|
+
nonBatchableSets.push({idx: i, sets, operation: VerificationCallOperation.single});
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case JobQueueItemType.sameMessage:
|
|
69
|
+
try {
|
|
70
|
+
const result = recordVerificationCall(
|
|
71
|
+
verificationCalls,
|
|
72
|
+
VerificationCallOperation.sameMessage,
|
|
73
|
+
workReq.sets.length,
|
|
74
|
+
() => verifySignatureSetsSameMessage(workReq.sets, workReq.message)
|
|
75
|
+
);
|
|
76
|
+
results[i] = {code: WorkResultCode.success, result};
|
|
77
|
+
} catch (e) {
|
|
78
|
+
results[i] = {code: WorkResultCode.error, error: e as Error};
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
47
81
|
}
|
|
48
82
|
}
|
|
49
83
|
|
|
@@ -52,7 +86,7 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
|
52
86
|
const batchableChunks = chunkifyMaximizeChunkSize(batchableSets, BATCHABLE_MIN_PER_CHUNK);
|
|
53
87
|
|
|
54
88
|
for (const batchableChunk of batchableChunks) {
|
|
55
|
-
const allSets:
|
|
89
|
+
const allSets: BlsSignatureSet[] = [];
|
|
56
90
|
for (const {sets} of batchableChunk) {
|
|
57
91
|
for (const set of sets) {
|
|
58
92
|
allSets.push(set);
|
|
@@ -61,33 +95,49 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
|
61
95
|
|
|
62
96
|
try {
|
|
63
97
|
// Attempt to verify multiple sets at once
|
|
64
|
-
const isValid =
|
|
98
|
+
const isValid = recordVerificationCall(verificationCalls, VerificationCallOperation.batch, allSets.length, () =>
|
|
99
|
+
verifySignatureSets(allSets)
|
|
100
|
+
);
|
|
65
101
|
|
|
66
102
|
if (isValid) {
|
|
67
103
|
// The entire batch is valid, return success to all
|
|
68
104
|
for (const {idx, sets} of batchableChunk) {
|
|
69
105
|
batchSigsSuccess += sets.length;
|
|
70
|
-
results[idx] = {code: WorkResultCode.success, result: isValid};
|
|
106
|
+
results[idx] = {code: WorkResultCode.success, result: [isValid]};
|
|
71
107
|
}
|
|
72
108
|
} else {
|
|
73
109
|
batchRetries++;
|
|
74
110
|
// Re-verify all sigs
|
|
75
|
-
nonBatchableSets.push(
|
|
111
|
+
nonBatchableSets.push(
|
|
112
|
+
...batchableChunk.map(({idx, sets}) => ({
|
|
113
|
+
idx,
|
|
114
|
+
sets,
|
|
115
|
+
operation: VerificationCallOperation.fallback as const,
|
|
116
|
+
}))
|
|
117
|
+
);
|
|
76
118
|
}
|
|
77
119
|
} catch (_e) {
|
|
78
120
|
// TODO: Ignore this error expecting that the same error will happen when re-verifying the set individually
|
|
79
|
-
// It's not ideal but
|
|
121
|
+
// It's not ideal but the BLS implementation may throw errors on some conditions
|
|
80
122
|
batchRetries++;
|
|
81
123
|
// Re-verify all sigs
|
|
82
|
-
nonBatchableSets.push(
|
|
124
|
+
nonBatchableSets.push(
|
|
125
|
+
...batchableChunk.map(({idx, sets}) => ({
|
|
126
|
+
idx,
|
|
127
|
+
sets,
|
|
128
|
+
operation: VerificationCallOperation.fallback as const,
|
|
129
|
+
}))
|
|
130
|
+
);
|
|
83
131
|
}
|
|
84
132
|
}
|
|
85
133
|
}
|
|
86
134
|
|
|
87
|
-
for (const {idx, sets} of nonBatchableSets) {
|
|
135
|
+
for (const {idx, sets, operation} of nonBatchableSets) {
|
|
88
136
|
try {
|
|
89
|
-
const isValid =
|
|
90
|
-
|
|
137
|
+
const isValid = recordVerificationCall(verificationCalls, operation, sets.length, () =>
|
|
138
|
+
verifySignatureSets(sets)
|
|
139
|
+
);
|
|
140
|
+
results[idx] = {code: WorkResultCode.success, result: [isValid]};
|
|
91
141
|
} catch (e) {
|
|
92
142
|
results[idx] = {code: WorkResultCode.error, error: e as Error};
|
|
93
143
|
}
|
|
@@ -99,16 +149,24 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
|
99
149
|
workerId,
|
|
100
150
|
batchRetries,
|
|
101
151
|
batchSigsSuccess,
|
|
152
|
+
verificationCalls,
|
|
102
153
|
workerStartTime: [startSec, startNs],
|
|
103
154
|
workerEndTime: [workerEndSec, workerEndNs],
|
|
104
155
|
results,
|
|
105
156
|
};
|
|
106
157
|
}
|
|
107
158
|
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
159
|
+
function recordVerificationCall<T>(
|
|
160
|
+
calls: VerificationCall[],
|
|
161
|
+
operation: VerificationCallOperation,
|
|
162
|
+
signatureSets: number,
|
|
163
|
+
verify: () => T
|
|
164
|
+
): T {
|
|
165
|
+
const startTime = process.hrtime();
|
|
166
|
+
try {
|
|
167
|
+
return verify();
|
|
168
|
+
} finally {
|
|
169
|
+
const [seconds, nanoseconds] = process.hrtime(startTime);
|
|
170
|
+
calls.push({operation, signatureSets, duration: seconds + nanoseconds / 1e9});
|
|
171
|
+
}
|
|
114
172
|
}
|
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {ISignatureSet
|
|
1
|
+
import {verifySignatureSetsSameMessage} from "@chainsafe/lodestar-z/bls-verifier";
|
|
2
|
+
import {ISignatureSet} from "@lodestar/state-transition";
|
|
3
3
|
import {Metrics} from "../../metrics/index.js";
|
|
4
|
-
import {IBlsVerifier} from "./interface.js";
|
|
5
|
-
import {
|
|
6
|
-
import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
|
|
4
|
+
import {IBlsVerifier, SameMessageSignatureSet} from "./interface.js";
|
|
5
|
+
import {chunkSameMessageSignatureSets, getAggregatedPubkeysCount, verifySignatureSetsInBatches} from "./utils.js";
|
|
7
6
|
|
|
8
7
|
export class BlsSingleThreadVerifier implements IBlsVerifier {
|
|
9
8
|
private readonly metrics: Metrics | null;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
constructor({metrics = null, pubkeyCache}: {metrics: Metrics | null; pubkeyCache: PubkeyCache}) {
|
|
9
|
+
constructor({metrics = null}: {metrics: Metrics | null}) {
|
|
13
10
|
this.metrics = metrics;
|
|
14
|
-
this.pubkeyCache = pubkeyCache;
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
|
|
18
14
|
this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
|
|
19
15
|
|
|
20
|
-
const setsAggregated = sets.map((set) => ({
|
|
21
|
-
publicKey: getAggregatedPubkey(set, this.pubkeyCache, this.metrics),
|
|
22
|
-
message: set.signingRoot,
|
|
23
|
-
signature: set.signature,
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
// Count time after aggregating
|
|
27
16
|
const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
|
|
28
|
-
const isValid =
|
|
17
|
+
const isValid = verifySignatureSetsInBatches(sets);
|
|
29
18
|
|
|
30
19
|
// Don't use a try/catch, only count run without exceptions
|
|
31
20
|
if (timer) {
|
|
@@ -35,46 +24,13 @@ export class BlsSingleThreadVerifier implements IBlsVerifier {
|
|
|
35
24
|
return isValid;
|
|
36
25
|
}
|
|
37
26
|
|
|
38
|
-
async verifySignatureSetsSameMessage(
|
|
39
|
-
sets: {publicKey: PublicKey; signature: Uint8Array}[],
|
|
40
|
-
message: Uint8Array
|
|
41
|
-
): Promise<boolean[]> {
|
|
27
|
+
async verifySignatureSetsSameMessage(sets: SameMessageSignatureSet[], message: Uint8Array): Promise<boolean[]> {
|
|
42
28
|
const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const signatures = sets.map((set) => {
|
|
47
|
-
try {
|
|
48
|
-
return Signature.fromBytes(set.signature, true);
|
|
49
|
-
} catch (_) {
|
|
50
|
-
// at least one set has malformed signature
|
|
51
|
-
isAllValid = false;
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
if (isAllValid) {
|
|
57
|
-
const signature = aggregateSignatures(signatures as Signature[]);
|
|
58
|
-
isAllValid = verify(message, pubkey, signature);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let result: boolean[];
|
|
62
|
-
if (isAllValid) {
|
|
63
|
-
result = sets.map(() => true);
|
|
64
|
-
} else {
|
|
65
|
-
result = sets.map((set, i) => {
|
|
66
|
-
const sig = signatures[i];
|
|
67
|
-
if (sig === null) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
return verify(message, set.publicKey, sig);
|
|
71
|
-
});
|
|
29
|
+
const result: boolean[] = [];
|
|
30
|
+
for (const setsChunk of chunkSameMessageSignatureSets(sets)) {
|
|
31
|
+
result.push(...verifySignatureSetsSameMessage(setsChunk, message));
|
|
72
32
|
}
|
|
73
|
-
|
|
74
|
-
if (timer) {
|
|
75
|
-
timer();
|
|
76
|
-
}
|
|
77
|
-
|
|
33
|
+
timer?.();
|
|
78
34
|
return result;
|
|
79
35
|
}
|
|
80
36
|
|
package/src/chain/bls/utils.ts
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
BLS_VERIFIER_MAX_BATCH_SIZE,
|
|
3
|
+
BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE,
|
|
4
|
+
verifySignatureSets,
|
|
5
|
+
} from "@chainsafe/lodestar-z/bls-verifier";
|
|
6
|
+
import {ISignatureSet, SignatureSetType, toBlsSignatureSet} from "@lodestar/state-transition";
|
|
7
|
+
import {SameMessageSignatureSet} from "./interface.js";
|
|
4
8
|
|
|
5
|
-
export function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
): PublicKey {
|
|
10
|
-
switch (signatureSet.type) {
|
|
11
|
-
case SignatureSetType.single:
|
|
12
|
-
return signatureSet.pubkey;
|
|
9
|
+
export function verifySignatureSetsInBatches(signatureSets: ISignatureSet[]): boolean {
|
|
10
|
+
if (signatureSets.length === 0) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
for (let start = 0; start < signatureSets.length; start += BLS_VERIFIER_MAX_BATCH_SIZE) {
|
|
15
|
+
const sets = signatureSets.slice(start, start + BLS_VERIFIER_MAX_BATCH_SIZE).map(toBlsSignatureSet);
|
|
16
|
+
if (!verifySignatureSets(sets)) {
|
|
17
|
+
return false;
|
|
16
18
|
}
|
|
19
|
+
}
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const pubkeys = signatureSet.indices.map((i) => {
|
|
21
|
-
return pubkeyCache.getOrThrow(i);
|
|
22
|
-
});
|
|
23
|
-
const aggregated = aggregatePublicKeys(pubkeys);
|
|
24
|
-
timer?.();
|
|
25
|
-
return aggregated;
|
|
26
|
-
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
export function chunkSameMessageSignatureSets(sets: SameMessageSignatureSet[]): SameMessageSignatureSet[][] {
|
|
25
|
+
const chunks: SameMessageSignatureSet[][] = [];
|
|
26
|
+
for (let start = 0; start < sets.length; start += BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE) {
|
|
27
|
+
chunks.push(sets.slice(start, start + BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE));
|
|
30
28
|
}
|
|
29
|
+
return chunks;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
export function getAggregatedPubkeysCount(signatureSets: ISignatureSet[]): number {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {IForkChoice} from "@lodestar/fork-choice";
|
|
1
|
+
import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
2
2
|
import {Slot} from "@lodestar/types";
|
|
3
3
|
import {Logger} from "@lodestar/utils";
|
|
4
4
|
import {getFaultInspectionParams} from "../execution/builder/http.js";
|
|
@@ -15,11 +15,15 @@ export type BuilderCircuitBreakerModules = {
|
|
|
15
15
|
metrics: Metrics | null;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
/** Four observations is the minimum useful recovery sample for the default ~25% fault budget */
|
|
19
|
+
const MIN_BLOCKS_TO_DEACTIVATE = 4;
|
|
20
|
+
|
|
18
21
|
/**
|
|
19
22
|
* Post-gloas circuit breaker for builder bids. The beacon block is produced by the proposer
|
|
20
23
|
* regardless of bid source, so missed blocks are not a useful builder health signal. Instead
|
|
21
|
-
* count blocks
|
|
22
|
-
*
|
|
24
|
+
* count canonical blocks selected as EMPTY. Activate when the proportion of EMPTY blocks exceeds
|
|
25
|
+
* the fault budget, and resume selecting builder bids only when the observed blocks are within
|
|
26
|
+
* budget and meet the minimum recovery sample size.
|
|
23
27
|
*/
|
|
24
28
|
export class BuilderCircuitBreaker {
|
|
25
29
|
readonly faultInspectionWindow: number;
|
|
@@ -35,39 +39,49 @@ export class BuilderCircuitBreaker {
|
|
|
35
39
|
const {faultInspectionWindow, allowedFaults} = getFaultInspectionParams(opts);
|
|
36
40
|
this.faultInspectionWindow = faultInspectionWindow;
|
|
37
41
|
this.allowedFaults = allowedFaults;
|
|
42
|
+
this.modules.logger.info("Builder circuit breaker initialized", {faultInspectionWindow, allowedFaults});
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
/** Whether builder bids must be ignored for a block produced at clockSlot */
|
|
41
|
-
isActive(clockSlot: Slot): boolean {
|
|
42
|
-
this.update(clockSlot);
|
|
46
|
+
isActive(clockSlot: Slot, head: ProtoBlock): boolean {
|
|
47
|
+
this.update(clockSlot, head);
|
|
43
48
|
return this.active;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
update(clockSlot: Slot): void {
|
|
51
|
+
update(clockSlot: Slot, head: ProtoBlock): void {
|
|
47
52
|
if (clockSlot <= this.lastUpdatedSlot) {
|
|
48
53
|
return;
|
|
49
54
|
}
|
|
50
55
|
this.lastUpdatedSlot = clockSlot;
|
|
51
56
|
|
|
52
|
-
// Exclude clockSlot itself, its payload
|
|
53
|
-
const {
|
|
57
|
+
// Exclude clockSlot itself, its payload status may still be unresolved
|
|
58
|
+
const {full, empty} = this.modules.forkChoice.getCanonicalPayloadCounts(
|
|
54
59
|
Math.max(clockSlot - this.faultInspectionWindow, 0),
|
|
55
|
-
clockSlot - 1
|
|
60
|
+
clockSlot - 1,
|
|
61
|
+
head
|
|
56
62
|
);
|
|
57
|
-
const
|
|
63
|
+
const canonicalBlocks = full + empty;
|
|
58
64
|
|
|
59
65
|
const wasActive = this.active;
|
|
60
|
-
// Scale the fault budget by blocks
|
|
61
|
-
|
|
66
|
+
// Scale the fault budget by canonical blocks so sparse windows still trigger on high EMPTY rates
|
|
67
|
+
const exceedsFaultBudget = empty * this.faultInspectionWindow > this.allowedFaults * canonicalBlocks;
|
|
68
|
+
if (exceedsFaultBudget) {
|
|
69
|
+
this.active = true;
|
|
70
|
+
} else if (canonicalBlocks >= MIN_BLOCKS_TO_DEACTIVATE) {
|
|
71
|
+
// Require a minimum sample within the fault budget before accepting builder bids again
|
|
72
|
+
this.active = false;
|
|
73
|
+
}
|
|
62
74
|
|
|
63
75
|
this.modules.metrics?.builderCircuitBreaker.active.set(this.active ? 1 : 0);
|
|
64
|
-
this.modules.metrics?.builderCircuitBreaker.
|
|
65
|
-
this.modules.metrics?.builderCircuitBreaker.
|
|
66
|
-
this.modules.metrics?.builderCircuitBreaker.
|
|
76
|
+
this.modules.metrics?.builderCircuitBreaker.canonicalBlocks.set(canonicalBlocks);
|
|
77
|
+
this.modules.metrics?.builderCircuitBreaker.fullBlocks.set(full);
|
|
78
|
+
this.modules.metrics?.builderCircuitBreaker.emptyBlocks.set(empty);
|
|
67
79
|
|
|
68
80
|
const logCtx = {
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
clockSlot,
|
|
82
|
+
canonicalBlocks,
|
|
83
|
+
full,
|
|
84
|
+
empty,
|
|
71
85
|
faultInspectionWindow: this.faultInspectionWindow,
|
|
72
86
|
allowedFaults: this.allowedFaults,
|
|
73
87
|
};
|
package/src/chain/chain.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
|
+
import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
|
|
3
4
|
import {Type} from "@chainsafe/ssz";
|
|
4
5
|
import {routes} from "@lodestar/api";
|
|
5
6
|
import {BeaconConfig} from "@lodestar/config";
|
|
@@ -25,7 +26,6 @@ import {
|
|
|
25
26
|
EffectiveBalanceIncrements,
|
|
26
27
|
EpochShuffling,
|
|
27
28
|
IBeaconStateView,
|
|
28
|
-
PubkeyCache,
|
|
29
29
|
computeEndSlotAtEpoch,
|
|
30
30
|
computeEpochAtSlot,
|
|
31
31
|
computeStartSlotAtEpoch,
|
|
@@ -79,6 +79,7 @@ import {CheckpointBalancesCache} from "./balancesCache.js";
|
|
|
79
79
|
import {BeaconProposerCache} from "./beaconProposerCache.js";
|
|
80
80
|
import {IBlockInput, isBlockInputBlobs, isBlockInputColumns} from "./blocks/blockInput/index.js";
|
|
81
81
|
import {BlockProcessor, ImportBlockOpts} from "./blocks/index.js";
|
|
82
|
+
import {PayloadEnvelopeInputSource} from "./blocks/payloadEnvelopeInput/index.js";
|
|
82
83
|
import {PayloadEnvelopeProcessor} from "./blocks/payloadEnvelopeProcessor.js";
|
|
83
84
|
import {ImportPayloadOpts} from "./blocks/types.js";
|
|
84
85
|
import {persistBlockInput} from "./blocks/writeBlockInputToDb.js";
|
|
@@ -94,6 +95,7 @@ import {LightClientServer} from "./lightClient/index.js";
|
|
|
94
95
|
import {
|
|
95
96
|
AggregatedAttestationPool,
|
|
96
97
|
AttestationPool,
|
|
98
|
+
DeferredVoluntaryExitPool,
|
|
97
99
|
ExecutionPayloadBidPool,
|
|
98
100
|
OpPool,
|
|
99
101
|
PayloadAttestationPool,
|
|
@@ -193,6 +195,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
193
195
|
readonly payloadAttestationPool: PayloadAttestationPool;
|
|
194
196
|
readonly proposerPreferencesPool = new ProposerPreferencesPool();
|
|
195
197
|
readonly opPool: OpPool;
|
|
198
|
+
readonly deferredVoluntaryExitPool: DeferredVoluntaryExitPool;
|
|
196
199
|
|
|
197
200
|
// Gossip seen cache
|
|
198
201
|
readonly seenAttesters = new SeenAttesters();
|
|
@@ -307,8 +310,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
307
310
|
const emitter = new ChainEventEmitter();
|
|
308
311
|
// by default, verify signatures on both main threads and worker threads
|
|
309
312
|
const bls = opts.blsVerifyAllMainThread
|
|
310
|
-
? new BlsSingleThreadVerifier({metrics
|
|
311
|
-
: new BlsMultiThreadWorkerPool(opts, {logger, metrics
|
|
313
|
+
? new BlsSingleThreadVerifier({metrics})
|
|
314
|
+
: new BlsMultiThreadWorkerPool(opts, {logger, metrics});
|
|
312
315
|
|
|
313
316
|
if (!clock) clock = new Clock({config, genesisTime: this.genesisTime, signal});
|
|
314
317
|
|
|
@@ -320,6 +323,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
320
323
|
this.executionPayloadBidPool = new ExecutionPayloadBidPool();
|
|
321
324
|
this.payloadAttestationPool = new PayloadAttestationPool(config, clock, metrics);
|
|
322
325
|
this.opPool = new OpPool(config);
|
|
326
|
+
this.deferredVoluntaryExitPool = new DeferredVoluntaryExitPool(logger);
|
|
323
327
|
|
|
324
328
|
this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
|
|
325
329
|
this.seenContributionAndProof = new SeenContributionAndProof(metrics);
|
|
@@ -451,6 +455,9 @@ export class BeaconChain implements IBeaconChain {
|
|
|
451
455
|
chainEvents: emitter,
|
|
452
456
|
signal,
|
|
453
457
|
serializedCache: this.serializedCache,
|
|
458
|
+
db,
|
|
459
|
+
seenBlockInputCache: this.seenBlockInputCache,
|
|
460
|
+
custodyConfig: this.custodyConfig,
|
|
454
461
|
metrics,
|
|
455
462
|
logger,
|
|
456
463
|
});
|
|
@@ -466,7 +473,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
466
473
|
bid: anchorBid,
|
|
467
474
|
sampledColumns: this.custodyConfig.sampledColumns,
|
|
468
475
|
custodyColumns: this.custodyConfig.custodyColumns,
|
|
469
|
-
|
|
476
|
+
seenTimestampSec: Date.now() / 1000,
|
|
477
|
+
source: PayloadEnvelopeInputSource.anchorState,
|
|
470
478
|
});
|
|
471
479
|
}
|
|
472
480
|
|
|
@@ -579,7 +587,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
579
587
|
// seenAggregators = single aggregator index, not participants of the aggregate
|
|
580
588
|
this.seenAggregators.isKnown(epoch, index) ||
|
|
581
589
|
// seenPayloadAttesters = single signer of payload attestation message
|
|
582
|
-
this.seenPayloadAttesters.
|
|
590
|
+
this.seenPayloadAttesters.seenAtEpoch(epoch, index) ||
|
|
583
591
|
// seenBlockProposers = single block proposer
|
|
584
592
|
this.seenBlockProposers.seenAtEpoch(epoch, index)
|
|
585
593
|
);
|
|
@@ -1072,6 +1080,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1072
1080
|
graffiti,
|
|
1073
1081
|
slot,
|
|
1074
1082
|
feeRecipient,
|
|
1083
|
+
strictFeeRecipientCheck,
|
|
1075
1084
|
commonBlockBodyPromise,
|
|
1076
1085
|
parentBlock,
|
|
1077
1086
|
builderBid,
|
|
@@ -1089,7 +1098,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1089
1098
|
RegenCaller.produceBlock
|
|
1090
1099
|
);
|
|
1091
1100
|
const proposerIndex = state.getBeaconProposer(slot);
|
|
1092
|
-
const proposerPubKey = this.pubkeyCache.
|
|
1101
|
+
const proposerPubKey = this.pubkeyCache.getPubkeyBytesOrThrow(proposerIndex);
|
|
1093
1102
|
|
|
1094
1103
|
const {body, produceResult, executionPayloadValue, shouldOverrideBuilder} = await produceBlockBody.call(
|
|
1095
1104
|
this,
|
|
@@ -1100,6 +1109,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1100
1109
|
graffiti,
|
|
1101
1110
|
slot,
|
|
1102
1111
|
feeRecipient,
|
|
1112
|
+
strictFeeRecipientCheck,
|
|
1103
1113
|
parentBlock,
|
|
1104
1114
|
proposerIndex,
|
|
1105
1115
|
proposerPubKey,
|
|
@@ -1217,7 +1227,12 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1217
1227
|
this.emitter.emit(routes.events.EventType.proposerSlashing, proposerSlashing);
|
|
1218
1228
|
this.emitter.emit(ChainEvent.publishProposerSlashing, proposerSlashing);
|
|
1219
1229
|
this.metrics?.opPool.proposerSlashingsProduced.inc();
|
|
1220
|
-
this.logger.info("Produced proposer slashing from observed equivocation", {
|
|
1230
|
+
this.logger.info("Produced proposer slashing from observed equivocation", {
|
|
1231
|
+
slot: blockSlot,
|
|
1232
|
+
proposerIndex,
|
|
1233
|
+
header1Root: toRootHex(ssz.phase0.BeaconBlockHeader.hashTreeRoot(header1.message)),
|
|
1234
|
+
header2Root: toRootHex(ssz.phase0.BeaconBlockHeader.hashTreeRoot(header2.message)),
|
|
1235
|
+
});
|
|
1221
1236
|
} finally {
|
|
1222
1237
|
this.producingProposerSlashing.delete(proposerIndex);
|
|
1223
1238
|
}
|
|
@@ -1562,6 +1577,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1562
1577
|
// aggregatedAttestationPool tracks metrics on its own
|
|
1563
1578
|
metrics.opPool.attestationPool.size.set(this.attestationPool.getAttestationCount());
|
|
1564
1579
|
metrics.opPool.attesterSlashingPoolSize.set(this.opPool.attesterSlashingsSize);
|
|
1580
|
+
metrics.opPool.deferredVoluntaryExitPool.size.set(this.deferredVoluntaryExitPool.size());
|
|
1565
1581
|
metrics.opPool.proposerSlashingPoolSize.set(this.opPool.proposerSlashingsSize);
|
|
1566
1582
|
metrics.opPool.voluntaryExitPoolSize.set(this.opPool.voluntaryExitsSize);
|
|
1567
1583
|
metrics.opPool.syncCommitteeMessagePoolSize.set(this.syncCommitteeMessagePool.size);
|
|
@@ -1570,6 +1586,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1570
1586
|
// syncContributionAndProofPool tracks metrics on its own
|
|
1571
1587
|
metrics.opPool.blsToExecutionChangePoolSize.set(this.opPool.blsToExecutionChangeSize);
|
|
1572
1588
|
metrics.chain.blacklistedBlocks.set(this.blacklistedBlocks.size);
|
|
1589
|
+
metrics.bls.pubkeyCacheSize.set(this.pubkeyCache.size);
|
|
1590
|
+
metrics.bls.pubkeyCacheCapacity.set(this.pubkeyCache.capacity);
|
|
1573
1591
|
|
|
1574
1592
|
const headState = this.getHeadState();
|
|
1575
1593
|
if (isStatePostElectra(headState)) {
|
|
@@ -118,7 +118,7 @@ export type BlockErrorType =
|
|
|
118
118
|
| {code: BlockErrorCode.GENESIS_BLOCK}
|
|
119
119
|
| {code: BlockErrorCode.WOULD_REVERT_FINALIZED_SLOT; blockSlot: Slot; finalizedSlot: Slot}
|
|
120
120
|
| {code: BlockErrorCode.ALREADY_KNOWN; root: RootHex}
|
|
121
|
-
| {code: BlockErrorCode.REPEAT_PROPOSAL; proposerIndex: ValidatorIndex}
|
|
121
|
+
| {code: BlockErrorCode.REPEAT_PROPOSAL; proposerIndex: ValidatorIndex; root: RootHex}
|
|
122
122
|
| {code: BlockErrorCode.BLOCK_SLOT_LIMIT_REACHED}
|
|
123
123
|
| {code: BlockErrorCode.INCORRECT_PROPOSER; proposerIndex: ValidatorIndex}
|
|
124
124
|
| {code: BlockErrorCode.PROPOSAL_SIGNATURE_INVALID; blockSlot: Slot}
|
|
@@ -136,7 +136,7 @@ export type BlockErrorType =
|
|
|
136
136
|
| {code: BlockErrorCode.NON_LINEAR_PARENT_ROOTS}
|
|
137
137
|
| {code: BlockErrorCode.NON_LINEAR_SLOTS}
|
|
138
138
|
| {code: BlockErrorCode.ENVELOPE_BLOCK_ROOT_MISMATCH; envelopeBlockRoot: RootHex; blockRoot: RootHex}
|
|
139
|
-
| {code: BlockErrorCode.PER_BLOCK_PROCESSING_ERROR; error: Error}
|
|
139
|
+
| {code: BlockErrorCode.PER_BLOCK_PROCESSING_ERROR; blockRoot: RootHex; error: Error}
|
|
140
140
|
| {code: BlockErrorCode.BEACON_CHAIN_ERROR; error: Error}
|
|
141
141
|
| {code: BlockErrorCode.KNOWN_BAD_BLOCK}
|
|
142
142
|
| {code: BlockErrorCode.BLACKLISTED_BLOCK}
|
|
@@ -184,13 +184,19 @@ export function isBlockErrorAborted(e: unknown): e is BlockError {
|
|
|
184
184
|
export function renderBlockErrorType(type: BlockErrorType): Record<string, string | number | null> {
|
|
185
185
|
switch (type.code) {
|
|
186
186
|
case BlockErrorCode.PRESTATE_MISSING:
|
|
187
|
-
case BlockErrorCode.PER_BLOCK_PROCESSING_ERROR:
|
|
188
187
|
case BlockErrorCode.BEACON_CHAIN_ERROR:
|
|
189
188
|
return {
|
|
190
189
|
code: type.code,
|
|
191
190
|
error: type.error.message,
|
|
192
191
|
};
|
|
193
192
|
|
|
193
|
+
case BlockErrorCode.PER_BLOCK_PROCESSING_ERROR:
|
|
194
|
+
return {
|
|
195
|
+
code: type.code,
|
|
196
|
+
blockRoot: type.blockRoot,
|
|
197
|
+
error: type.error.message,
|
|
198
|
+
};
|
|
199
|
+
|
|
194
200
|
case BlockErrorCode.INVALID_SIGNATURE:
|
|
195
201
|
return {
|
|
196
202
|
code: type.code,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import {ForkName} from "@lodestar/params";
|
|
1
2
|
import {Epoch, RootHex, Slot, ValidatorIndex} from "@lodestar/types";
|
|
2
3
|
import {GossipActionError} from "./gossipValidation.js";
|
|
3
4
|
|
|
4
5
|
export enum ProposerPreferencesErrorCode {
|
|
6
|
+
PRE_GLOAS_PROPOSAL_SLOT = "PROPOSER_PREFERENCES_ERROR_PRE_GLOAS_PROPOSAL_SLOT",
|
|
5
7
|
INVALID_EPOCH = "PROPOSER_PREFERENCES_ERROR_INVALID_EPOCH",
|
|
6
8
|
PROPOSAL_SLOT_PASSED = "PROPOSER_PREFERENCES_ERROR_PROPOSAL_SLOT_PASSED",
|
|
7
9
|
UNKNOWN_DEPENDENT_ROOT = "PROPOSER_PREFERENCES_ERROR_UNKNOWN_DEPENDENT_ROOT",
|
|
@@ -13,6 +15,11 @@ export enum ProposerPreferencesErrorCode {
|
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export type ProposerPreferencesErrorType =
|
|
18
|
+
| {
|
|
19
|
+
code: ProposerPreferencesErrorCode.PRE_GLOAS_PROPOSAL_SLOT;
|
|
20
|
+
proposalSlot: Slot;
|
|
21
|
+
proposalFork: ForkName;
|
|
22
|
+
}
|
|
16
23
|
| {
|
|
17
24
|
code: ProposerPreferencesErrorCode.INVALID_EPOCH;
|
|
18
25
|
proposalSlot: Slot;
|
package/src/chain/interface.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
|
|
1
2
|
import {Type} from "@chainsafe/ssz";
|
|
2
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
4
|
import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
4
|
-
import {EpochShuffling, IBeaconStateView
|
|
5
|
+
import {EpochShuffling, IBeaconStateView} from "@lodestar/state-transition";
|
|
5
6
|
import {
|
|
6
7
|
BeaconBlock,
|
|
7
8
|
BlindedBeaconBlock,
|
|
@@ -44,6 +45,7 @@ import {LightClientServer} from "./lightClient/index.js";
|
|
|
44
45
|
import {AggregatedAttestationPool} from "./opPools/aggregatedAttestationPool.js";
|
|
45
46
|
import {
|
|
46
47
|
AttestationPool,
|
|
48
|
+
DeferredVoluntaryExitPool,
|
|
47
49
|
ExecutionPayloadBidPool,
|
|
48
50
|
OpPool,
|
|
49
51
|
PayloadAttestationPool,
|
|
@@ -127,6 +129,7 @@ export interface IBeaconChain {
|
|
|
127
129
|
readonly payloadAttestationPool: PayloadAttestationPool;
|
|
128
130
|
readonly proposerPreferencesPool: ProposerPreferencesPool;
|
|
129
131
|
readonly opPool: OpPool;
|
|
132
|
+
readonly deferredVoluntaryExitPool: DeferredVoluntaryExitPool;
|
|
130
133
|
|
|
131
134
|
// Gossip seen cache
|
|
132
135
|
readonly seenAttesters: SeenAttesters;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
4
|
import {IForkChoice} from "@lodestar/fork-choice";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {ChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {MAX_COMMITTEES_PER_SLOT, isForkPostElectra} from "@lodestar/params";
|