@lodestar/beacon-node 1.51.0-dev.ab56d90f0c → 1.51.0-dev.ab8f3f6381
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 +22 -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 +39 -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 +32 -18
- 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 +25 -3
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +123 -10
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +6 -0
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +5 -0
- package/lib/chain/emitter.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 +9 -6
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts +17 -4
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +199 -46
- 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/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.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/singleAttestationPool.d.ts +77 -0
- package/lib/chain/opPools/singleAttestationPool.d.ts.map +1 -0
- package/lib/chain/opPools/singleAttestationPool.js +209 -0
- package/lib/chain/opPools/singleAttestationPool.js.map +1 -0
- 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 +5 -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 +3 -2
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/proposerTracker.d.ts +31 -0
- package/lib/chain/proposerTracker.d.ts.map +1 -0
- package/lib/chain/proposerTracker.js +75 -0
- package/lib/chain/proposerTracker.js.map +1 -0
- 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/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/http.d.ts +2 -2
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +5 -4
- 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/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/transport.d.ts +1 -12
- package/lib/execution/engine/transport.d.ts.map +1 -1
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +2 -2
- 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 +33 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +84 -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 +4 -1
- package/lib/network/core/networkCore.d.ts.map +1 -1
- package/lib/network/core/networkCore.js +7 -0
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorker.js +2 -0
- package/lib/network/core/networkCoreWorker.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.d.ts +4 -1
- package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js +6 -0
- package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
- package/lib/network/core/types.d.ts +6 -1
- 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/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 +6 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +53 -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 +2 -0
- 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/peers/utils/subnetMap.d.ts +5 -2
- package/lib/network/peers/utils/subnetMap.d.ts.map +1 -1
- package/lib/network/peers/utils/subnetMap.js +6 -3
- package/lib/network/peers/utils/subnetMap.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +77 -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/network/subnets/attnetsService.d.ts +35 -5
- package/lib/network/subnets/attnetsService.d.ts.map +1 -1
- package/lib/network/subnets/attnetsService.js +84 -6
- package/lib/network/subnets/attnetsService.js.map +1 -1
- package/lib/network/subnets/interface.d.ts +7 -0
- package/lib/network/subnets/interface.d.ts.map +1 -1
- package/lib/network/subnets/interface.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 +16 -17
- 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 +31 -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 +60 -71
- package/src/chain/blocks/importExecutionPayload.ts +55 -34
- 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 +139 -8
- package/src/chain/emitter.ts +7 -0
- 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 +9 -5
- package/src/chain/opPools/aggregatedAttestationPool.ts +246 -43
- package/src/chain/opPools/attestationPool.ts +16 -4
- package/src/chain/opPools/index.ts +1 -0
- package/src/chain/opPools/payloadAttestationPool.ts +18 -7
- package/src/chain/opPools/singleAttestationPool.ts +287 -0
- 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 +5 -2
- package/src/chain/produceBlock/produceBlockBody.ts +7 -3
- package/src/chain/proposerTracker.ts +94 -0
- 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/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/http.ts +12 -13
- 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/restTransport.ts +3 -1
- package/src/execution/engine/transport.ts +8 -14
- package/src/execution/engine/types.ts +3 -1
- package/src/execution/engine/utils.ts +4 -2
- package/src/index.ts +2 -0
- package/src/metrics/metrics/lodestar.ts +85 -0
- package/src/metrics/server/http.ts +5 -5
- package/src/monitoring/service.ts +1 -1
- package/src/network/core/networkCore.ts +11 -1
- package/src/network/core/networkCoreWorker.ts +2 -0
- package/src/network/core/networkCoreWorkerHandler.ts +8 -1
- package/src/network/core/types.ts +6 -1
- 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 +55 -19
- package/src/network/options.ts +4 -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/peers/utils/subnetMap.ts +6 -3
- package/src/network/processor/gossipHandlers.ts +98 -40
- package/src/network/processor/index.ts +25 -3
- package/src/network/subnets/attnetsService.ts +94 -6
- package/src/network/subnets/interface.ts +7 -0
- 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,8 +43,10 @@ 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";
|
|
49
|
+
import {IncludedAttesters} from "../opPools/singleAttestationPool.js";
|
|
48
50
|
import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS} from "../reprocess.js";
|
|
49
51
|
import {toCheckpointHex} from "../stateCache/persistentCheckpointsCache.js";
|
|
50
52
|
import {isBlockInputBlobs, isBlockInputColumns} from "./blockInput/blockInput.js";
|
|
@@ -94,8 +96,8 @@ export async function importBlock(
|
|
|
94
96
|
fullyVerifiedBlock: FullyVerifiedBlock,
|
|
95
97
|
opts: ImportBlockOpts
|
|
96
98
|
): Promise<void> {
|
|
97
|
-
const {blockInput, postState, parentBlockSlot, dataAvailabilityStatus, indexedAttestations} =
|
|
98
|
-
|
|
99
|
+
const {blockInput, postState, parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
|
|
100
|
+
fullyVerifiedBlock;
|
|
99
101
|
const block = blockInput.getBlock();
|
|
100
102
|
const source = blockInput.getBlockSource();
|
|
101
103
|
const {slot: blockSlot} = block.message;
|
|
@@ -105,8 +107,9 @@ export async function importBlock(
|
|
|
105
107
|
const currentEpoch = computeEpochAtSlot(currentSlot);
|
|
106
108
|
const blockEpoch = computeEpochAtSlot(blockSlot);
|
|
107
109
|
const prevFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
108
|
-
const
|
|
109
|
-
fullyVerifiedBlock.seenTimestampSec
|
|
110
|
+
const receiveDelayMs =
|
|
111
|
+
Math.round(fullyVerifiedBlock.seenTimestampSec * 1000) -
|
|
112
|
+
computeTimeAtSlotMs(this.config, blockSlot, postState.genesisTime * 1000);
|
|
110
113
|
const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
|
|
111
114
|
const fork = this.config.getForkSeq(blockSlot);
|
|
112
115
|
|
|
@@ -130,35 +133,30 @@ export async function importBlock(
|
|
|
130
133
|
|
|
131
134
|
// Should compute checkpoint balances before forkchoice.onBlock
|
|
132
135
|
this.checkpointBalancesCache.processState(blockRootHex, postState);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
136
|
+
const importDelayMs = this.clock.msFromSlot(blockSlot);
|
|
137
|
+
let blockSummary: ProtoBlock;
|
|
138
|
+
try {
|
|
139
|
+
blockSummary = this.forkChoice.onBlock(
|
|
140
|
+
block.message,
|
|
141
|
+
postState,
|
|
142
|
+
receiveDelayMs,
|
|
143
|
+
importDelayMs,
|
|
144
|
+
currentSlot,
|
|
145
|
+
executionStatus,
|
|
146
|
+
dataAvailabilityStatus
|
|
147
|
+
);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
// The parent can be invalidated by a forkchoiceUpdated verdict after verifyBlocksSanityChecks passed
|
|
150
|
+
if (
|
|
151
|
+
e instanceof ForkChoiceError &&
|
|
152
|
+
e.type.code === ForkChoiceErrorCode.INVALID_BLOCK &&
|
|
153
|
+
e.type.err.code === InvalidBlockCode.PARENT_EXECUTION_INVALID
|
|
154
|
+
) {
|
|
155
|
+
throw new BlockError(block, {code: BlockErrorCode.PARENT_EXECUTION_INVALID, parentRoot: e.type.err.root});
|
|
147
156
|
}
|
|
148
|
-
|
|
157
|
+
throw e;
|
|
149
158
|
}
|
|
150
159
|
|
|
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
160
|
// This adds the state necessary to process the next block
|
|
163
161
|
// Some block event handlers require state being in state cache so need to do this before emitting EventType.block
|
|
164
162
|
this.regen.processState(blockRootHex, postState);
|
|
@@ -175,6 +173,9 @@ export async function importBlock(
|
|
|
175
173
|
// Only process attestations of blocks with relevant attestations for the fork-choice:
|
|
176
174
|
// If current epoch is N, and block is epoch X, block may include attestations for epoch X or X - 1.
|
|
177
175
|
// The latest block that is useful is at epoch N - 1 which may include attestations for epoch N - 1 or N - 2.
|
|
176
|
+
// the pool is empty outside the slots before a local block proposal, nothing to prune then
|
|
177
|
+
const pruneSingleAttestations = fork >= ForkSeq.electra && !this.singleAttestationPool.isEmpty();
|
|
178
|
+
const includedAttesters: IncludedAttesters[] = [];
|
|
178
179
|
if (importsBlockAttestations(opts, blockEpoch, currentEpoch)) {
|
|
179
180
|
const attestations = block.message.body.attestations;
|
|
180
181
|
const rootCache = new RootCache(postState);
|
|
@@ -189,6 +190,14 @@ export async function importBlock(
|
|
|
189
190
|
const {target, beaconBlockRoot} = attestation.data;
|
|
190
191
|
|
|
191
192
|
const attDataRoot = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(indexedAttestation.data));
|
|
193
|
+
// the block includes these attesters even if fork choice below rejects the vote
|
|
194
|
+
if (pruneSingleAttestations) {
|
|
195
|
+
includedAttesters.push({
|
|
196
|
+
slot: attestation.data.slot,
|
|
197
|
+
attDataRootHex: attDataRoot,
|
|
198
|
+
attestingIndices: indexedAttestation.attestingIndices,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
192
201
|
addAttestation.call(
|
|
193
202
|
this,
|
|
194
203
|
postState,
|
|
@@ -320,19 +329,19 @@ export async function importBlock(
|
|
|
320
329
|
});
|
|
321
330
|
}
|
|
322
331
|
|
|
332
|
+
// only a block that becomes head prunes, not a side-branch import
|
|
333
|
+
if (pruneSingleAttestations && newHead.blockRoot === blockRootHex) {
|
|
334
|
+
callInNextEventLoop(() => {
|
|
335
|
+
const deleted = this.singleAttestationPool.onHead(blockRootHex, newHead.parentRoot, includedAttesters);
|
|
336
|
+
this.metrics?.opPool.singleAttestationPool.deletedByBlock.inc(deleted);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
323
340
|
if (newHead.blockRoot !== oldHead.blockRoot) {
|
|
324
|
-
|
|
325
|
-
this.regen.updateHeadState(newHead, postState);
|
|
341
|
+
this.onHeadChanged(oldHead, newHead, postState);
|
|
326
342
|
|
|
327
343
|
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
344
|
if (this.metrics) {
|
|
335
|
-
this.metrics.headSlot.set(newHead.slot);
|
|
336
345
|
// Only track "recent" blocks. Otherwise sync can distort this metrics heavily.
|
|
337
346
|
// We want to track recent blocks coming from gossip, unknown block sync, and API.
|
|
338
347
|
const headFork = this.config.getForkName(newHead.slot);
|
|
@@ -345,32 +354,6 @@ export async function importBlock(
|
|
|
345
354
|
}
|
|
346
355
|
}
|
|
347
356
|
|
|
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
357
|
// Lightclient server support (only after altair)
|
|
375
358
|
// - Persist state witness
|
|
376
359
|
// - Use block's syncAggregate
|
|
@@ -417,7 +400,7 @@ export async function importBlock(
|
|
|
417
400
|
// 4) Block meets the criteria of being re-orged out (this is also checked inside the function)
|
|
418
401
|
const result = this.forkChoice.shouldOverrideForkChoiceUpdate(
|
|
419
402
|
blockSummary,
|
|
420
|
-
this.clock.
|
|
403
|
+
this.clock.msFromSlot(currentSlot),
|
|
421
404
|
currentSlot
|
|
422
405
|
);
|
|
423
406
|
shouldOverrideFcu = result.shouldOverrideFcu;
|
|
@@ -469,7 +452,13 @@ export async function importBlock(
|
|
|
469
452
|
const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
|
|
470
453
|
if (headBlockHash !== ZERO_HASH_HEX) {
|
|
471
454
|
this.executionEngine
|
|
472
|
-
.notifyForkchoiceUpdate(
|
|
455
|
+
.notifyForkchoiceUpdate(
|
|
456
|
+
this.config.getForkName(fcuHead.slot),
|
|
457
|
+
fcuHead.blockRoot,
|
|
458
|
+
headBlockHash,
|
|
459
|
+
safeBlockHash,
|
|
460
|
+
finalizedBlockHash
|
|
461
|
+
)
|
|
473
462
|
.catch((e) => {
|
|
474
463
|
if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
|
|
475
464
|
this.logger.error("Error pushing notifyForkchoiceUpdate()", {headBlockHash, finalizedBlockHash}, e);
|
|
@@ -2,6 +2,9 @@ import {SerializedList} from "@chainsafe/ssz";
|
|
|
2
2
|
import {routes} from "@lodestar/api";
|
|
3
3
|
import {
|
|
4
4
|
ExecutionStatus,
|
|
5
|
+
ForkChoiceError,
|
|
6
|
+
ForkChoiceErrorCode,
|
|
7
|
+
InvalidBlockCode,
|
|
5
8
|
PayloadExecutionStatus,
|
|
6
9
|
getFinalizedExecutionBlockHash,
|
|
7
10
|
getSafeExecutionBlockHash,
|
|
@@ -26,7 +29,6 @@ import {
|
|
|
26
29
|
verifyExecutionPayloadEnvelope,
|
|
27
30
|
verifyExecutionPayloadEnvelopeSignature,
|
|
28
31
|
} from "./verifyExecutionPayloadEnvelope.js";
|
|
29
|
-
import {verifyPayloadsDataAvailability} from "./verifyPayloadsDataAvailability.js";
|
|
30
32
|
|
|
31
33
|
const EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS = 64;
|
|
32
34
|
|
|
@@ -34,9 +36,11 @@ export enum PayloadErrorCode {
|
|
|
34
36
|
EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
|
|
35
37
|
EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
|
|
36
38
|
BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
|
|
39
|
+
BLOCK_EXECUTION_INVALID = "PAYLOAD_ERROR_BLOCK_EXECUTION_INVALID",
|
|
37
40
|
MISS_BLOCK_STATE = "PAYLOAD_ERROR_MISS_BLOCK_STATE",
|
|
38
41
|
ENVELOPE_VERIFICATION_ERROR = "PAYLOAD_ERROR_ENVELOPE_VERIFICATION_ERROR",
|
|
39
42
|
INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
|
|
43
|
+
DATA_UNAVAILABLE = "PAYLOAD_ERROR_DATA_UNAVAILABLE",
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
export type PayloadErrorType =
|
|
@@ -54,6 +58,10 @@ export type PayloadErrorType =
|
|
|
54
58
|
code: PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE;
|
|
55
59
|
blockRootHex: string;
|
|
56
60
|
}
|
|
61
|
+
| {
|
|
62
|
+
code: PayloadErrorCode.BLOCK_EXECUTION_INVALID;
|
|
63
|
+
blockRootHex: string;
|
|
64
|
+
}
|
|
57
65
|
| {
|
|
58
66
|
code: PayloadErrorCode.MISS_BLOCK_STATE;
|
|
59
67
|
blockRootHex: string;
|
|
@@ -64,6 +72,9 @@ export type PayloadErrorType =
|
|
|
64
72
|
}
|
|
65
73
|
| {
|
|
66
74
|
code: PayloadErrorCode.INVALID_SIGNATURE;
|
|
75
|
+
}
|
|
76
|
+
| {
|
|
77
|
+
code: PayloadErrorCode.DATA_UNAVAILABLE;
|
|
67
78
|
};
|
|
68
79
|
|
|
69
80
|
export class PayloadError extends Error {
|
|
@@ -95,7 +106,8 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
|
|
|
95
106
|
* are applied on the next block via processParentExecutionPayload.
|
|
96
107
|
*
|
|
97
108
|
* The DA wait must have run upstream (range sync awaits DA in `verifyBlocksInEpoch` for the
|
|
98
|
-
* whole segment; gossip / API path
|
|
109
|
+
* whole segment; the gossip / API / unknown-payload sync path waits in `PayloadEnvelopeProcessor`
|
|
110
|
+
* before the import is queued).
|
|
99
111
|
*
|
|
100
112
|
* Steps:
|
|
101
113
|
* 1. Emit `execution_payload_available` event for payload attestation
|
|
@@ -140,6 +152,13 @@ export async function importExecutionPayload(
|
|
|
140
152
|
blockRootHex,
|
|
141
153
|
});
|
|
142
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
|
+
}
|
|
143
162
|
|
|
144
163
|
// 3. Regenerate state for envelope verification
|
|
145
164
|
const blockState = await this.regen
|
|
@@ -318,25 +337,45 @@ export async function importExecutionPayload(
|
|
|
318
337
|
|
|
319
338
|
// 6. Update fork choice, transitions the block's PENDING variant to FULL
|
|
320
339
|
const execStatus = toForkChoiceExecutionStatus(execResult.status);
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
+
}
|
|
329
360
|
|
|
330
361
|
// 7. Queue notifyForkchoiceUpdate to engine api
|
|
331
362
|
const head = this.forkChoice.getHead();
|
|
332
|
-
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
|
+
) {
|
|
333
370
|
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice, this.logger);
|
|
334
371
|
const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
|
|
335
|
-
this.executionEngine
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
+
});
|
|
340
379
|
}
|
|
341
380
|
|
|
342
381
|
// 8. Record metrics for payload envelope and column sources
|
|
@@ -368,21 +407,3 @@ export async function importExecutionPayload(
|
|
|
368
407
|
delaySec,
|
|
369
408
|
});
|
|
370
409
|
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Process an execution payload envelope end-to-end: wait for DA, then import.
|
|
374
|
-
*
|
|
375
|
-
* Used by the PayloadEnvelopeProcessor queue (gossip / API / unknown-payload sync) — i.e.
|
|
376
|
-
* callers that have NOT already awaited DA themselves. Range sync's inline dispatch in
|
|
377
|
-
* processBlocks skips this wrapper and calls `importExecutionPayload` directly, since
|
|
378
|
-
* `verifyBlocksInEpoch` already awaited DA for the segment.
|
|
379
|
-
*/
|
|
380
|
-
export async function processExecutionPayload(
|
|
381
|
-
this: BeaconChain,
|
|
382
|
-
payloadInput: PayloadEnvelopeInput,
|
|
383
|
-
signal: AbortSignal,
|
|
384
|
-
opts: ImportPayloadOpts = {}
|
|
385
|
-
): Promise<void> {
|
|
386
|
-
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability([payloadInput], signal);
|
|
387
|
-
await importExecutionPayload.call(this, payloadInput, dataAvailabilityStatuses[0], opts);
|
|
388
|
-
}
|
|
@@ -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
|
}
|