@lodestar/beacon-node 1.51.0-dev.e22f67e7bc → 1.51.0-dev.e2bf489dd3
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/api.js +1 -1
- package/lib/api/impl/api.js.map +1 -1
- package/lib/api/impl/beacon/blocks/index.d.ts +2 -1
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +29 -34
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/index.d.ts +2 -1
- package/lib/api/impl/beacon/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/index.js +2 -2
- package/lib/api/impl/beacon/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 +5 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/validator/index.d.ts +6 -0
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +42 -26
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/options.d.ts +2 -0
- package/lib/api/options.d.ts.map +1 -1
- package/lib/api/options.js +1 -0
- package/lib/api/options.js.map +1 -1
- package/lib/chain/GetBlobsTracker.d.ts +13 -2
- package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
- package/lib/chain/GetBlobsTracker.js +85 -27
- package/lib/chain/GetBlobsTracker.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +4 -0
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +61 -97
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +21 -50
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +10 -11
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +34 -19
- 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 +4 -4
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +12 -9
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +24 -19
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +4 -1
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +18 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.js +8 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +4 -0
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +7 -5
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +3 -3
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +11 -6
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
- package/lib/chain/bls/interface.d.ts +2 -0
- package/lib/chain/bls/interface.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +13 -11
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/types.d.ts +1 -1
- package/lib/chain/bls/multithread/types.d.ts.map +1 -1
- package/lib/chain/bls/multithread/worker.js +1 -1
- package/lib/chain/bls/multithread/worker.js.map +1 -1
- package/lib/chain/bls/singleThread.js +1 -1
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.js +1 -1
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +57 -7
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +1 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +1 -1
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +7 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts +11 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +11 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/forkChoiceExecutionEngine.d.ts +53 -0
- package/lib/chain/forkChoiceExecutionEngine.d.ts.map +1 -0
- package/lib/chain/forkChoiceExecutionEngine.js +121 -0
- package/lib/chain/forkChoiceExecutionEngine.js.map +1 -0
- package/lib/chain/interface.d.ts +5 -5
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +23 -10
- 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 +15 -4
- package/lib/chain/opPools/attestationPool.js.map +1 -1
- package/lib/chain/opPools/inclusionListStore.d.ts.map +1 -1
- package/lib/chain/opPools/inclusionListStore.js +2 -2
- package/lib/chain/opPools/inclusionListStore.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +17 -7
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.d.ts.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js +9 -3
- package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.d.ts.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +11 -3
- 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 +0 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +0 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +1 -2
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -2
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +0 -1
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +5 -3
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +0 -15
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +13 -166
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts +6 -0
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +53 -0
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/inclusionList.d.ts.map +1 -1
- package/lib/chain/validation/inclusionList.js +11 -2
- package/lib/chain/validation/inclusionList.js.map +1 -1
- package/lib/db/beacon.d.ts +7 -0
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +34 -0
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/dataColumnStore.d.ts +1 -1
- package/lib/db/dataColumnStore.d.ts.map +1 -1
- package/lib/db/dataColumnStore.js +1 -4
- package/lib/db/dataColumnStore.js.map +1 -1
- package/lib/db/flatFileStore/flatFileStore.js +5 -5
- package/lib/db/flatFileStore/flatFileStore.js.map +1 -1
- package/lib/db/flatFileStore/slotIndex.d.ts.map +1 -1
- package/lib/db/flatFileStore/slotIndex.js +2 -2
- package/lib/db/flatFileStore/slotIndex.js.map +1 -1
- package/lib/db/interface.d.ts +1 -0
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts +6 -0
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js +19 -0
- package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
- package/lib/execution/builder/apiClient.d.ts +14 -8
- package/lib/execution/builder/apiClient.d.ts.map +1 -1
- package/lib/execution/builder/apiClient.js +12 -10
- package/lib/execution/builder/apiClient.js.map +1 -1
- package/lib/execution/builder/http.d.ts +2 -0
- package/lib/execution/builder/http.d.ts.map +1 -1
- package/lib/execution/builder/http.js +2 -0
- package/lib/execution/builder/http.js.map +1 -1
- package/lib/execution/engine/blobVersionedHashes.d.ts +1 -1
- package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -1
- package/lib/execution/engine/blobVersionedHashes.js.map +1 -1
- package/lib/execution/engine/http.d.ts +2 -2
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +5 -5
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/index.d.ts +1 -1
- package/lib/execution/engine/index.d.ts.map +1 -1
- package/lib/execution/engine/index.js +1 -1
- package/lib/execution/engine/index.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +17 -3
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/interface.js.map +1 -1
- package/lib/execution/engine/jsonRpcTransport.d.ts +2 -2
- package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -1
- package/lib/execution/engine/jsonRpcTransport.js +1 -1
- package/lib/execution/engine/jsonRpcTransport.js.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +6 -4
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/payloadIdCache.d.ts +1 -2
- package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
- package/lib/execution/engine/payloadIdCache.js +3 -3
- package/lib/execution/engine/payloadIdCache.js.map +1 -1
- package/lib/execution/engine/restTransport.d.ts +2 -2
- package/lib/execution/engine/restTransport.d.ts.map +1 -1
- package/lib/execution/engine/restTransport.js.map +1 -1
- package/lib/execution/engine/sszTypes.d.ts +38 -38
- package/lib/execution/engine/transport.d.ts +1 -12
- package/lib/execution/engine/transport.d.ts.map +1 -1
- package/lib/execution/engine/types.d.ts +1 -1
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +9 -8
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/execution/engine/utils.d.ts.map +1 -1
- package/lib/execution/engine/utils.js +3 -2
- package/lib/execution/engine/utils.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +7 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +15 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/metrics/server/http.js +5 -5
- package/lib/metrics/server/http.js.map +1 -1
- package/lib/monitoring/service.js +1 -1
- package/lib/monitoring/service.js.map +1 -1
- package/lib/network/core/networkCore.d.ts +2 -0
- package/lib/network/core/networkCore.d.ts.map +1 -1
- package/lib/network/core/networkCore.js +3 -0
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorker.js +1 -0
- package/lib/network/core/networkCoreWorker.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.d.ts +2 -0
- package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js +3 -0
- package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
- package/lib/network/core/types.d.ts +2 -0
- package/lib/network/core/types.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts +1 -0
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +10 -0
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +6 -6
- package/lib/network/interface.d.ts +2 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +5 -1
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts +4 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +45 -15
- package/lib/network/network.js.map +1 -1
- package/lib/network/options.d.ts +2 -0
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js.map +1 -1
- package/lib/network/peers/peerManager.d.ts +2 -1
- package/lib/network/peers/peerManager.d.ts.map +1 -1
- package/lib/network/peers/peerManager.js +28 -1
- package/lib/network/peers/peerManager.js.map +1 -1
- package/lib/network/peers/utils/assertPeerRelevance.d.ts +9 -1
- package/lib/network/peers/utils/assertPeerRelevance.d.ts.map +1 -1
- package/lib/network/peers/utils/assertPeerRelevance.js +32 -21
- package/lib/network/peers/utils/assertPeerRelevance.js.map +1 -1
- package/lib/network/peers/utils/prioritizePeers.d.ts +4 -1
- package/lib/network/peers/utils/prioritizePeers.d.ts.map +1 -1
- package/lib/network/peers/utils/prioritizePeers.js +8 -16
- package/lib/network/peers/utils/prioritizePeers.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +60 -37
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +6 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +29 -3
- package/lib/network/processor/index.js.map +1 -1
- package/lib/node/nodejs.d.ts +3 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +47 -21
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/options.d.ts +3 -1
- package/lib/node/options.d.ts.map +1 -1
- package/lib/node/options.js +4 -2
- package/lib/node/options.js.map +1 -1
- package/lib/sync/interface.d.ts.map +1 -1
- package/lib/sync/interface.js.map +1 -1
- package/lib/sync/sync.d.ts +7 -0
- package/lib/sync/sync.d.ts.map +1 -1
- package/lib/sync/sync.js +61 -3
- package/lib/sync/sync.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +42 -18
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/execution.d.ts +4 -4
- package/lib/util/execution.d.ts.map +1 -1
- package/lib/util/execution.js.map +1 -1
- package/lib/util/file.d.ts.map +1 -1
- package/lib/util/file.js +8 -9
- package/lib/util/file.js.map +1 -1
- package/lib/util/queue/itemQueue.js +1 -1
- package/lib/util/queue/itemQueue.js.map +1 -1
- package/lib/util/sszBytes.d.ts +5 -0
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +35 -2
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +31 -32
- package/src/api/impl/api.ts +1 -1
- package/src/api/impl/beacon/blocks/index.ts +57 -62
- package/src/api/impl/beacon/index.ts +3 -1
- package/src/api/impl/beacon/pool/index.ts +5 -1
- package/src/api/impl/beacon/state/utils.ts +1 -1
- package/src/api/impl/validator/index.ts +47 -30
- package/src/api/options.ts +3 -0
- package/src/chain/GetBlobsTracker.ts +99 -40
- package/src/chain/archiveStore/archiveStore.ts +1 -0
- package/src/chain/archiveStore/utils/archiveBlocks.ts +76 -130
- package/src/chain/blocks/importBlock.ts +40 -71
- package/src/chain/blocks/importExecutionPayload.ts +57 -35
- package/src/chain/blocks/index.ts +11 -4
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +35 -24
- package/src/chain/blocks/types.ts +4 -1
- package/src/chain/blocks/verifyBlock.ts +31 -16
- package/src/chain/blocks/verifyBlocksDataAvailability.ts +10 -1
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +1 -1
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +4 -1
- package/src/chain/blocks/verifyBlocksSignatures.ts +7 -5
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +14 -6
- package/src/chain/bls/interface.ts +2 -0
- package/src/chain/bls/multithread/index.ts +14 -10
- package/src/chain/bls/multithread/types.ts +1 -1
- package/src/chain/bls/multithread/worker.ts +1 -5
- package/src/chain/bls/singleThread.ts +1 -1
- package/src/chain/bls/utils.ts +1 -1
- package/src/chain/chain.ts +67 -8
- package/src/chain/errors/blockError.ts +1 -1
- package/src/chain/errors/executionPayloadEnvelope.ts +8 -0
- package/src/chain/forkChoice/index.ts +11 -0
- package/src/chain/forkChoiceExecutionEngine.ts +197 -0
- package/src/chain/interface.ts +5 -5
- package/src/chain/opPools/aggregatedAttestationPool.ts +25 -9
- package/src/chain/opPools/attestationPool.ts +16 -4
- package/src/chain/opPools/inclusionListStore.ts +3 -3
- package/src/chain/opPools/payloadAttestationPool.ts +18 -7
- package/src/chain/opPools/syncCommitteeMessagePool.ts +10 -3
- package/src/chain/opPools/syncContributionAndProofPool.ts +13 -3
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/options.ts +0 -2
- package/src/chain/produceBlock/produceBlockBody.ts +4 -3
- package/src/chain/regen/interface.ts +1 -2
- package/src/chain/regen/queued.ts +6 -4
- package/src/chain/validation/executionPayloadBid.ts +14 -193
- package/src/chain/validation/executionPayloadEnvelope.ts +68 -1
- package/src/chain/validation/inclusionList.ts +11 -2
- package/src/db/beacon.ts +44 -0
- package/src/db/dataColumnStore.ts +2 -4
- package/src/db/flatFileStore/flatFileStore.ts +7 -7
- package/src/db/flatFileStore/slotIndex.ts +4 -3
- package/src/db/interface.ts +2 -0
- package/src/db/repositories/dataColumnSidecarArchive.ts +20 -0
- package/src/execution/builder/apiClient.ts +16 -13
- package/src/execution/builder/http.ts +4 -0
- package/src/execution/engine/blobVersionedHashes.ts +1 -1
- package/src/execution/engine/http.ts +12 -14
- package/src/execution/engine/index.ts +1 -1
- package/src/execution/engine/interface.ts +19 -3
- package/src/execution/engine/jsonRpcTransport.ts +10 -2
- package/src/execution/engine/mock.ts +6 -4
- package/src/execution/engine/payloadIdCache.ts +6 -7
- package/src/execution/engine/restTransport.ts +3 -1
- package/src/execution/engine/transport.ts +8 -14
- package/src/execution/engine/types.ts +11 -9
- package/src/execution/engine/utils.ts +4 -2
- package/src/index.ts +2 -0
- package/src/metrics/metrics/lodestar.ts +15 -0
- package/src/metrics/server/http.ts +5 -5
- package/src/monitoring/service.ts +1 -1
- package/src/network/core/networkCore.ts +5 -0
- package/src/network/core/networkCoreWorker.ts +1 -0
- package/src/network/core/networkCoreWorkerHandler.ts +4 -0
- package/src/network/core/types.ts +2 -0
- package/src/network/gossip/gossipsub.ts +11 -0
- package/src/network/interface.ts +2 -0
- package/src/network/libp2p/index.ts +5 -1
- package/src/network/network.ts +45 -19
- package/src/network/options.ts +2 -0
- package/src/network/peers/peerManager.ts +28 -3
- package/src/network/peers/utils/assertPeerRelevance.ts +39 -23
- package/src/network/peers/utils/prioritizePeers.ts +14 -22
- package/src/network/processor/gossipHandlers.ts +72 -40
- package/src/network/processor/index.ts +25 -3
- package/src/node/nodejs.ts +58 -22
- package/src/node/options.ts +9 -6
- package/src/sync/interface.ts +1 -0
- package/src/sync/sync.ts +65 -4
- package/src/sync/unknownBlock.ts +47 -28
- package/src/util/execution.ts +6 -6
- package/src/util/file.ts +8 -9
- package/src/util/queue/itemQueue.ts +1 -1
- package/src/util/sszBytes.ts +42 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {BitArray} from "@chainsafe/ssz";
|
|
2
2
|
import {routes} from "@lodestar/api";
|
|
3
3
|
import {
|
|
4
|
-
AncestorStatus,
|
|
5
|
-
ExecutionStatus,
|
|
6
4
|
ForkChoiceError,
|
|
7
5
|
ForkChoiceErrorCode,
|
|
6
|
+
InvalidBlockCode,
|
|
8
7
|
NotReorgedReason,
|
|
8
|
+
ProtoBlock,
|
|
9
9
|
getFinalizedExecutionBlockHash,
|
|
10
10
|
getSafeExecutionBlockHash,
|
|
11
11
|
} from "@lodestar/fork-choice";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
IBeaconStateView,
|
|
22
22
|
RootCache,
|
|
23
23
|
computeEpochAtSlot,
|
|
24
|
-
|
|
24
|
+
computeTimeAtSlotMs,
|
|
25
25
|
getBeaconCommittees,
|
|
26
26
|
isStatePostAltair,
|
|
27
27
|
isStatePostBellatrix,
|
|
@@ -43,7 +43,8 @@ import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
|
43
43
|
import {isOptimisticBlock} from "../../util/forkChoice.js";
|
|
44
44
|
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
45
45
|
import type {BeaconChain} from "../chain.js";
|
|
46
|
-
import {ChainEvent
|
|
46
|
+
import {ChainEvent} from "../emitter.js";
|
|
47
|
+
import {BlockError, BlockErrorCode} from "../errors/index.js";
|
|
47
48
|
import {ForkchoiceCaller} from "../forkChoice/index.js";
|
|
48
49
|
import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS} from "../reprocess.js";
|
|
49
50
|
import {toCheckpointHex} from "../stateCache/persistentCheckpointsCache.js";
|
|
@@ -94,8 +95,8 @@ export async function importBlock(
|
|
|
94
95
|
fullyVerifiedBlock: FullyVerifiedBlock,
|
|
95
96
|
opts: ImportBlockOpts
|
|
96
97
|
): Promise<void> {
|
|
97
|
-
const {blockInput, postState, parentBlockSlot, dataAvailabilityStatus, indexedAttestations} =
|
|
98
|
-
|
|
98
|
+
const {blockInput, postState, parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
|
|
99
|
+
fullyVerifiedBlock;
|
|
99
100
|
const block = blockInput.getBlock();
|
|
100
101
|
const source = blockInput.getBlockSource();
|
|
101
102
|
const {slot: blockSlot} = block.message;
|
|
@@ -105,8 +106,9 @@ export async function importBlock(
|
|
|
105
106
|
const currentEpoch = computeEpochAtSlot(currentSlot);
|
|
106
107
|
const blockEpoch = computeEpochAtSlot(blockSlot);
|
|
107
108
|
const prevFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
108
|
-
const
|
|
109
|
-
fullyVerifiedBlock.seenTimestampSec
|
|
109
|
+
const receiveDelayMs =
|
|
110
|
+
Math.round(fullyVerifiedBlock.seenTimestampSec * 1000) -
|
|
111
|
+
computeTimeAtSlotMs(this.config, blockSlot, postState.genesisTime * 1000);
|
|
110
112
|
const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
|
|
111
113
|
const fork = this.config.getForkSeq(blockSlot);
|
|
112
114
|
|
|
@@ -130,35 +132,30 @@ export async function importBlock(
|
|
|
130
132
|
|
|
131
133
|
// Should compute checkpoint balances before forkchoice.onBlock
|
|
132
134
|
this.checkpointBalancesCache.processState(blockRootHex, postState);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
135
|
+
const importDelayMs = this.clock.msFromSlot(blockSlot);
|
|
136
|
+
let blockSummary: ProtoBlock;
|
|
137
|
+
try {
|
|
138
|
+
blockSummary = this.forkChoice.onBlock(
|
|
139
|
+
block.message,
|
|
140
|
+
postState,
|
|
141
|
+
receiveDelayMs,
|
|
142
|
+
importDelayMs,
|
|
143
|
+
currentSlot,
|
|
144
|
+
executionStatus,
|
|
145
|
+
dataAvailabilityStatus
|
|
146
|
+
);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
// The parent can be invalidated by a forkchoiceUpdated verdict after verifyBlocksSanityChecks passed
|
|
149
|
+
if (
|
|
150
|
+
e instanceof ForkChoiceError &&
|
|
151
|
+
e.type.code === ForkChoiceErrorCode.INVALID_BLOCK &&
|
|
152
|
+
e.type.err.code === InvalidBlockCode.PARENT_EXECUTION_INVALID
|
|
153
|
+
) {
|
|
154
|
+
throw new BlockError(block, {code: BlockErrorCode.PARENT_EXECUTION_INVALID, parentRoot: e.type.err.root});
|
|
147
155
|
}
|
|
148
|
-
|
|
156
|
+
throw e;
|
|
149
157
|
}
|
|
150
158
|
|
|
151
|
-
const importDelaySec = this.clock.secFromSlot(blockSlot);
|
|
152
|
-
const blockSummary = this.forkChoice.onBlock(
|
|
153
|
-
block.message,
|
|
154
|
-
postState,
|
|
155
|
-
receiveDelaySec,
|
|
156
|
-
importDelaySec,
|
|
157
|
-
currentSlot,
|
|
158
|
-
executionStatus,
|
|
159
|
-
dataAvailabilityStatus
|
|
160
|
-
);
|
|
161
|
-
|
|
162
159
|
// This adds the state necessary to process the next block
|
|
163
160
|
// Some block event handlers require state being in state cache so need to do this before emitting EventType.block
|
|
164
161
|
this.regen.processState(blockRootHex, postState);
|
|
@@ -321,18 +318,10 @@ export async function importBlock(
|
|
|
321
318
|
}
|
|
322
319
|
|
|
323
320
|
if (newHead.blockRoot !== oldHead.blockRoot) {
|
|
324
|
-
|
|
325
|
-
this.regen.updateHeadState(newHead, postState);
|
|
321
|
+
this.onHeadChanged(oldHead, newHead, postState);
|
|
326
322
|
|
|
327
323
|
const delaySec = this.clock.secFromSlot(newHead.slot);
|
|
328
|
-
this.logger.verbose("New chain head", {
|
|
329
|
-
slot: newHead.slot,
|
|
330
|
-
root: newHead.blockRoot,
|
|
331
|
-
delaySec,
|
|
332
|
-
});
|
|
333
|
-
|
|
334
324
|
if (this.metrics) {
|
|
335
|
-
this.metrics.headSlot.set(newHead.slot);
|
|
336
325
|
// Only track "recent" blocks. Otherwise sync can distort this metrics heavily.
|
|
337
326
|
// We want to track recent blocks coming from gossip, unknown block sync, and API.
|
|
338
327
|
const headFork = this.config.getForkName(newHead.slot);
|
|
@@ -345,32 +334,6 @@ export async function importBlock(
|
|
|
345
334
|
}
|
|
346
335
|
}
|
|
347
336
|
|
|
348
|
-
this.onNewHead(newHead);
|
|
349
|
-
|
|
350
|
-
this.metrics?.forkChoice.changedHead.inc();
|
|
351
|
-
|
|
352
|
-
const ancestorResult = this.forkChoice.getCommonAncestorDepth(oldHead, newHead);
|
|
353
|
-
if (ancestorResult.code === AncestorStatus.CommonAncestor) {
|
|
354
|
-
// CommonAncestor = chain reorg, old head and new head not direct descendants
|
|
355
|
-
|
|
356
|
-
const forkChoiceReorgEventData: ReorgEventData = {
|
|
357
|
-
depth: ancestorResult.depth,
|
|
358
|
-
epoch: computeEpochAtSlot(newHead.slot),
|
|
359
|
-
slot: newHead.slot,
|
|
360
|
-
newHeadBlock: newHead.blockRoot,
|
|
361
|
-
oldHeadBlock: oldHead.blockRoot,
|
|
362
|
-
newHeadState: newHead.stateRoot,
|
|
363
|
-
oldHeadState: oldHead.stateRoot,
|
|
364
|
-
executionOptimistic: isOptimisticBlock(newHead),
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
this.emitter.emit(routes.events.EventType.chainReorg, forkChoiceReorgEventData);
|
|
368
|
-
this.logger.verbose("Chain reorg", forkChoiceReorgEventData);
|
|
369
|
-
|
|
370
|
-
this.metrics?.forkChoice.reorg.inc();
|
|
371
|
-
this.metrics?.forkChoice.reorgDistance.observe(ancestorResult.depth);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
337
|
// Lightclient server support (only after altair)
|
|
375
338
|
// - Persist state witness
|
|
376
339
|
// - Use block's syncAggregate
|
|
@@ -417,7 +380,7 @@ export async function importBlock(
|
|
|
417
380
|
// 4) Block meets the criteria of being re-orged out (this is also checked inside the function)
|
|
418
381
|
const result = this.forkChoice.shouldOverrideForkChoiceUpdate(
|
|
419
382
|
blockSummary,
|
|
420
|
-
this.clock.
|
|
383
|
+
this.clock.msFromSlot(currentSlot),
|
|
421
384
|
currentSlot
|
|
422
385
|
);
|
|
423
386
|
shouldOverrideFcu = result.shouldOverrideFcu;
|
|
@@ -469,7 +432,13 @@ export async function importBlock(
|
|
|
469
432
|
const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
|
|
470
433
|
if (headBlockHash !== ZERO_HASH_HEX) {
|
|
471
434
|
this.executionEngine
|
|
472
|
-
.notifyForkchoiceUpdate(
|
|
435
|
+
.notifyForkchoiceUpdate(
|
|
436
|
+
this.config.getForkName(fcuHead.slot),
|
|
437
|
+
fcuHead.blockRoot,
|
|
438
|
+
headBlockHash,
|
|
439
|
+
safeBlockHash,
|
|
440
|
+
finalizedBlockHash
|
|
441
|
+
)
|
|
473
442
|
.catch((e) => {
|
|
474
443
|
if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
|
|
475
444
|
this.logger.error("Error pushing notifyForkchoiceUpdate()", {headBlockHash, finalizedBlockHash}, e);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {SerializedList} from "@chainsafe/ssz";
|
|
1
2
|
import {routes} from "@lodestar/api";
|
|
2
3
|
import {
|
|
3
4
|
ExecutionStatus,
|
|
5
|
+
ForkChoiceError,
|
|
6
|
+
ForkChoiceErrorCode,
|
|
7
|
+
InvalidBlockCode,
|
|
4
8
|
PayloadExecutionStatus,
|
|
5
9
|
getFinalizedExecutionBlockHash,
|
|
6
10
|
getSafeExecutionBlockHash,
|
|
@@ -25,7 +29,6 @@ import {
|
|
|
25
29
|
verifyExecutionPayloadEnvelope,
|
|
26
30
|
verifyExecutionPayloadEnvelopeSignature,
|
|
27
31
|
} from "./verifyExecutionPayloadEnvelope.js";
|
|
28
|
-
import {verifyPayloadsDataAvailability} from "./verifyPayloadsDataAvailability.js";
|
|
29
32
|
|
|
30
33
|
const EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS = 64;
|
|
31
34
|
|
|
@@ -33,9 +36,11 @@ export enum PayloadErrorCode {
|
|
|
33
36
|
EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
|
|
34
37
|
EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
|
|
35
38
|
BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
|
|
39
|
+
BLOCK_EXECUTION_INVALID = "PAYLOAD_ERROR_BLOCK_EXECUTION_INVALID",
|
|
36
40
|
MISS_BLOCK_STATE = "PAYLOAD_ERROR_MISS_BLOCK_STATE",
|
|
37
41
|
ENVELOPE_VERIFICATION_ERROR = "PAYLOAD_ERROR_ENVELOPE_VERIFICATION_ERROR",
|
|
38
42
|
INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
|
|
43
|
+
DATA_UNAVAILABLE = "PAYLOAD_ERROR_DATA_UNAVAILABLE",
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
export type PayloadErrorType =
|
|
@@ -53,6 +58,10 @@ export type PayloadErrorType =
|
|
|
53
58
|
code: PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE;
|
|
54
59
|
blockRootHex: string;
|
|
55
60
|
}
|
|
61
|
+
| {
|
|
62
|
+
code: PayloadErrorCode.BLOCK_EXECUTION_INVALID;
|
|
63
|
+
blockRootHex: string;
|
|
64
|
+
}
|
|
56
65
|
| {
|
|
57
66
|
code: PayloadErrorCode.MISS_BLOCK_STATE;
|
|
58
67
|
blockRootHex: string;
|
|
@@ -63,6 +72,9 @@ export type PayloadErrorType =
|
|
|
63
72
|
}
|
|
64
73
|
| {
|
|
65
74
|
code: PayloadErrorCode.INVALID_SIGNATURE;
|
|
75
|
+
}
|
|
76
|
+
| {
|
|
77
|
+
code: PayloadErrorCode.DATA_UNAVAILABLE;
|
|
66
78
|
};
|
|
67
79
|
|
|
68
80
|
export class PayloadError extends Error {
|
|
@@ -94,7 +106,8 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
|
|
|
94
106
|
* are applied on the next block via processParentExecutionPayload.
|
|
95
107
|
*
|
|
96
108
|
* The DA wait must have run upstream (range sync awaits DA in `verifyBlocksInEpoch` for the
|
|
97
|
-
* whole segment; gossip / API path
|
|
109
|
+
* whole segment; the gossip / API / unknown-payload sync path waits in `PayloadEnvelopeProcessor`
|
|
110
|
+
* before the import is queued).
|
|
98
111
|
*
|
|
99
112
|
* Steps:
|
|
100
113
|
* 1. Emit `execution_payload_available` event for payload attestation
|
|
@@ -139,6 +152,13 @@ export async function importExecutionPayload(
|
|
|
139
152
|
blockRootHex,
|
|
140
153
|
});
|
|
141
154
|
}
|
|
155
|
+
// The payload chain this block builds on was invalidated, a VALID verdict here would contradict it
|
|
156
|
+
if (protoBlock.executionStatus === ExecutionStatus.Invalid) {
|
|
157
|
+
throw new PayloadError(payloadInput, {
|
|
158
|
+
code: PayloadErrorCode.BLOCK_EXECUTION_INVALID,
|
|
159
|
+
blockRootHex,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
142
162
|
|
|
143
163
|
// 3. Regenerate state for envelope verification
|
|
144
164
|
const blockState = await this.regen
|
|
@@ -206,7 +226,7 @@ export async function importExecutionPayload(
|
|
|
206
226
|
}
|
|
207
227
|
inclusionListTransactions =
|
|
208
228
|
dependentRoot === null
|
|
209
|
-
?
|
|
229
|
+
? SerializedList.empty()
|
|
210
230
|
: this.inclusionListStore.getInclusionListTransactions(inclusionListSlot, dependentRoot, true);
|
|
211
231
|
}
|
|
212
232
|
|
|
@@ -317,25 +337,45 @@ export async function importExecutionPayload(
|
|
|
317
337
|
|
|
318
338
|
// 6. Update fork choice, transitions the block's PENDING variant to FULL
|
|
319
339
|
const execStatus = toForkChoiceExecutionStatus(execResult.status);
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
340
|
+
try {
|
|
341
|
+
this.forkChoice.onExecutionPayload(
|
|
342
|
+
blockRootHex,
|
|
343
|
+
blockHashHex,
|
|
344
|
+
envelope.payload.blockNumber,
|
|
345
|
+
envelope.payload.gasLimit,
|
|
346
|
+
execStatus,
|
|
347
|
+
dataAvailabilityStatus
|
|
348
|
+
);
|
|
349
|
+
} catch (e) {
|
|
350
|
+
// The payload chain can be invalidated by a forkchoiceUpdated verdict while the engine was awaited
|
|
351
|
+
if (
|
|
352
|
+
e instanceof ForkChoiceError &&
|
|
353
|
+
e.type.code === ForkChoiceErrorCode.INVALID_BLOCK &&
|
|
354
|
+
e.type.err.code === InvalidBlockCode.PARENT_EXECUTION_INVALID
|
|
355
|
+
) {
|
|
356
|
+
throw new PayloadError(payloadInput, {code: PayloadErrorCode.BLOCK_EXECUTION_INVALID, blockRootHex});
|
|
357
|
+
}
|
|
358
|
+
throw e;
|
|
359
|
+
}
|
|
328
360
|
|
|
329
361
|
// 7. Queue notifyForkchoiceUpdate to engine api
|
|
330
362
|
const head = this.forkChoice.getHead();
|
|
331
|
-
if (
|
|
363
|
+
if (
|
|
364
|
+
!this.opts.disableImportExecutionFcU &&
|
|
365
|
+
blockRootHex === head.blockRoot &&
|
|
366
|
+
// Skip a payload that does not satisfy the inclusion list constraints, fork choice keeps the EMPTY
|
|
367
|
+
// variant as head and the next prepare fcU keeps the engine on the parent payload
|
|
368
|
+
this.forkChoice.isPayloadInclusionListSatisfied(blockRootHex)
|
|
369
|
+
) {
|
|
332
370
|
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice, this.logger);
|
|
333
371
|
const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
|
|
334
|
-
this.executionEngine
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
372
|
+
this.executionEngine
|
|
373
|
+
.notifyForkchoiceUpdate(fork, blockRootHex, blockHashHex, safeBlockHash, finalizedBlockHash)
|
|
374
|
+
.catch((e) => {
|
|
375
|
+
if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
|
|
376
|
+
this.logger.error("Error pushing notifyForkchoiceUpdate()", {blockHashHex, finalizedBlockHash}, e);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
339
379
|
}
|
|
340
380
|
|
|
341
381
|
// 8. Record metrics for payload envelope and column sources
|
|
@@ -367,21 +407,3 @@ export async function importExecutionPayload(
|
|
|
367
407
|
delaySec,
|
|
368
408
|
});
|
|
369
409
|
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Process an execution payload envelope end-to-end: wait for DA, then import.
|
|
373
|
-
*
|
|
374
|
-
* Used by the PayloadEnvelopeProcessor queue (gossip / API / unknown-payload sync) — i.e.
|
|
375
|
-
* callers that have NOT already awaited DA themselves. Range sync's inline dispatch in
|
|
376
|
-
* processBlocks skips this wrapper and calls `importExecutionPayload` directly, since
|
|
377
|
-
* `verifyBlocksInEpoch` already awaited DA for the segment.
|
|
378
|
-
*/
|
|
379
|
-
export async function processExecutionPayload(
|
|
380
|
-
this: BeaconChain,
|
|
381
|
-
payloadInput: PayloadEnvelopeInput,
|
|
382
|
-
signal: AbortSignal,
|
|
383
|
-
opts: ImportPayloadOpts = {}
|
|
384
|
-
): Promise<void> {
|
|
385
|
-
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability([payloadInput], signal);
|
|
386
|
-
await importExecutionPayload.call(this, payloadInput, dataAvailabilityStatuses[0], opts);
|
|
387
|
-
}
|
|
@@ -7,7 +7,7 @@ import {nextEventLoop} from "../../util/eventLoop.js";
|
|
|
7
7
|
import {JobItemQueue, isQueueErrorAborted} from "../../util/queue/index.js";
|
|
8
8
|
import type {BeaconChain} from "../chain.js";
|
|
9
9
|
import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.js";
|
|
10
|
-
import {ForkchoiceCaller} from "../forkChoice/index.js";
|
|
10
|
+
import {ExecutionInvalidSource, ForkchoiceCaller} from "../forkChoice/index.js";
|
|
11
11
|
import {BlockProcessOpts} from "../options.js";
|
|
12
12
|
import {IBlockInput} from "./blockInput/types.js";
|
|
13
13
|
import {importBlock, importsBlockAttestations} from "./importBlock.js";
|
|
@@ -123,7 +123,10 @@ export async function processBlocks(
|
|
|
123
123
|
// and we need to further propagate
|
|
124
124
|
if (segmentExecStatus.execAborted !== null) {
|
|
125
125
|
if (segmentExecStatus.invalidSegmentLVH !== undefined) {
|
|
126
|
-
this.
|
|
126
|
+
this.executionEngine.invalidateExecutionPayloads(
|
|
127
|
+
segmentExecStatus.invalidSegmentLVH,
|
|
128
|
+
ExecutionInvalidSource.blockSegment
|
|
129
|
+
);
|
|
127
130
|
}
|
|
128
131
|
throw segmentExecStatus.execAborted.execError;
|
|
129
132
|
}
|
|
@@ -147,7 +150,7 @@ export async function processBlocks(
|
|
|
147
150
|
proposerBalanceDelta: proposerBalanceDeltas[i],
|
|
148
151
|
indexedAttestations: indexedAttestationsByBlock[i],
|
|
149
152
|
// TODO: Make this param mandatory and capture in gossip
|
|
150
|
-
seenTimestampSec: opts.seenTimestampSec ??
|
|
153
|
+
seenTimestampSec: opts.seenTimestampSec ?? Date.now() / 1000,
|
|
151
154
|
});
|
|
152
155
|
}
|
|
153
156
|
|
|
@@ -292,7 +295,11 @@ async function importPayloadEnvelopesOfKnownBlocks(
|
|
|
292
295
|
return result;
|
|
293
296
|
}
|
|
294
297
|
|
|
295
|
-
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability(
|
|
298
|
+
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability(
|
|
299
|
+
this.config,
|
|
300
|
+
payloadInputs,
|
|
301
|
+
new AbortController().signal
|
|
302
|
+
);
|
|
296
303
|
for (let i = 0; i < payloadInputs.length; i++) {
|
|
297
304
|
this.logger.debug("Importing payload envelope of known block", {
|
|
298
305
|
slot: payloadInputs[i].slot,
|
|
@@ -1,32 +1,37 @@
|
|
|
1
|
+
import {DataAvailabilityStatus} from "@lodestar/state-transition";
|
|
1
2
|
import {Metrics} from "../../metrics/metrics.js";
|
|
2
3
|
import {JobItemQueue} from "../../util/queue/index.js";
|
|
3
4
|
import type {BeaconChain} from "../chain.js";
|
|
4
5
|
import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
|
|
5
|
-
import {
|
|
6
|
+
import {importExecutionPayload} from "./importExecutionPayload.js";
|
|
6
7
|
import {ImportPayloadOpts} from "./types.js";
|
|
8
|
+
import {verifyPayloadsDataAvailability} from "./verifyPayloadsDataAvailability.js";
|
|
7
9
|
|
|
8
10
|
// TODO GLOAS: Set to be equal to DEFAULT_MAX_PENDING_UNFINALIZED_PAYLOAD_ENVELOPE_WRITES for now
|
|
9
11
|
const QUEUE_MAX_LENGTH = 16;
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
|
-
* PayloadEnvelopeProcessor
|
|
14
|
+
* PayloadEnvelopeProcessor imports payload envelopes in a queued fashion, one after the other.
|
|
13
15
|
*
|
|
14
|
-
* Jobs are
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* and spin re-processing the same root until OOM while the import is blocked (e.g. EL syncing).
|
|
16
|
+
* Jobs are triggered only on envelope arrival (gossip or API). The envelope may reach us before the
|
|
17
|
+
* sampled data columns, the data availability wait runs before the job is queued. Duplicate
|
|
18
|
+
* triggers for the same payloadInput are deduped by sharing the in-flight promise: every caller
|
|
19
|
+
* observes the real import outcome. Resolving duplicates early instead would let
|
|
20
|
+
* BlockInputSync mark a still-pending payload as processed, re-queue it, and spin re-processing
|
|
21
|
+
* the same root until OOM while the import is blocked (e.g. EL syncing).
|
|
21
22
|
*/
|
|
22
23
|
export class PayloadEnvelopeProcessor {
|
|
23
|
-
readonly jobQueue: JobItemQueue<[PayloadEnvelopeInput, ImportPayloadOpts], void>;
|
|
24
|
+
readonly jobQueue: JobItemQueue<[PayloadEnvelopeInput, DataAvailabilityStatus, ImportPayloadOpts], void>;
|
|
24
25
|
private readonly imports = new WeakMap<PayloadEnvelopeInput, Promise<void>>();
|
|
25
26
|
|
|
26
|
-
constructor(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
constructor(
|
|
28
|
+
private readonly chain: BeaconChain,
|
|
29
|
+
metrics: Metrics | null,
|
|
30
|
+
private readonly signal: AbortSignal
|
|
31
|
+
) {
|
|
32
|
+
this.jobQueue = new JobItemQueue<[PayloadEnvelopeInput, DataAvailabilityStatus, ImportPayloadOpts], void>(
|
|
33
|
+
(payloadInput, dataAvailabilityStatus, opts) => {
|
|
34
|
+
return importExecutionPayload.call(chain, payloadInput, dataAvailabilityStatus, opts);
|
|
30
35
|
},
|
|
31
36
|
{maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
|
|
32
37
|
metrics?.payloadEnvelopeProcessorQueue ?? undefined
|
|
@@ -35,19 +40,11 @@ export class PayloadEnvelopeProcessor {
|
|
|
35
40
|
|
|
36
41
|
async processPayloadEnvelopeJob(payloadInput: PayloadEnvelopeInput, opts: ImportPayloadOpts = {}): Promise<void> {
|
|
37
42
|
const existing = this.imports.get(payloadInput);
|
|
38
|
-
if (existing) {
|
|
43
|
+
if (existing !== undefined) {
|
|
39
44
|
return existing;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Re-check after await, as another call may have queued this payload.
|
|
45
|
-
const queued = this.imports.get(payloadInput);
|
|
46
|
-
if (queued) {
|
|
47
|
-
return queued;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const importPromise = this.jobQueue.push(payloadInput, opts);
|
|
47
|
+
const importPromise = this.waitForDataAndImport(payloadInput, opts);
|
|
51
48
|
this.imports.set(payloadInput, importPromise);
|
|
52
49
|
|
|
53
50
|
try {
|
|
@@ -59,4 +56,18 @@ export class PayloadEnvelopeProcessor {
|
|
|
59
56
|
throw e;
|
|
60
57
|
}
|
|
61
58
|
}
|
|
59
|
+
|
|
60
|
+
private async waitForDataAndImport(payloadInput: PayloadEnvelopeInput, opts: ImportPayloadOpts): Promise<void> {
|
|
61
|
+
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability(
|
|
62
|
+
this.chain.config,
|
|
63
|
+
[payloadInput],
|
|
64
|
+
this.signal
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
while (this.jobQueue.jobLen >= QUEUE_MAX_LENGTH) {
|
|
68
|
+
await this.jobQueue.waitForSpace();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return this.jobQueue.push(payloadInput, dataAvailabilityStatuses[0], opts);
|
|
72
|
+
}
|
|
62
73
|
}
|
|
@@ -109,7 +109,10 @@ export type FullyVerifiedBlock = {
|
|
|
109
109
|
parentBlockSlot: Slot;
|
|
110
110
|
proposerBalanceDelta: number;
|
|
111
111
|
dataAvailabilityStatus: DataAvailabilityStatus;
|
|
112
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* Pre-computed indexed attestations from signature verification to avoid duplicate work.
|
|
114
|
+
* Their `attestingIndices` are in committee order, not sorted, so they are not spec-valid `IndexedAttestation`s.
|
|
115
|
+
*/
|
|
113
116
|
indexedAttestations: IndexedAttestation[];
|
|
114
117
|
/** Seen timestamp seconds */
|
|
115
118
|
seenTimestampSec: number;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
DataAvailabilityStatus,
|
|
5
5
|
IBeaconStateView,
|
|
6
6
|
computeEpochAtSlot,
|
|
7
|
-
|
|
7
|
+
getAttestingIndices,
|
|
8
8
|
signedBlockToSignedHeader,
|
|
9
9
|
} from "@lodestar/state-transition";
|
|
10
10
|
import {IndexedAttestation, Slot, deneb} from "@lodestar/types";
|
|
@@ -119,7 +119,13 @@ export async function verifyBlocksInEpoch(
|
|
|
119
119
|
const shuffling =
|
|
120
120
|
this.shufflingCache.getSync(attEpoch, preState0.getShufflingDecisionRoot(attEpoch)) ??
|
|
121
121
|
preState0.getShufflingAtEpoch(attEpoch);
|
|
122
|
-
|
|
122
|
+
// Unlike getIndexedAttestation, keep attestingIndices in committee order: sorting them dominates building
|
|
123
|
+
// these on mainnet blocks. See FullyVerifiedBlock.indexedAttestations.
|
|
124
|
+
return {
|
|
125
|
+
attestingIndices: getAttestingIndices(shuffling, fork, attestation),
|
|
126
|
+
data: attestation.data,
|
|
127
|
+
signature: attestation.signature,
|
|
128
|
+
};
|
|
123
129
|
});
|
|
124
130
|
}
|
|
125
131
|
|
|
@@ -143,6 +149,7 @@ export async function verifyBlocksInEpoch(
|
|
|
143
149
|
? Array.from(payloadEnvelopes.values()).filter((payloadInput) => payloadInput.hasPayloadEnvelope())
|
|
144
150
|
: [];
|
|
145
151
|
const {dataAvailabilityStatuses, availableTime} = await verifyPayloadsDataAvailability(
|
|
152
|
+
this.config,
|
|
146
153
|
payloadInputsForDa,
|
|
147
154
|
abortController.signal
|
|
148
155
|
);
|
|
@@ -174,16 +181,29 @@ export async function verifyBlocksInEpoch(
|
|
|
174
181
|
const [
|
|
175
182
|
segmentExecStatus,
|
|
176
183
|
{blockDAStatuses, payloadDAStatuses, availableTime},
|
|
177
|
-
{postStates, proposerBalanceDeltas, verifyStateTime},
|
|
178
184
|
{verifySignaturesTime},
|
|
185
|
+
{postStates, proposerBalanceDeltas, verifyStateTime},
|
|
179
186
|
] = await Promise.all([
|
|
180
187
|
verifyExecutionPayloadsPromise,
|
|
181
188
|
|
|
182
189
|
// data availability (fork-specific; see daAvailabilityPromise above)
|
|
183
190
|
daAvailabilityPromise,
|
|
184
191
|
|
|
192
|
+
// All signatures at once. Must be called before verifyBlocksStateTransitionOnly()
|
|
193
|
+
// so we hand the BLS job to the worker pool before the main thread
|
|
194
|
+
// is busy with the state transition.
|
|
195
|
+
verifyBlocksSignatures(
|
|
196
|
+
this.config,
|
|
197
|
+
this.bls,
|
|
198
|
+
this.logger,
|
|
199
|
+
this.metrics,
|
|
200
|
+
preState0,
|
|
201
|
+
blocks,
|
|
202
|
+
indexedAttestationsByBlock,
|
|
203
|
+
opts
|
|
204
|
+
),
|
|
205
|
+
|
|
185
206
|
// Run state transition only
|
|
186
|
-
// TODO: Ensure it yields to allow flushing to workers and engine API
|
|
187
207
|
verifyBlocksStateTransitionOnly(
|
|
188
208
|
preState0,
|
|
189
209
|
blockInputs,
|
|
@@ -197,22 +217,17 @@ export async function verifyBlocksInEpoch(
|
|
|
197
217
|
opts
|
|
198
218
|
),
|
|
199
219
|
|
|
200
|
-
// All signatures at once
|
|
201
|
-
verifyBlocksSignatures(
|
|
202
|
-
this.config,
|
|
203
|
-
this.bls,
|
|
204
|
-
this.logger,
|
|
205
|
-
this.metrics,
|
|
206
|
-
preState0,
|
|
207
|
-
blocks,
|
|
208
|
-
indexedAttestationsByBlock,
|
|
209
|
-
opts
|
|
210
|
-
),
|
|
211
|
-
|
|
212
220
|
// TODO GLOAS: can verify payload signatures in batch too
|
|
213
221
|
// maybe chain with the above verifyBlocksSignatures()
|
|
214
222
|
]);
|
|
215
223
|
|
|
224
|
+
if (blockInputs.length === 1 && opts.seenTimestampSec !== undefined) {
|
|
225
|
+
const consensusVerifiedTime = Math.max(verifyStateTime, verifySignaturesTime);
|
|
226
|
+
this.metrics?.gossipBlock.receivedToConsensusVerifiedTime.observe(
|
|
227
|
+
consensusVerifiedTime / 1000 - opts.seenTimestampSec
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
216
231
|
for (const blockInput of blockInputs) {
|
|
217
232
|
const block = blockInput.getBlock();
|
|
218
233
|
const {slot, proposerIndex} = block.message;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {DataAvailabilityStatus} from "@lodestar/state-transition";
|
|
2
|
+
import {TimeoutError} from "@lodestar/utils";
|
|
3
|
+
import {BlockError, BlockErrorCode} from "../errors/index.js";
|
|
2
4
|
import {DAData, DAType, IBlockInput} from "./blockInput/index.js";
|
|
3
5
|
|
|
4
6
|
// we can now wait for full 12 seconds because unavailable block sync will try pulling
|
|
@@ -22,7 +24,14 @@ export async function verifyBlocksDataAvailability(
|
|
|
22
24
|
for (const blockInput of blocks) {
|
|
23
25
|
// block verification is triggered on a verified gossip block so we only need to wait for all data
|
|
24
26
|
if (!blockInput.hasAllData()) {
|
|
25
|
-
promises.push(
|
|
27
|
+
promises.push(
|
|
28
|
+
blockInput.waitForAllData(BLOB_AVAILABILITY_TIMEOUT, signal).catch((e) => {
|
|
29
|
+
if (e instanceof TimeoutError) {
|
|
30
|
+
throw new BlockError(blockInput.getBlock(), {code: BlockErrorCode.DATA_UNAVAILABLE});
|
|
31
|
+
}
|
|
32
|
+
throw e;
|
|
33
|
+
})
|
|
34
|
+
);
|
|
26
35
|
}
|
|
27
36
|
}
|
|
28
37
|
await Promise.all(promises);
|
|
@@ -21,7 +21,7 @@ import {IBlockInput} from "./blockInput/types.js";
|
|
|
21
21
|
import {ImportBlockOpts} from "./types.js";
|
|
22
22
|
|
|
23
23
|
export type VerifyBlockExecutionPayloadModules = {
|
|
24
|
-
executionEngine: IExecutionEngine
|
|
24
|
+
executionEngine: Pick<IExecutionEngine, "notifyNewPayload">;
|
|
25
25
|
clock: IClock;
|
|
26
26
|
logger: Logger;
|
|
27
27
|
metrics: Metrics | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
2
|
+
import {ExecutionStatus, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
4
4
|
import {RootHex, Slot, isGloasBeaconBlock} from "@lodestar/types";
|
|
5
5
|
import {toRootHex} from "@lodestar/utils";
|
|
@@ -118,6 +118,9 @@ export function verifyBlocksSanityChecks(
|
|
|
118
118
|
parentBlock = parentBlockWithPayload;
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
+
if (parentBlock.executionStatus === ExecutionStatus.Invalid) {
|
|
122
|
+
throw new BlockError(block, {code: BlockErrorCode.PARENT_EXECUTION_INVALID, parentRoot});
|
|
123
|
+
}
|
|
121
124
|
// Parent is known to the fork-choice
|
|
122
125
|
parentBlockSlot = parentBlock.slot;
|
|
123
126
|
}
|