@lodestar/beacon-node 1.43.0-dev.bc569affb9 → 1.43.0-dev.c98da75ec7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +16 -5
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +86 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +0 -1
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.js +1 -1
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +68 -2
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +4 -1
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +16 -28
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +23 -6
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +57 -24
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts +5 -3
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +58 -25
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +12 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +28 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +17 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +2 -2
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +4 -3
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +21 -2
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +92 -12
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +5 -3
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +50 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +12 -8
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
- package/lib/chain/chain.d.ts +5 -3
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +38 -13
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +0 -11
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +0 -4
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +8 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +19 -1
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +3 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/index.d.ts +1 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +1 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +40 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/errors/proposerPreferences.js +14 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -0
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +6 -1
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +5 -3
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +1 -1
- package/lib/chain/lightClient/index.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 +4 -3
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +56 -14
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.d.ts +29 -0
- package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -0
- package/lib/chain/opPools/proposerPreferencesPool.js +56 -0
- package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -0
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +16 -18
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +12 -3
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +35 -17
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -0
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +1 -4
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +1 -4
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -0
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -0
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +21 -11
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +70 -20
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
- package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -0
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +68 -17
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +5 -3
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +8 -0
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/validation/proposerPreferences.js +91 -0
- package/lib/chain/validation/proposerPreferences.js.map +1 -0
- package/lib/metrics/metrics/lodestar.d.ts +5 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +9 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +7 -1
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +1 -0
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.js +12 -1
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +29 -766
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +6 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +3 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +3 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +13 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +77 -20
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/index.js +5 -0
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +6 -5
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts +9 -0
- package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts.map +1 -0
- package/lib/network/reqresp/handlers/beaconBlocksByHead.js +61 -0
- package/lib/network/reqresp/handlers/beaconBlocksByHead.js.map +1 -0
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/index.js +5 -0
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/interface.d.ts +1 -1
- package/lib/network/reqresp/interface.js +1 -1
- package/lib/network/reqresp/protocols.d.ts +1 -0
- package/lib/network/reqresp/protocols.d.ts.map +1 -1
- package/lib/network/reqresp/protocols.js +5 -0
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
- package/lib/network/reqresp/rateLimit.js +4 -0
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +1 -0
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/reqresp/types.d.ts +3 -0
- package/lib/network/reqresp/types.d.ts.map +1 -1
- package/lib/network/reqresp/types.js +3 -0
- package/lib/network/reqresp/types.js.map +1 -1
- package/lib/node/nodejs.js +2 -2
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/constants.d.ts +7 -1
- package/lib/sync/constants.d.ts.map +1 -1
- package/lib/sync/constants.js +7 -4
- package/lib/sync/constants.js.map +1 -1
- package/lib/sync/range/batch.d.ts +55 -8
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +291 -66
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +22 -4
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +103 -11
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +71 -11
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/range/utils/peerBalancer.d.ts +2 -1
- package/lib/sync/range/utils/peerBalancer.d.ts.map +1 -1
- package/lib/sync/range/utils/peerBalancer.js +8 -4
- package/lib/sync/range/utils/peerBalancer.js.map +1 -1
- package/lib/sync/sync.d.ts.map +1 -1
- package/lib/sync/sync.js +13 -0
- package/lib/sync/sync.js.map +1 -1
- package/lib/sync/types.d.ts +34 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +34 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +29 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +727 -61
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +73 -10
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +213 -26
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +16 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.js +0 -9
- package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
- package/lib/sync/utils/rateLimit.d.ts +2 -0
- package/lib/sync/utils/rateLimit.d.ts.map +1 -0
- package/lib/sync/utils/rateLimit.js +15 -0
- package/lib/sync/utils/rateLimit.js.map +1 -0
- package/lib/util/dependentRoot.d.ts +6 -2
- package/lib/util/dependentRoot.d.ts.map +1 -1
- package/lib/util/dependentRoot.js +20 -16
- package/lib/util/dependentRoot.js.map +1 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +8 -6
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +15 -16
- package/src/api/impl/beacon/blocks/index.ts +21 -5
- package/src/api/impl/beacon/pool/index.ts +136 -1
- package/src/api/impl/debug/index.ts +0 -1
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +82 -1
- package/src/chain/blocks/blockInput/blockInput.ts +4 -1
- package/src/chain/blocks/importBlock.ts +16 -48
- package/src/chain/blocks/importExecutionPayload.ts +76 -30
- package/src/chain/blocks/index.ts +71 -22
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +37 -3
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +18 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
- package/src/chain/blocks/types.ts +4 -3
- package/src/chain/blocks/utils/chainSegment.ts +117 -17
- package/src/chain/blocks/verifyBlock.ts +70 -9
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +16 -8
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
- package/src/chain/chain.ts +46 -10
- package/src/chain/emitter.ts +0 -11
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/executionPayloadBid.ts +22 -1
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/errors/proposerPreferences.ts +47 -0
- package/src/chain/initState.ts +9 -1
- package/src/chain/interface.ts +9 -1
- package/src/chain/lightClient/index.ts +6 -6
- package/src/chain/opPools/index.ts +1 -0
- package/src/chain/opPools/payloadAttestationPool.ts +63 -18
- package/src/chain/opPools/proposerPreferencesPool.ts +59 -0
- package/src/chain/prepareNextSlot.ts +21 -29
- package/src/chain/produceBlock/produceBlockBody.ts +46 -22
- package/src/chain/regen/interface.ts +1 -0
- package/src/chain/regen/queued.ts +2 -7
- package/src/chain/regen/regen.ts +2 -7
- package/src/chain/seenCache/index.ts +1 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +90 -24
- package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/executionPayloadBid.ts +71 -18
- package/src/chain/validation/payloadAttestationMessage.ts +6 -4
- package/src/chain/validation/proposerPreferences.ts +110 -0
- package/src/metrics/metrics/lodestar.ts +10 -0
- package/src/network/gossip/interface.ts +6 -0
- package/src/network/gossip/scoringParameters.ts +14 -1
- package/src/network/gossip/topic.ts +6 -0
- package/src/network/interface.ts +3 -0
- package/src/network/network.ts +34 -0
- package/src/network/processor/gossipHandlers.ts +96 -20
- package/src/network/processor/gossipQueues/index.ts +5 -0
- package/src/network/processor/index.ts +6 -5
- package/src/network/reqresp/ReqRespBeaconNode.ts +1 -0
- package/src/network/reqresp/handlers/beaconBlocksByHead.ts +91 -0
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
- package/src/network/reqresp/handlers/index.ts +5 -0
- package/src/network/reqresp/interface.ts +1 -1
- package/src/network/reqresp/protocols.ts +6 -0
- package/src/network/reqresp/rateLimit.ts +4 -0
- package/src/network/reqresp/score.ts +1 -0
- package/src/network/reqresp/types.ts +5 -0
- package/src/node/nodejs.ts +2 -2
- package/src/sync/constants.ts +8 -4
- package/src/sync/range/batch.ts +388 -75
- package/src/sync/range/chain.ts +131 -14
- package/src/sync/range/range.ts +86 -11
- package/src/sync/range/utils/peerBalancer.ts +9 -3
- package/src/sync/sync.ts +13 -1
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +915 -65
- package/src/sync/utils/downloadByRange.ts +386 -39
- package/src/sync/utils/downloadByRoot.ts +24 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
- package/src/sync/utils/rateLimit.ts +16 -0
- package/src/util/dependentRoot.ts +22 -18
- package/src/util/sszBytes.ts +8 -6
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
computeTimeAtSlot,
|
|
27
27
|
getCurrentSlot,
|
|
28
28
|
isStatePostAltair,
|
|
29
|
+
isStatePostGloas,
|
|
29
30
|
proposerShufflingDecisionRoot,
|
|
30
31
|
} from "@lodestar/state-transition";
|
|
31
32
|
import {
|
|
@@ -1049,6 +1050,36 @@ export function getValidatorApi(
|
|
|
1049
1050
|
};
|
|
1050
1051
|
},
|
|
1051
1052
|
|
|
1053
|
+
async producePayloadAttestationData({slot}) {
|
|
1054
|
+
const fork = config.getForkName(slot);
|
|
1055
|
+
if (!isForkPostGloas(fork)) {
|
|
1056
|
+
throw new ApiError(400, `producePayloadAttestationData is not supported before Gloas fork=${fork}`);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
notWhileSyncing();
|
|
1060
|
+
await waitForSlot(slot);
|
|
1061
|
+
|
|
1062
|
+
const block = chain.forkChoice.getCanonicalBlockClosestLteSlot(slot);
|
|
1063
|
+
if (!block) {
|
|
1064
|
+
throw new ApiError(404, `No canonical block found at or before slot=${slot}`);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
const blockIsForSlot = block.slot === slot;
|
|
1068
|
+
const payloadInput = chain.seenPayloadEnvelopeInputCache.get(block.blockRoot);
|
|
1069
|
+
const payloadPresent = blockIsForSlot && (payloadInput?.hasPayloadEnvelope() ?? false);
|
|
1070
|
+
const blobDataAvailable = blockIsForSlot && (payloadInput?.hasAllData() ?? false);
|
|
1071
|
+
|
|
1072
|
+
return {
|
|
1073
|
+
data: {
|
|
1074
|
+
beaconBlockRoot: fromHex(block.blockRoot),
|
|
1075
|
+
slot,
|
|
1076
|
+
payloadPresent,
|
|
1077
|
+
blobDataAvailable,
|
|
1078
|
+
},
|
|
1079
|
+
meta: {version: fork},
|
|
1080
|
+
};
|
|
1081
|
+
},
|
|
1082
|
+
|
|
1052
1083
|
/**
|
|
1053
1084
|
* GET `/eth/v1/validator/sync_committee_contribution`
|
|
1054
1085
|
*
|
|
@@ -1263,6 +1294,55 @@ export function getValidatorApi(
|
|
|
1263
1294
|
};
|
|
1264
1295
|
},
|
|
1265
1296
|
|
|
1297
|
+
async getPtcDuties({epoch, indices}) {
|
|
1298
|
+
notWhileSyncing();
|
|
1299
|
+
|
|
1300
|
+
if (indices.length === 0) {
|
|
1301
|
+
throw new ApiError(400, "No validator to get PTC duties");
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
const startSlot = computeStartSlotAtEpoch(epoch);
|
|
1305
|
+
const fork = config.getForkName(startSlot);
|
|
1306
|
+
if (!isForkPostGloas(fork)) {
|
|
1307
|
+
throw new ApiError(400, `PTC duties are not supported before Gloas fork=${fork}`);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
await waitForNextClosestEpoch();
|
|
1311
|
+
|
|
1312
|
+
if (epoch > chain.clock.currentEpoch + 1) {
|
|
1313
|
+
throw new ApiError(400, "Cannot get PTC duties for epoch more than one ahead");
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
const head = chain.forkChoice.getHead();
|
|
1317
|
+
const state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.getDuties);
|
|
1318
|
+
if (!isStatePostGloas(state)) {
|
|
1319
|
+
throw new ApiError(400, `PTC duties are not available before Gloas fork=${state.forkName}`);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
const pubkeys = getPubkeysForIndices(state, indices);
|
|
1323
|
+
const ptcs = state.getEpochPTCs(epoch);
|
|
1324
|
+
const duties: routes.validator.PtcDuty[] = [];
|
|
1325
|
+
for (let i = 0, len = indices.length; i < len; i++) {
|
|
1326
|
+
const validatorIndex = indices[i];
|
|
1327
|
+
for (let j = 0; j < SLOTS_PER_EPOCH; j++) {
|
|
1328
|
+
if (ptcs[j].indexOf(validatorIndex) !== -1) {
|
|
1329
|
+
duties.push({pubkey: pubkeys[i], validatorIndex, slot: j + startSlot});
|
|
1330
|
+
break;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
const dependentRoot = fromHex(state.getShufflingDecisionRoot(epoch)) || (await getGenesisBlockRoot(state));
|
|
1336
|
+
|
|
1337
|
+
return {
|
|
1338
|
+
data: duties,
|
|
1339
|
+
meta: {
|
|
1340
|
+
dependentRoot: toRootHex(dependentRoot),
|
|
1341
|
+
executionOptimistic: isOptimisticBlock(head),
|
|
1342
|
+
},
|
|
1343
|
+
};
|
|
1344
|
+
},
|
|
1345
|
+
|
|
1266
1346
|
/**
|
|
1267
1347
|
* `POST /eth/v1/validator/duties/sync/{epoch}`
|
|
1268
1348
|
*
|
|
@@ -1641,13 +1721,14 @@ export function getValidatorApi(
|
|
|
1641
1721
|
throw Error("Cached block production result is not full block");
|
|
1642
1722
|
}
|
|
1643
1723
|
|
|
1644
|
-
const {executionPayload, executionRequests} = produceResult as ProduceFullGloas;
|
|
1724
|
+
const {executionPayload, executionRequests, parentBlockRoot} = produceResult as ProduceFullGloas;
|
|
1645
1725
|
|
|
1646
1726
|
const envelope: gloas.ExecutionPayloadEnvelope = {
|
|
1647
1727
|
payload: executionPayload,
|
|
1648
1728
|
executionRequests: executionRequests,
|
|
1649
1729
|
builderIndex: BUILDER_INDEX_SELF_BUILD,
|
|
1650
1730
|
beaconBlockRoot,
|
|
1731
|
+
parentBeaconBlockRoot: parentBlockRoot,
|
|
1651
1732
|
};
|
|
1652
1733
|
|
|
1653
1734
|
logger.info("Produced execution payload envelope", {
|
|
@@ -895,8 +895,11 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
895
895
|
return this.getAllColumnsWithSource().map(({columnSidecar}) => columnSidecar);
|
|
896
896
|
}
|
|
897
897
|
|
|
898
|
+
/**
|
|
899
|
+
* Strictly checks missing sampled columns. Does NOT short-circuit on `state.hasAllData`.
|
|
900
|
+
*/
|
|
898
901
|
getMissingSampledColumnMeta(): MissingColumnMeta {
|
|
899
|
-
if (this.state.
|
|
902
|
+
if (this.state.hasComputedAllData) {
|
|
900
903
|
return {
|
|
901
904
|
missing: [],
|
|
902
905
|
versionedHashes: this.state.versionedHashes,
|
|
@@ -9,14 +9,7 @@ import {
|
|
|
9
9
|
NotReorgedReason,
|
|
10
10
|
getSafeExecutionBlockHash,
|
|
11
11
|
} from "@lodestar/fork-choice";
|
|
12
|
-
import {
|
|
13
|
-
ForkPostAltair,
|
|
14
|
-
ForkPostElectra,
|
|
15
|
-
ForkPostGloas,
|
|
16
|
-
ForkSeq,
|
|
17
|
-
MAX_SEED_LOOKAHEAD,
|
|
18
|
-
SLOTS_PER_EPOCH,
|
|
19
|
-
} from "@lodestar/params";
|
|
12
|
+
import {ForkPostAltair, ForkPostElectra, ForkSeq, MAX_SEED_LOOKAHEAD, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
20
13
|
import {
|
|
21
14
|
IBeaconStateView,
|
|
22
15
|
RootCache,
|
|
@@ -27,17 +20,7 @@ import {
|
|
|
27
20
|
isStatePostAltair,
|
|
28
21
|
isStatePostBellatrix,
|
|
29
22
|
} from "@lodestar/state-transition";
|
|
30
|
-
import {
|
|
31
|
-
Attestation,
|
|
32
|
-
BeaconBlock,
|
|
33
|
-
SignedBeaconBlock,
|
|
34
|
-
altair,
|
|
35
|
-
capella,
|
|
36
|
-
electra,
|
|
37
|
-
isGloasBeaconBlock,
|
|
38
|
-
phase0,
|
|
39
|
-
ssz,
|
|
40
|
-
} from "@lodestar/types";
|
|
23
|
+
import {Attestation, BeaconBlock, altair, capella, electra, isGloasBeaconBlock, phase0, ssz} from "@lodestar/types";
|
|
41
24
|
import {isErrorAborted, toRootHex} from "@lodestar/utils";
|
|
42
25
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
43
26
|
import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
@@ -86,8 +69,8 @@ export async function importBlock(
|
|
|
86
69
|
fullyVerifiedBlock: FullyVerifiedBlock,
|
|
87
70
|
opts: ImportBlockOpts
|
|
88
71
|
): Promise<void> {
|
|
89
|
-
const {blockInput, postState, parentBlockSlot,
|
|
90
|
-
|
|
72
|
+
const {blockInput, postState, parentBlockSlot, dataAvailabilityStatus, indexedAttestations} = fullyVerifiedBlock;
|
|
73
|
+
let {executionStatus} = fullyVerifiedBlock;
|
|
91
74
|
const block = blockInput.getBlock();
|
|
92
75
|
const source = blockInput.getBlockSource();
|
|
93
76
|
const {slot: blockSlot} = block.message;
|
|
@@ -122,12 +105,23 @@ export async function importBlock(
|
|
|
122
105
|
|
|
123
106
|
// Should compute checkpoint balances before forkchoice.onBlock
|
|
124
107
|
this.checkpointBalancesCache.processState(blockRootHex, postState);
|
|
108
|
+
if (fork >= ForkSeq.gloas) {
|
|
109
|
+
const parentRootHex = toRootHex(block.message.parentRoot);
|
|
110
|
+
const parentBlock = this.forkChoice.getBlockHexDefaultStatus(parentRootHex);
|
|
111
|
+
if (parentBlock === null) {
|
|
112
|
+
throw Error(`Parent block not found in forkChoice, parentRoot=${parentRootHex}`);
|
|
113
|
+
}
|
|
114
|
+
if (parentBlock.executionStatus === ExecutionStatus.Invalid) {
|
|
115
|
+
throw Error(`Parent block has invalid execution status, parentRoot=${parentRootHex}`);
|
|
116
|
+
}
|
|
117
|
+
executionStatus = parentBlock.executionStatus;
|
|
118
|
+
}
|
|
125
119
|
const blockSummary = this.forkChoice.onBlock(
|
|
126
120
|
block.message,
|
|
127
121
|
postState,
|
|
128
122
|
blockDelaySec,
|
|
129
123
|
currentSlot,
|
|
130
|
-
|
|
124
|
+
executionStatus,
|
|
131
125
|
dataAvailabilityStatus
|
|
132
126
|
);
|
|
133
127
|
|
|
@@ -135,32 +129,6 @@ export async function importBlock(
|
|
|
135
129
|
// Some block event handlers require state being in state cache so need to do this before emitting EventType.block
|
|
136
130
|
this.regen.processState(blockRootHex, postState);
|
|
137
131
|
|
|
138
|
-
// For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
|
|
139
|
-
if (fork >= ForkSeq.gloas) {
|
|
140
|
-
const payloadInput = this.seenPayloadEnvelopeInputCache.add({
|
|
141
|
-
blockRootHex,
|
|
142
|
-
block: block as SignedBeaconBlock<ForkPostGloas>,
|
|
143
|
-
forkName: blockInput.forkName,
|
|
144
|
-
sampledColumns: this.custodyConfig.sampledColumns,
|
|
145
|
-
custodyColumns: this.custodyConfig.custodyColumns,
|
|
146
|
-
timeCreatedSec: fullyVerifiedBlock.seenTimestampSec,
|
|
147
|
-
});
|
|
148
|
-
this.logger.debug("Created PayloadEnvelopeInput for block", {
|
|
149
|
-
slot: blockSlot,
|
|
150
|
-
root: blockRootHex,
|
|
151
|
-
source: source.source,
|
|
152
|
-
...(opts.seenTimestampSec !== undefined ? {recvToImport: Date.now() / 1000 - opts.seenTimestampSec} : {}),
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
|
|
156
|
-
// which is all the information we need so there is no reason to delay until execution payload arrives
|
|
157
|
-
// TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
|
|
158
|
-
// (for example later in the slot). Do not couple retries to incoming gossip columns.
|
|
159
|
-
// Columns fetched here feed payloadInput.addColumn, which resolves waitForAllData for any
|
|
160
|
-
// in-flight importExecutionPayload. No processExecutionPayload trigger needed from this path.
|
|
161
|
-
this.getBlobsTracker.triggerGetBlobs(payloadInput);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
132
|
this.metrics?.importBlock.bySource.inc({source: source.source});
|
|
165
133
|
this.logger.verbose("Added block to forkchoice and state cache", {slot: blockSlot, root: blockRootHex});
|
|
166
134
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
|
-
import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
|
|
3
|
-
import {isStatePostGloas} from "@lodestar/state-transition";
|
|
4
|
-
import {
|
|
2
|
+
import {ExecutionStatus, PayloadExecutionStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
3
|
+
import {DataAvailabilityStatus, isStatePostGloas} from "@lodestar/state-transition";
|
|
4
|
+
import {isErrorAborted} from "@lodestar/utils";
|
|
5
|
+
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
5
6
|
import {ExecutionPayloadStatus} from "../../execution/index.js";
|
|
6
7
|
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
7
8
|
import {BeaconChain} from "../chain.js";
|
|
@@ -20,6 +21,7 @@ export enum PayloadErrorCode {
|
|
|
20
21
|
EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
|
|
21
22
|
EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
|
|
22
23
|
BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
|
|
24
|
+
MISS_BLOCK_STATE = "PAYLOAD_ERROR_MISS_BLOCK_STATE",
|
|
23
25
|
ENVELOPE_VERIFICATION_ERROR = "PAYLOAD_ERROR_ENVELOPE_VERIFICATION_ERROR",
|
|
24
26
|
INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
|
|
25
27
|
}
|
|
@@ -39,6 +41,10 @@ export type PayloadErrorType =
|
|
|
39
41
|
code: PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE;
|
|
40
42
|
blockRootHex: string;
|
|
41
43
|
}
|
|
44
|
+
| {
|
|
45
|
+
code: PayloadErrorCode.MISS_BLOCK_STATE;
|
|
46
|
+
blockRootHex: string;
|
|
47
|
+
}
|
|
42
48
|
| {
|
|
43
49
|
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR;
|
|
44
50
|
message: string;
|
|
@@ -60,7 +66,6 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
|
|
|
60
66
|
switch (status) {
|
|
61
67
|
case ExecutionPayloadStatus.VALID:
|
|
62
68
|
return ExecutionStatus.Valid;
|
|
63
|
-
// TODO GLOAS: Handle optimistic import for payload
|
|
64
69
|
case ExecutionPayloadStatus.SYNCING:
|
|
65
70
|
case ExecutionPayloadStatus.ACCEPTED:
|
|
66
71
|
return ExecutionStatus.Syncing;
|
|
@@ -75,21 +80,24 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
|
|
|
75
80
|
* The envelope is only verified here, no state mutation. State effects from the payload
|
|
76
81
|
* are applied on the next block via processParentExecutionPayload.
|
|
77
82
|
*
|
|
83
|
+
* The DA wait must have run upstream (range sync awaits DA in `verifyBlocksInEpoch` for the
|
|
84
|
+
* whole segment; gossip / API path uses the `processExecutionPayload` wrapper below).
|
|
85
|
+
*
|
|
78
86
|
* Steps:
|
|
79
87
|
* 1. Emit `execution_payload_available` event for payload attestation
|
|
80
88
|
* 2. Get the ProtoBlock from fork choice
|
|
81
|
-
* 3.
|
|
82
|
-
* 4.
|
|
83
|
-
* 5.
|
|
84
|
-
* 6.
|
|
85
|
-
* 7.
|
|
89
|
+
* 3. Regenerate state for envelope verification
|
|
90
|
+
* 4. Verify envelope (fields against state, signature, and EL in parallel where possible)
|
|
91
|
+
* 5. Persist verified payload envelope to hot DB (waits for write-queue space for backpressure)
|
|
92
|
+
* 6. Update fork choice (transitions the block's PENDING variant to FULL)
|
|
93
|
+
* 7. Queue notifyForkchoiceUpdate to engine api
|
|
86
94
|
* 8. Record metrics for payload envelope and column sources
|
|
87
95
|
* 9. Emit `execution_payload` event
|
|
88
96
|
*/
|
|
89
97
|
export async function importExecutionPayload(
|
|
90
98
|
this: BeaconChain,
|
|
91
99
|
payloadInput: PayloadEnvelopeInput,
|
|
92
|
-
|
|
100
|
+
dataAvailabilityStatus: DataAvailabilityStatus,
|
|
93
101
|
opts: ImportPayloadOpts = {}
|
|
94
102
|
): Promise<void> {
|
|
95
103
|
const signedEnvelope = payloadInput.getPayloadEnvelope();
|
|
@@ -119,17 +127,20 @@ export async function importExecutionPayload(
|
|
|
119
127
|
});
|
|
120
128
|
}
|
|
121
129
|
|
|
122
|
-
// 3.
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
// 3. Regenerate state for envelope verification
|
|
131
|
+
const blockState = await this.regen
|
|
132
|
+
.getBlockSlotState(protoBlock, protoBlock.slot, {dontTransferCache: true}, RegenCaller.processBlock)
|
|
133
|
+
.catch(() =>
|
|
134
|
+
// only happen at the 1st batch of skipped slot checkpoint sync
|
|
135
|
+
this.regen.getClosestHeadState(protoBlock)
|
|
136
|
+
);
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
);
|
|
138
|
+
if (blockState == null) {
|
|
139
|
+
throw new PayloadError({
|
|
140
|
+
code: PayloadErrorCode.MISS_BLOCK_STATE,
|
|
141
|
+
blockRootHex: protoBlock.blockRoot,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
133
144
|
if (!isStatePostGloas(blockState)) {
|
|
134
145
|
throw new PayloadError({
|
|
135
146
|
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
|
|
@@ -137,7 +148,7 @@ export async function importExecutionPayload(
|
|
|
137
148
|
});
|
|
138
149
|
}
|
|
139
150
|
|
|
140
|
-
//
|
|
151
|
+
// 4. Verify envelope fields against state first to fail fast before the EL + BLS work.
|
|
141
152
|
// When validSignature is true, gossip/API has already verified both the signature and the
|
|
142
153
|
// executionRequestsRoot, so we skip those checks here.
|
|
143
154
|
try {
|
|
@@ -154,13 +165,13 @@ export async function importExecutionPayload(
|
|
|
154
165
|
);
|
|
155
166
|
}
|
|
156
167
|
|
|
157
|
-
//
|
|
168
|
+
// 4a. Run EL and signature verification in parallel
|
|
158
169
|
const [execResult, signatureValid] = await Promise.all([
|
|
159
170
|
this.executionEngine.notifyNewPayload(
|
|
160
171
|
fork,
|
|
161
172
|
envelope.payload,
|
|
162
173
|
payloadInput.getVersionedHashes(),
|
|
163
|
-
|
|
174
|
+
envelope.parentBeaconBlockRoot,
|
|
164
175
|
envelope.executionRequests
|
|
165
176
|
),
|
|
166
177
|
|
|
@@ -176,12 +187,12 @@ export async function importExecutionPayload(
|
|
|
176
187
|
),
|
|
177
188
|
]);
|
|
178
189
|
|
|
179
|
-
//
|
|
190
|
+
// 4b. Check signature verification result
|
|
180
191
|
if (!signatureValid) {
|
|
181
192
|
throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
|
|
182
193
|
}
|
|
183
194
|
|
|
184
|
-
//
|
|
195
|
+
// 4c. Handle EL response
|
|
185
196
|
switch (execResult.status) {
|
|
186
197
|
case ExecutionPayloadStatus.VALID:
|
|
187
198
|
break;
|
|
@@ -207,7 +218,7 @@ export async function importExecutionPayload(
|
|
|
207
218
|
});
|
|
208
219
|
}
|
|
209
220
|
|
|
210
|
-
//
|
|
221
|
+
// 5. Persist payload envelope to hot DB. Wait for write-queue space here to apply backpressure
|
|
211
222
|
// on the import pipeline during sync, then perform the write asynchronously to avoid blocking.
|
|
212
223
|
await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
|
|
213
224
|
this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
|
|
@@ -220,9 +231,27 @@ export async function importExecutionPayload(
|
|
|
220
231
|
}
|
|
221
232
|
});
|
|
222
233
|
|
|
223
|
-
//
|
|
234
|
+
// 6. Update fork choice, transitions the block's PENDING variant to FULL
|
|
224
235
|
const execStatus = toForkChoiceExecutionStatus(execResult.status);
|
|
225
|
-
this.forkChoice.onExecutionPayload(
|
|
236
|
+
this.forkChoice.onExecutionPayload(
|
|
237
|
+
blockRootHex,
|
|
238
|
+
blockHashHex,
|
|
239
|
+
envelope.payload.blockNumber,
|
|
240
|
+
execStatus,
|
|
241
|
+
dataAvailabilityStatus
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
// 7. Queue notifyForkchoiceUpdate to engine api
|
|
245
|
+
const head = this.forkChoice.getHead();
|
|
246
|
+
if (!this.opts.disableImportExecutionFcU && blockRootHex === head.blockRoot) {
|
|
247
|
+
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
|
|
248
|
+
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
249
|
+
this.executionEngine.notifyForkchoiceUpdate(fork, blockHashHex, safeBlockHash, finalizedBlockHash).catch((e) => {
|
|
250
|
+
if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
|
|
251
|
+
this.logger.error("Error pushing notifyForkchoiceUpdate()", {blockHashHex, finalizedBlockHash}, e);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
226
255
|
|
|
227
256
|
// 8. Record metrics for payload envelope and column sources
|
|
228
257
|
this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
|
|
@@ -237,8 +266,7 @@ export async function importExecutionPayload(
|
|
|
237
266
|
builderIndex: envelope.builderIndex,
|
|
238
267
|
blockHash: blockHashHex,
|
|
239
268
|
blockRoot: blockRootHex,
|
|
240
|
-
|
|
241
|
-
executionOptimistic: false,
|
|
269
|
+
executionOptimistic: execStatus === ExecutionStatus.Syncing,
|
|
242
270
|
});
|
|
243
271
|
}
|
|
244
272
|
|
|
@@ -249,3 +277,21 @@ export async function importExecutionPayload(
|
|
|
249
277
|
blockHash: blockHashHex,
|
|
250
278
|
});
|
|
251
279
|
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Process an execution payload envelope end-to-end: wait for DA, then import.
|
|
283
|
+
*
|
|
284
|
+
* Used by the PayloadEnvelopeProcessor queue (gossip / API / unknown-payload sync) — i.e.
|
|
285
|
+
* callers that have NOT already awaited DA themselves. Range sync's inline dispatch in
|
|
286
|
+
* processBlocks skips this wrapper and calls `importExecutionPayload` directly, since
|
|
287
|
+
* `verifyBlocksInEpoch` already awaited DA for the segment.
|
|
288
|
+
*/
|
|
289
|
+
export async function processExecutionPayload(
|
|
290
|
+
this: BeaconChain,
|
|
291
|
+
payloadInput: PayloadEnvelopeInput,
|
|
292
|
+
signal: AbortSignal,
|
|
293
|
+
opts: ImportPayloadOpts = {}
|
|
294
|
+
): Promise<void> {
|
|
295
|
+
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability([payloadInput], signal);
|
|
296
|
+
await importExecutionPayload.call(this, payloadInput, dataAvailabilityStatuses[0], opts);
|
|
297
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {SignedBeaconBlock} from "@lodestar/types";
|
|
1
|
+
import {SignedBeaconBlock, Slot} from "@lodestar/types";
|
|
2
2
|
import {isErrorAborted, toRootHex} from "@lodestar/utils";
|
|
3
3
|
import {Metrics} from "../../metrics/metrics.js";
|
|
4
4
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
@@ -8,6 +8,8 @@ import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.j
|
|
|
8
8
|
import {BlockProcessOpts} from "../options.js";
|
|
9
9
|
import {IBlockInput} from "./blockInput/types.js";
|
|
10
10
|
import {importBlock} from "./importBlock.js";
|
|
11
|
+
import {importExecutionPayload} from "./importExecutionPayload.js";
|
|
12
|
+
import {PayloadEnvelopeInput} from "./payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
11
13
|
import {FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
|
|
12
14
|
import {assertLinearChainSegment} from "./utils/chainSegment.js";
|
|
13
15
|
import {verifyBlocksInEpoch} from "./verifyBlock.js";
|
|
@@ -21,20 +23,24 @@ const QUEUE_MAX_LENGTH = 256;
|
|
|
21
23
|
* BlockProcessor processes block jobs in a queued fashion, one after the other.
|
|
22
24
|
*/
|
|
23
25
|
export class BlockProcessor {
|
|
24
|
-
readonly jobQueue: JobItemQueue<[IBlockInput[], ImportBlockOpts], void>;
|
|
26
|
+
readonly jobQueue: JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>;
|
|
25
27
|
|
|
26
28
|
constructor(chain: BeaconChain, metrics: Metrics | null, opts: BlockProcessOpts, signal: AbortSignal) {
|
|
27
|
-
this.jobQueue = new JobItemQueue<[IBlockInput[], ImportBlockOpts], void>(
|
|
28
|
-
(job, importOpts) => {
|
|
29
|
-
return processBlocks.call(chain, job, {...opts, ...importOpts});
|
|
29
|
+
this.jobQueue = new JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>(
|
|
30
|
+
(job, payloadEnvelopes, importOpts) => {
|
|
31
|
+
return processBlocks.call(chain, job, payloadEnvelopes, {...opts, ...importOpts});
|
|
30
32
|
},
|
|
31
33
|
{maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
|
|
32
34
|
metrics?.blockProcessorQueue ?? undefined
|
|
33
35
|
);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
async processBlocksJob(
|
|
37
|
-
|
|
38
|
+
async processBlocksJob(
|
|
39
|
+
job: IBlockInput[],
|
|
40
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
41
|
+
opts: ImportBlockOpts = {}
|
|
42
|
+
): Promise<void> {
|
|
43
|
+
await this.jobQueue.push(job, payloadEnvelopes, opts);
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
|
|
@@ -51,18 +57,15 @@ export class BlockProcessor {
|
|
|
51
57
|
export async function processBlocks(
|
|
52
58
|
this: BeaconChain,
|
|
53
59
|
blocks: IBlockInput[],
|
|
60
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
54
61
|
opts: BlockProcessOpts & ImportBlockOpts
|
|
55
62
|
): Promise<void> {
|
|
56
63
|
if (blocks.length === 0) {
|
|
57
64
|
return; // TODO: or throw?
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
if (blocks.length > 1) {
|
|
61
|
-
assertLinearChainSegment(this.config, blocks);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
67
|
try {
|
|
65
|
-
const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksSanityChecks(this, blocks, opts);
|
|
68
|
+
const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksSanityChecks(this, blocks, payloadEnvelopes, opts);
|
|
66
69
|
|
|
67
70
|
// No relevant blocks, skip verifyBlocksInEpoch()
|
|
68
71
|
if (relevantBlocks.length === 0 || parentBlock === null) {
|
|
@@ -70,10 +73,31 @@ export async function processBlocks(
|
|
|
70
73
|
return;
|
|
71
74
|
}
|
|
72
75
|
|
|
76
|
+
const {warnings: orphanedPayloads} = assertLinearChainSegment(
|
|
77
|
+
this.config,
|
|
78
|
+
relevantBlocks,
|
|
79
|
+
payloadEnvelopes,
|
|
80
|
+
parentBlock
|
|
81
|
+
);
|
|
82
|
+
if (orphanedPayloads != null) {
|
|
83
|
+
for (const orphaned of orphanedPayloads) {
|
|
84
|
+
this.logger.debug("Orphaned payload envelope in chain segment", {
|
|
85
|
+
slot: orphaned.slot,
|
|
86
|
+
blockRoot: orphaned.payloadEnvelopeInput.blockRootHex,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
73
91
|
// Fully verify a block to be imported immediately after. Does not produce any side-effects besides adding intermediate
|
|
74
92
|
// states in the state cache through regen.
|
|
75
|
-
const {
|
|
76
|
-
|
|
93
|
+
const {
|
|
94
|
+
postStates,
|
|
95
|
+
blockDAStatuses,
|
|
96
|
+
payloadDAStatuses,
|
|
97
|
+
proposerBalanceDeltas,
|
|
98
|
+
segmentExecStatus,
|
|
99
|
+
indexedAttestationsByBlock,
|
|
100
|
+
} = await verifyBlocksInEpoch.call(this, parentBlock, relevantBlocks, payloadEnvelopes, opts);
|
|
77
101
|
|
|
78
102
|
// If segmentExecStatus has lvhForkchoice then, the entire segment should be invalid
|
|
79
103
|
// and we need to further propagate
|
|
@@ -85,24 +109,49 @@ export async function processBlocks(
|
|
|
85
109
|
}
|
|
86
110
|
|
|
87
111
|
const {executionStatuses} = segmentExecStatus;
|
|
88
|
-
const
|
|
89
|
-
|
|
112
|
+
const verifiedBlocksBySlot = new Map<Slot, FullyVerifiedBlock>();
|
|
113
|
+
for (let i = 0; i < relevantBlocks.length; i++) {
|
|
114
|
+
const block = relevantBlocks[i];
|
|
115
|
+
verifiedBlocksBySlot.set(block.getBlock().message.slot, {
|
|
90
116
|
blockInput: block,
|
|
91
117
|
postState: postStates[i],
|
|
92
118
|
parentBlockSlot: parentSlots[i],
|
|
93
119
|
executionStatus: executionStatuses[i],
|
|
94
120
|
// start supporting optimistic syncing/processing
|
|
95
|
-
dataAvailabilityStatus:
|
|
121
|
+
dataAvailabilityStatus: blockDAStatuses[i],
|
|
96
122
|
proposerBalanceDelta: proposerBalanceDeltas[i],
|
|
97
123
|
indexedAttestations: indexedAttestationsByBlock[i],
|
|
98
124
|
// TODO: Make this param mandatory and capture in gossip
|
|
99
125
|
seenTimestampSec: opts.seenTimestampSec ?? Math.floor(Date.now() / 1000),
|
|
100
|
-
})
|
|
101
|
-
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const slotSet = new Set<Slot>(blocks.map((b) => b.getBlock().message.slot));
|
|
130
|
+
if (payloadEnvelopes) {
|
|
131
|
+
for (const slot of payloadEnvelopes.keys()) slotSet.add(slot);
|
|
132
|
+
}
|
|
133
|
+
const slots = Array.from(slotSet).sort((a, b) => a - b);
|
|
134
|
+
for (const slot of slots) {
|
|
135
|
+
const fullyVerifiedBlock = verifiedBlocksBySlot.get(slot);
|
|
136
|
+
if (fullyVerifiedBlock !== undefined) {
|
|
137
|
+
// TODO: Consider batching importBlock too if it takes significant time
|
|
138
|
+
await importBlock.call(this, fullyVerifiedBlock, opts);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const payloadInput = payloadEnvelopes?.get(slot);
|
|
142
|
+
if (payloadInput?.hasPayloadEnvelope()) {
|
|
143
|
+
if (!payloadInput.isComplete()) {
|
|
144
|
+
// we validated DA before reaching this
|
|
145
|
+
throw new Error(`Payload envelope for slot ${slot} not complete after DA verification`);
|
|
146
|
+
}
|
|
147
|
+
// we already awaited DA in verifyBlocksInEpoch for this segment
|
|
148
|
+
const payloadDA = payloadDAStatuses.get(slot);
|
|
149
|
+
if (payloadDA === undefined) {
|
|
150
|
+
throw new Error(`Missing payload DA status for slot ${slot}`);
|
|
151
|
+
}
|
|
152
|
+
await importExecutionPayload.call(this, payloadInput, payloadDA, {validSignature: false});
|
|
153
|
+
}
|
|
102
154
|
|
|
103
|
-
for (const fullyVerifiedBlock of fullyVerifiedBlocks) {
|
|
104
|
-
// TODO: Consider batching importBlock too if it takes significant time
|
|
105
|
-
await importBlock.call(this, fullyVerifiedBlock, opts);
|
|
106
155
|
await nextEventLoop();
|
|
107
156
|
}
|
|
108
157
|
} catch (e) {
|