@lodestar/beacon-node 1.43.0-dev.2870b59b6a → 1.43.0-dev.2fba242f5d
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 +17 -9
- 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 +45 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -2
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/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 +67 -5
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/GetBlobsTracker.d.ts +1 -1
- package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
- package/lib/chain/GetBlobsTracker.js +1 -2
- package/lib/chain/GetBlobsTracker.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +4 -4
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
- 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 +45 -49
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +28 -14
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +88 -88
- 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 +59 -26
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +4 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +25 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +7 -5
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +16 -21
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +89 -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 +24 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +30 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -6
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +35 -36
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +16 -15
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +5 -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 +5 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -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/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 +33 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/errors/proposerPreferences.js +13 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -0
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +11 -15
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +7 -5
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +26 -4
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +47 -23
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +12 -8
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +67 -25
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/errors.d.ts +1 -11
- package/lib/chain/regen/errors.d.ts.map +1 -1
- package/lib/chain/regen/errors.js +0 -2
- package/lib/chain/regen/errors.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +7 -11
- 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 +6 -10
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +4 -14
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +0 -5
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +1 -12
- 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 +19 -6
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +40 -22
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts +15 -0
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
- package/lib/chain/seenCache/seenProposerPreferences.js +25 -0
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -7
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -9
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +0 -6
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- 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 +13 -1
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +20 -10
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +4 -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 +69 -0
- package/lib/chain/validation/proposerPreferences.js.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +21 -14
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +1 -0
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +6 -0
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +20 -0
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +18 -0
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +1 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +4 -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 +11 -2
- 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 +1 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +6 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +46 -22
- 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/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/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +6 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/batch.d.ts +23 -2
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +84 -33
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +6 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +26 -7
- 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 +17 -6
- package/lib/sync/range/range.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 +22 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +602 -53
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +46 -10
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +164 -24
- 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/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +16 -3
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +17 -16
- package/src/api/impl/beacon/blocks/index.ts +22 -9
- package/src/api/impl/beacon/pool/index.ts +83 -1
- package/src/api/impl/beacon/state/utils.ts +2 -2
- 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 +83 -6
- package/src/chain/GetBlobsTracker.ts +1 -2
- package/src/chain/archiveStore/archiveStore.ts +5 -5
- package/src/chain/archiveStore/interface.ts +4 -4
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
- package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
- package/src/chain/blocks/importBlock.ts +46 -73
- package/src/chain/blocks/importExecutionPayload.ts +109 -101
- package/src/chain/blocks/index.ts +74 -24
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +33 -1
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +7 -6
- package/src/chain/blocks/types.ts +16 -26
- package/src/chain/blocks/utils/chainSegment.ts +114 -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 +129 -0
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +41 -0
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
- package/src/chain/chain.ts +51 -51
- package/src/chain/emitter.ts +15 -14
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/executionPayloadBid.ts +6 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/errors/proposerPreferences.ts +39 -0
- package/src/chain/forkChoice/index.ts +8 -20
- package/src/chain/interface.ts +11 -3
- package/src/chain/opPools/payloadAttestationPool.ts +29 -8
- package/src/chain/prepareNextSlot.ts +55 -24
- package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
- package/src/chain/produceBlock/produceBlockBody.ts +89 -27
- package/src/chain/regen/errors.ts +1 -6
- package/src/chain/regen/interface.ts +7 -11
- package/src/chain/regen/queued.ts +8 -21
- package/src/chain/regen/regen.ts +2 -15
- package/src/chain/seenCache/index.ts +1 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +47 -25
- package/src/chain/seenCache/seenProposerPreferences.ts +29 -0
- package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
- package/src/chain/stateCache/types.ts +0 -3
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/executionPayloadBid.ts +14 -0
- package/src/chain/validation/executionPayloadEnvelope.ts +21 -11
- package/src/chain/validation/payloadAttestationMessage.ts +5 -3
- package/src/chain/validation/proposerPreferences.ts +91 -0
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
- package/src/execution/engine/http.ts +21 -14
- package/src/execution/engine/interface.ts +1 -0
- package/src/execution/engine/mock.ts +8 -1
- package/src/execution/engine/types.ts +41 -0
- package/src/metrics/metrics/lodestar.ts +4 -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 +1 -0
- package/src/network/network.ts +12 -1
- package/src/network/processor/gossipHandlers.ts +61 -27
- package/src/network/processor/gossipQueues/index.ts +5 -0
- package/src/network/processor/index.ts +6 -5
- 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/node/nodejs.ts +6 -4
- package/src/sync/range/batch.ts +142 -38
- package/src/sync/range/chain.ts +37 -9
- package/src/sync/range/range.ts +18 -6
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +760 -57
- package/src/sync/utils/downloadByRange.ts +274 -39
- package/src/sync/utils/downloadByRoot.ts +24 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
- package/src/util/sszBytes.ts +21 -3
|
@@ -46,8 +46,7 @@ type VerifyBlockExecutionResponse =
|
|
|
46
46
|
| VerifyExecutionErrorResponse
|
|
47
47
|
| {executionStatus: ExecutionStatus.Valid; lvhResponse: LVHValidResponse; execError: null}
|
|
48
48
|
| {executionStatus: ExecutionStatus.Syncing; lvhResponse?: LVHValidResponse; execError: null}
|
|
49
|
-
| {executionStatus: ExecutionStatus.PreMerge; lvhResponse: undefined; execError: null}
|
|
50
|
-
| {executionStatus: ExecutionStatus.PayloadSeparated; lvhResponse: undefined; execError: null};
|
|
49
|
+
| {executionStatus: ExecutionStatus.PreMerge; lvhResponse: undefined; execError: null};
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
52
|
* Verifies 1 or more execution payloads from a linear sequence of blocks.
|
|
@@ -145,9 +144,10 @@ export async function verifyBlockExecutionPayload(
|
|
|
145
144
|
): Promise<VerifyBlockExecutionResponse> {
|
|
146
145
|
const block = blockInput.getBlock();
|
|
147
146
|
|
|
148
|
-
// Gloas block doesn't have execution payload. Return
|
|
147
|
+
// Gloas block doesn't have execution payload. Return Syncing as a placeholder; the actual
|
|
148
|
+
// status for gloas PENDING/EMPTY is derived from parent's chain in importBlock.
|
|
149
149
|
if (isBlockInputNoData(blockInput)) {
|
|
150
|
-
return {executionStatus: ExecutionStatus.
|
|
150
|
+
return {executionStatus: ExecutionStatus.Syncing, lvhResponse: undefined, execError: null};
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/** Not null if execution is enabled */
|
|
@@ -198,6 +198,7 @@ export async function verifyBlockExecutionPayload(
|
|
|
198
198
|
executionStatus,
|
|
199
199
|
latestValidExecHash: execResult.latestValidHash,
|
|
200
200
|
invalidateFromParentBlockRoot: blockInput.parentRootHex,
|
|
201
|
+
invalidateFromParentBlockHash: toRootHex(executionPayloadEnabled.parentHash),
|
|
201
202
|
};
|
|
202
203
|
const execError = new BlockError(block, {
|
|
203
204
|
code: BlockErrorCode.EXECUTION_ENGINE_ERROR,
|
|
@@ -281,6 +282,7 @@ function getSegmentErrorResponse(
|
|
|
281
282
|
executionStatus: ExecutionStatus.Invalid,
|
|
282
283
|
latestValidExecHash: lvhResponse.latestValidExecHash,
|
|
283
284
|
invalidateFromParentBlockRoot: parentBlock.blockRoot,
|
|
285
|
+
invalidateFromParentBlockHash: parentBlock.executionPayloadBlockHash,
|
|
284
286
|
};
|
|
285
287
|
}
|
|
286
288
|
}
|
|
@@ -7,6 +7,7 @@ import {IClock} from "../../util/clock.js";
|
|
|
7
7
|
import {BlockError, BlockErrorCode} from "../errors/index.js";
|
|
8
8
|
import {IChainOptions} from "../options.js";
|
|
9
9
|
import {IBlockInput} from "./blockInput/types.js";
|
|
10
|
+
import {PayloadEnvelopeInput} from "./payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
10
11
|
import {ImportBlockOpts} from "./types.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -30,6 +31,7 @@ export function verifyBlocksSanityChecks(
|
|
|
30
31
|
blacklistedBlocks: Map<RootHex, Slot | null>;
|
|
31
32
|
},
|
|
32
33
|
blocks: IBlockInput[],
|
|
34
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
33
35
|
opts: ImportBlockOpts
|
|
34
36
|
): {
|
|
35
37
|
relevantBlocks: IBlockInput[];
|
|
@@ -90,15 +92,32 @@ export function verifyBlocksSanityChecks(
|
|
|
90
92
|
} else {
|
|
91
93
|
// When importing a block segment, only the first NON-IGNORED block must be known to the fork-choice.
|
|
92
94
|
const parentRoot = toRootHex(block.message.parentRoot);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
parentRoot,
|
|
96
|
-
toRootHex(block.message.body.signedExecutionPayloadBid.message.parentBlockHash)
|
|
97
|
-
)
|
|
98
|
-
: chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
99
|
-
if (!parentBlock) {
|
|
95
|
+
const parentBlockDefaultStatus = chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
96
|
+
if (!parentBlockDefaultStatus) {
|
|
100
97
|
throw new BlockError(block, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
|
|
101
98
|
}
|
|
99
|
+
|
|
100
|
+
parentBlock = parentBlockDefaultStatus;
|
|
101
|
+
if (isGloasBeaconBlock(block.message)) {
|
|
102
|
+
const parentBlockHash = toRootHex(block.message.body.signedExecutionPayloadBid.message.parentBlockHash);
|
|
103
|
+
const parentBlockWithPayload = chain.forkChoice.getBlockHexAndBlockHash(parentRoot, parentBlockHash);
|
|
104
|
+
if (!parentBlockWithPayload) {
|
|
105
|
+
// Checkpoint sync: parent's FULL variant may not be in fork-choice yet because the
|
|
106
|
+
// anchor block is initialized with PENDING+EMPTY only. The parent's payload arrives
|
|
107
|
+
// in the same batch via payloadEnvelopes and will be imported by processBlocks. If
|
|
108
|
+
// a matching payload is in the Map, accept the parent as known.
|
|
109
|
+
const parentPayloadInput = payloadEnvelopes?.get(parentBlockDefaultStatus.slot);
|
|
110
|
+
if (parentPayloadInput?.getBlockHashHex() !== parentBlockHash) {
|
|
111
|
+
throw new BlockError(block, {
|
|
112
|
+
code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
|
|
113
|
+
parentRoot,
|
|
114
|
+
parentBlockHash,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
parentBlock = parentBlockWithPayload;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
102
121
|
// Parent is known to the fork-choice
|
|
103
122
|
parentBlockSlot = parentBlock.slot;
|
|
104
123
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
+
import {
|
|
3
|
+
type IBeaconStateViewGloas,
|
|
4
|
+
type PubkeyCache,
|
|
5
|
+
computeTimeAtSlot,
|
|
6
|
+
getExecutionPayloadEnvelopeSignatureSet,
|
|
7
|
+
} from "@lodestar/state-transition";
|
|
8
|
+
import {gloas, ssz} from "@lodestar/types";
|
|
9
|
+
import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
|
|
10
|
+
import {IBlsVerifier} from "../bls/index.js";
|
|
11
|
+
|
|
12
|
+
export type VerifyExecutionPayloadEnvelopeOpts = {
|
|
13
|
+
verifyExecutionRequestsRoot?: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Verify execution payload envelope fields against the post-block state.
|
|
18
|
+
*
|
|
19
|
+
* Signature verification and the execution engine call (`verify_and_notify_new_payload`) are
|
|
20
|
+
* performed outside this function, see `verifyExecutionPayloadEnvelopeSignature` and
|
|
21
|
+
* `importExecutionPayload` which run both in parallel with this check.
|
|
22
|
+
*
|
|
23
|
+
* Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/fork-choice.md#new-verify_execution_payload_envelope
|
|
24
|
+
*/
|
|
25
|
+
export function verifyExecutionPayloadEnvelope(
|
|
26
|
+
config: BeaconConfig,
|
|
27
|
+
state: IBeaconStateViewGloas,
|
|
28
|
+
envelope: gloas.ExecutionPayloadEnvelope,
|
|
29
|
+
opts?: VerifyExecutionPayloadEnvelopeOpts
|
|
30
|
+
): void {
|
|
31
|
+
const {verifyExecutionRequestsRoot = true} = opts ?? {};
|
|
32
|
+
const payload = envelope.payload;
|
|
33
|
+
|
|
34
|
+
// Verify consistency with the beacon block.
|
|
35
|
+
// Compute header root on a clone of latestBlockHeader to avoid mutating state.
|
|
36
|
+
const headerValue = ssz.phase0.BeaconBlockHeader.clone(state.latestBlockHeader);
|
|
37
|
+
if (byteArrayEquals(headerValue.stateRoot, ssz.Root.defaultValue())) {
|
|
38
|
+
headerValue.stateRoot = state.hashTreeRoot();
|
|
39
|
+
}
|
|
40
|
+
const headerRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(headerValue);
|
|
41
|
+
if (!byteArrayEquals(envelope.beaconBlockRoot, headerRoot)) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Envelope's block is not the latest block header envelope=${toRootHex(envelope.beaconBlockRoot)} latestBlockHeader=${toRootHex(headerRoot)}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Verify consistency with the committed bid
|
|
48
|
+
const bid = state.latestExecutionPayloadBid;
|
|
49
|
+
if (envelope.builderIndex !== bid.builderIndex) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Builder index mismatch between envelope and committed bid envelope=${envelope.builderIndex} bid=${bid.builderIndex}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
if (!byteArrayEquals(bid.prevRandao, payload.prevRandao)) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
`Prev randao mismatch between bid and payload bid=${toHex(bid.prevRandao)} payload=${toHex(payload.prevRandao)}`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if (Number(bid.gasLimit) !== payload.gasLimit) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Gas limit mismatch between payload and bid payload=${payload.gasLimit} bid=${Number(bid.gasLimit)}`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
if (!byteArrayEquals(bid.blockHash, payload.blockHash)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Block hash mismatch between payload and bid payload=${toRootHex(payload.blockHash)} bid=${toRootHex(bid.blockHash)}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
// Verify execution_requests_root matches bid commitment.
|
|
70
|
+
// Can be skipped if already verified during gossip validation.
|
|
71
|
+
if (verifyExecutionRequestsRoot) {
|
|
72
|
+
const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
|
|
73
|
+
if (!byteArrayEquals(requestsRoot, bid.executionRequestsRoot)) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Execution requests root mismatch envelope=${toRootHex(requestsRoot)} bid=${toRootHex(bid.executionRequestsRoot)}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Verify the execution payload is valid
|
|
81
|
+
if (payload.slotNumber !== state.slot) {
|
|
82
|
+
throw new Error(`Slot mismatch between payload and state payload=${payload.slotNumber} state=${state.slot}`);
|
|
83
|
+
}
|
|
84
|
+
if (!byteArrayEquals(payload.parentHash, state.latestBlockHash)) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Parent hash mismatch between payload and state payload=${toRootHex(payload.parentHash)} state=${toRootHex(state.latestBlockHash)}`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const expectedTimestamp = computeTimeAtSlot(config, state.slot, state.genesisTime);
|
|
90
|
+
if (payload.timestamp !== expectedTimestamp) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Timestamp mismatch between payload and state payload=${payload.timestamp} state=${expectedTimestamp}`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Verify consistency with expected withdrawals
|
|
97
|
+
const payloadWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
|
|
98
|
+
const expectedWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(state.payloadExpectedWithdrawals);
|
|
99
|
+
if (!byteArrayEquals(payloadWithdrawalsRoot, expectedWithdrawalsRoot)) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Withdrawals mismatch between payload and expected payload=${toRootHex(payloadWithdrawalsRoot)} expected=${toRootHex(expectedWithdrawalsRoot)}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Execution engine verification (verify_and_notify_new_payload) is done externally by the caller
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Verify the BLS signature of an execution payload envelope.
|
|
110
|
+
*
|
|
111
|
+
* Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/fork-choice.md#new-verify_execution_payload_envelope_signature
|
|
112
|
+
*/
|
|
113
|
+
export async function verifyExecutionPayloadEnvelopeSignature(
|
|
114
|
+
config: BeaconConfig,
|
|
115
|
+
state: IBeaconStateViewGloas,
|
|
116
|
+
pubkeyCache: PubkeyCache,
|
|
117
|
+
signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
|
|
118
|
+
proposerIndex: number,
|
|
119
|
+
bls: IBlsVerifier
|
|
120
|
+
): Promise<boolean> {
|
|
121
|
+
const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
|
|
122
|
+
config,
|
|
123
|
+
pubkeyCache,
|
|
124
|
+
state,
|
|
125
|
+
signedEnvelope,
|
|
126
|
+
proposerIndex
|
|
127
|
+
);
|
|
128
|
+
return bls.verifySignatureSets([signatureSet]);
|
|
129
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {DataAvailabilityStatus} from "@lodestar/state-transition";
|
|
2
|
+
import {gloas} from "@lodestar/types";
|
|
3
|
+
import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
|
|
4
|
+
|
|
5
|
+
// we can now wait for full 12 seconds because sync and reconstruction will try pulling
|
|
6
|
+
// the data columns from the network anyway while the envelope is being processed
|
|
7
|
+
export const PAYLOAD_DATA_AVAILABILITY_TIMEOUT = 12_000;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Verifies that all payload envelope inputs have their data columns available.
|
|
11
|
+
* - Waits a max of PAYLOAD_DATA_AVAILABILITY_TIMEOUT for all data to be available
|
|
12
|
+
* - Returns the time at which all data was available
|
|
13
|
+
* - Returns the data availability status for each payload input
|
|
14
|
+
*/
|
|
15
|
+
export async function verifyPayloadsDataAvailability(
|
|
16
|
+
payloadInputs: PayloadEnvelopeInput[],
|
|
17
|
+
signal: AbortSignal
|
|
18
|
+
): Promise<{
|
|
19
|
+
dataAvailabilityStatuses: DataAvailabilityStatus[];
|
|
20
|
+
availableTime: number;
|
|
21
|
+
}> {
|
|
22
|
+
const promises: Promise<gloas.DataColumnSidecar[]>[] = [];
|
|
23
|
+
for (const payloadInput of payloadInputs) {
|
|
24
|
+
if (!payloadInput.hasAllData()) {
|
|
25
|
+
promises.push(payloadInput.waitForAllData(PAYLOAD_DATA_AVAILABILITY_TIMEOUT, signal));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
await Promise.all(promises);
|
|
29
|
+
|
|
30
|
+
const availableTime = Math.max(0, Math.max(...payloadInputs.map((payloadInput) => payloadInput.getTimeComplete())));
|
|
31
|
+
const dataAvailabilityStatuses: DataAvailabilityStatus[] = payloadInputs.map((payloadInput) => {
|
|
32
|
+
if (payloadInput.daOutOfRange) {
|
|
33
|
+
return DataAvailabilityStatus.OutOfRange;
|
|
34
|
+
}
|
|
35
|
+
return payloadInput.getBlobKzgCommitments().length === 0
|
|
36
|
+
? DataAvailabilityStatus.NotRequired
|
|
37
|
+
: DataAvailabilityStatus.Available;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return {dataAvailabilityStatuses, availableTime};
|
|
41
|
+
}
|
|
@@ -5,7 +5,7 @@ import {writeDataColumnsToDb} from "./writeBlockInputToDb.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Persists payload envelope data to DB. This operation must be eventually completed if a payload is imported.
|
|
7
7
|
*
|
|
8
|
-
* TODO GLOAS: Persist envelope metadata (
|
|
8
|
+
* TODO GLOAS: Persist envelope metadata (executionRequests, builderIndex, etc.) without the full
|
|
9
9
|
* execution payload body — only keep the blockHash reference. The EL already stores the payload.
|
|
10
10
|
* See https://github.com/ChainSafe/lodestar/issues/5671
|
|
11
11
|
*/
|
|
@@ -33,23 +33,14 @@ export async function persistPayloadEnvelopeInput(
|
|
|
33
33
|
this: BeaconChain,
|
|
34
34
|
payloadInput: PayloadEnvelopeInput
|
|
35
35
|
): Promise<void> {
|
|
36
|
-
await writePayloadEnvelopeInputToDb
|
|
37
|
-
.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"Error persisting payload envelope in hot db",
|
|
41
|
-
{
|
|
42
|
-
slot: payloadInput.slot,
|
|
43
|
-
root: payloadInput.blockRootHex,
|
|
44
|
-
},
|
|
45
|
-
e
|
|
46
|
-
);
|
|
47
|
-
})
|
|
48
|
-
.finally(() => {
|
|
49
|
-
this.seenPayloadEnvelopeInputCache.prune(payloadInput.blockRootHex);
|
|
50
|
-
this.logger.debug("Pruned payload envelope input", {
|
|
36
|
+
await writePayloadEnvelopeInputToDb.call(this, payloadInput).catch((e) => {
|
|
37
|
+
this.logger.error(
|
|
38
|
+
"Error persisting payload envelope in hot db",
|
|
39
|
+
{
|
|
51
40
|
slot: payloadInput.slot,
|
|
52
41
|
root: payloadInput.blockRootHex,
|
|
53
|
-
}
|
|
54
|
-
|
|
42
|
+
},
|
|
43
|
+
e
|
|
44
|
+
);
|
|
45
|
+
});
|
|
55
46
|
}
|
package/src/chain/chain.ts
CHANGED
|
@@ -2,10 +2,9 @@ import path from "node:path";
|
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {Type} from "@chainsafe/ssz";
|
|
4
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
5
|
-
import {
|
|
5
|
+
import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
|
|
6
6
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
7
7
|
import {
|
|
8
|
-
BUILDER_INDEX_SELF_BUILD,
|
|
9
8
|
EFFECTIVE_BALANCE_INCREMENT,
|
|
10
9
|
type ForkPostFulu,
|
|
11
10
|
type ForkPostGloas,
|
|
@@ -24,7 +23,6 @@ import {
|
|
|
24
23
|
getEffectiveBalancesFromStateBytes,
|
|
25
24
|
isStatePostAltair,
|
|
26
25
|
isStatePostElectra,
|
|
27
|
-
isStatePostGloas,
|
|
28
26
|
} from "@lodestar/state-transition";
|
|
29
27
|
import {
|
|
30
28
|
BeaconBlock,
|
|
@@ -41,6 +39,7 @@ import {
|
|
|
41
39
|
ValidatorIndex,
|
|
42
40
|
Wei,
|
|
43
41
|
deneb,
|
|
42
|
+
electra,
|
|
44
43
|
gloas,
|
|
45
44
|
isBlindedBeaconBlock,
|
|
46
45
|
phase0,
|
|
@@ -93,8 +92,8 @@ import {
|
|
|
93
92
|
} from "./opPools/index.js";
|
|
94
93
|
import {IChainOptions} from "./options.js";
|
|
95
94
|
import {PrepareNextSlotScheduler} from "./prepareNextSlot.js";
|
|
96
|
-
import {computeNewStateRoot
|
|
97
|
-
import {AssembledBlockType, BlockType,
|
|
95
|
+
import {computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
|
|
96
|
+
import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index.js";
|
|
98
97
|
import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
|
|
99
98
|
import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
100
99
|
import {ReprocessController} from "./reprocess.js";
|
|
@@ -107,6 +106,7 @@ import {
|
|
|
107
106
|
SeenExecutionPayloadBids,
|
|
108
107
|
SeenPayloadAttesters,
|
|
109
108
|
SeenPayloadEnvelopeInput,
|
|
109
|
+
SeenProposerPreferences,
|
|
110
110
|
SeenSyncCommitteeMessages,
|
|
111
111
|
} from "./seenCache/index.js";
|
|
112
112
|
import {SeenAggregatedAttestations} from "./seenCache/seenAggregateAndProof.js";
|
|
@@ -118,7 +118,7 @@ import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datasto
|
|
|
118
118
|
import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
|
|
119
119
|
import {CPStateDatastore} from "./stateCache/datastore/types.js";
|
|
120
120
|
import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
|
|
121
|
-
import {PersistentCheckpointStateCache
|
|
121
|
+
import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
|
|
122
122
|
import {CheckpointStateCache} from "./stateCache/types.js";
|
|
123
123
|
import {ValidatorMonitor} from "./validatorMonitor.js";
|
|
124
124
|
|
|
@@ -187,6 +187,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
187
187
|
readonly seenPayloadAttesters = new SeenPayloadAttesters();
|
|
188
188
|
readonly seenAggregatedAttestations: SeenAggregatedAttestations;
|
|
189
189
|
readonly seenExecutionPayloadBids = new SeenExecutionPayloadBids();
|
|
190
|
+
readonly seenProposerPreferences = new SeenProposerPreferences();
|
|
190
191
|
readonly seenBlockProposers = new SeenBlockProposers();
|
|
191
192
|
readonly seenSyncCommitteeMessages = new SeenSyncCommitteeMessages();
|
|
192
193
|
readonly seenContributionAndProof: SeenContributionAndProof;
|
|
@@ -335,6 +336,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
335
336
|
logger,
|
|
336
337
|
});
|
|
337
338
|
this.seenPayloadEnvelopeInputCache = new SeenPayloadEnvelopeInput({
|
|
339
|
+
config,
|
|
340
|
+
clock,
|
|
338
341
|
chainEvents: emitter,
|
|
339
342
|
signal,
|
|
340
343
|
serializedCache: this.serializedCache,
|
|
@@ -682,11 +685,11 @@ export class BeaconChain implements IBeaconChain {
|
|
|
682
685
|
}
|
|
683
686
|
|
|
684
687
|
getStateByCheckpoint(
|
|
685
|
-
checkpoint:
|
|
688
|
+
checkpoint: CheckpointWithHex
|
|
686
689
|
): {state: IBeaconStateView; executionOptimistic: boolean; finalized: boolean} | null {
|
|
687
690
|
// finalized or justified checkpoint states maynot be available with PersistentCheckpointStateCache, use getCheckpointStateOrBytes() api to get Uint8Array
|
|
688
|
-
const
|
|
689
|
-
const cachedStateCtx = this.regen.getCheckpointStateSync(
|
|
691
|
+
const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
|
|
692
|
+
const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHex);
|
|
690
693
|
if (cachedStateCtx) {
|
|
691
694
|
const block = this.forkChoice.getBlockDefaultStatus(
|
|
692
695
|
ssz.phase0.BeaconBlockHeader.hashTreeRoot(cachedStateCtx.latestBlockHeader)
|
|
@@ -703,10 +706,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
703
706
|
}
|
|
704
707
|
|
|
705
708
|
async getStateOrBytesByCheckpoint(
|
|
706
|
-
checkpoint:
|
|
709
|
+
checkpoint: CheckpointWithHex
|
|
707
710
|
): Promise<{state: IBeaconStateView | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
|
|
708
|
-
const
|
|
709
|
-
const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(
|
|
711
|
+
const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
|
|
712
|
+
const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHex);
|
|
710
713
|
if (cachedStateCtx) {
|
|
711
714
|
const block = this.forkChoice.getBlockDefaultStatus(checkpoint.root);
|
|
712
715
|
const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
@@ -888,6 +891,21 @@ export class BeaconChain implements IBeaconChain {
|
|
|
888
891
|
);
|
|
889
892
|
}
|
|
890
893
|
|
|
894
|
+
async getParentExecutionRequests(
|
|
895
|
+
parentBlockSlot: Slot,
|
|
896
|
+
parentBlockRootHex: RootHex
|
|
897
|
+
): Promise<electra.ExecutionRequests> {
|
|
898
|
+
// at the fork boundary, parent is pre-gloas
|
|
899
|
+
if (!isForkPostGloas(this.config.getForkName(parentBlockSlot))) {
|
|
900
|
+
return ssz.electra.ExecutionRequests.defaultValue();
|
|
901
|
+
}
|
|
902
|
+
const envelope = await this.getExecutionPayloadEnvelope(parentBlockSlot, parentBlockRootHex);
|
|
903
|
+
if (envelope === null) {
|
|
904
|
+
throw Error(`Parent execution payload envelope not found slot=${parentBlockSlot}, root=${parentBlockRootHex}`);
|
|
905
|
+
}
|
|
906
|
+
return envelope.message.executionRequests;
|
|
907
|
+
}
|
|
908
|
+
|
|
891
909
|
async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecar[]> {
|
|
892
910
|
const fork = this.config.getForkName(blockSlot);
|
|
893
911
|
|
|
@@ -1062,7 +1080,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1062
1080
|
body,
|
|
1063
1081
|
} as AssembledBlockType<T>;
|
|
1064
1082
|
|
|
1065
|
-
const {newStateRoot, proposerReward
|
|
1083
|
+
const {newStateRoot, proposerReward} = computeNewStateRoot(this.metrics, state, block);
|
|
1066
1084
|
block.stateRoot = newStateRoot;
|
|
1067
1085
|
const blockRoot =
|
|
1068
1086
|
produceResult.type === BlockType.Full
|
|
@@ -1071,26 +1089,9 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1071
1089
|
const blockRootHex = toRootHex(blockRoot);
|
|
1072
1090
|
|
|
1073
1091
|
const fork = this.config.getForkName(slot);
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
const gloasResult = produceResult as ProduceFullGloas;
|
|
1081
|
-
const envelope: gloas.ExecutionPayloadEnvelope = {
|
|
1082
|
-
payload: gloasResult.executionPayload,
|
|
1083
|
-
executionRequests: gloasResult.executionRequests,
|
|
1084
|
-
builderIndex: BUILDER_INDEX_SELF_BUILD,
|
|
1085
|
-
beaconBlockRoot: blockRoot,
|
|
1086
|
-
slot,
|
|
1087
|
-
stateRoot: ZERO_HASH,
|
|
1088
|
-
};
|
|
1089
|
-
if (!isStatePostGloas(postBlockState)) {
|
|
1090
|
-
throw Error(`Expected gloas+ post-state for execution payload envelope, got fork=${postBlockState.forkName}`);
|
|
1091
|
-
}
|
|
1092
|
-
const payloadEnvelopeStateRoot = computePayloadEnvelopeStateRoot(this.metrics, postBlockState, envelope);
|
|
1093
|
-
gloasResult.payloadEnvelopeStateRoot = payloadEnvelopeStateRoot;
|
|
1092
|
+
// TODO GLOAS: we should retire BlockType post-gloas, may need a new enum for self vs non-self built
|
|
1093
|
+
if (isForkPostGloas(fork) && produceResult.type !== BlockType.Full) {
|
|
1094
|
+
throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
|
|
1094
1095
|
}
|
|
1095
1096
|
|
|
1096
1097
|
// Track the produced block for consensus broadcast validations, later validation, etc.
|
|
@@ -1101,11 +1102,15 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1101
1102
|
}
|
|
1102
1103
|
|
|
1103
1104
|
async processBlock(block: IBlockInput, opts?: ImportBlockOpts): Promise<void> {
|
|
1104
|
-
return this.blockProcessor.processBlocksJob([block], opts);
|
|
1105
|
+
return this.blockProcessor.processBlocksJob([block], null, opts);
|
|
1105
1106
|
}
|
|
1106
1107
|
|
|
1107
|
-
async processChainSegment(
|
|
1108
|
-
|
|
1108
|
+
async processChainSegment(
|
|
1109
|
+
blocks: IBlockInput[],
|
|
1110
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
1111
|
+
opts?: ImportBlockOpts
|
|
1112
|
+
): Promise<void> {
|
|
1113
|
+
await this.blockProcessor.processBlocksJob(blocks, payloadEnvelopes, opts);
|
|
1109
1114
|
}
|
|
1110
1115
|
|
|
1111
1116
|
async processExecutionPayload(payloadInput: PayloadEnvelopeInput, opts?: ImportPayloadOpts): Promise<void> {
|
|
@@ -1296,7 +1301,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1296
1301
|
* @param blockState state that declares justified checkpoint `checkpoint`
|
|
1297
1302
|
*/
|
|
1298
1303
|
private justifiedBalancesGetter(
|
|
1299
|
-
checkpoint:
|
|
1304
|
+
checkpoint: CheckpointWithHex,
|
|
1300
1305
|
blockState: IBeaconStateView
|
|
1301
1306
|
): EffectiveBalanceIncrements {
|
|
1302
1307
|
this.metrics?.balancesCache.requests.inc();
|
|
@@ -1335,11 +1340,11 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1335
1340
|
* @param blockState state that declares justified checkpoint `checkpoint`
|
|
1336
1341
|
*/
|
|
1337
1342
|
private closestJustifiedBalancesStateToCheckpoint(
|
|
1338
|
-
checkpoint:
|
|
1343
|
+
checkpoint: CheckpointWithHex,
|
|
1339
1344
|
blockState: IBeaconStateView
|
|
1340
1345
|
): {state: IBeaconStateView; stateId: string; shouldWarn: boolean} {
|
|
1341
|
-
const
|
|
1342
|
-
const state = this.regen.getCheckpointStateSync(
|
|
1346
|
+
const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
|
|
1347
|
+
const state = this.regen.getCheckpointStateSync(checkpointHex);
|
|
1343
1348
|
if (state) {
|
|
1344
1349
|
return {state, stateId: "checkpoint_state", shouldWarn: false};
|
|
1345
1350
|
}
|
|
@@ -1350,10 +1355,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1350
1355
|
}
|
|
1351
1356
|
|
|
1352
1357
|
// Find a state in the same branch of checkpoint at same epoch. Balances should exactly the same
|
|
1353
|
-
for (const descendantBlock of this.forkChoice.
|
|
1354
|
-
checkpoint.rootHex,
|
|
1355
|
-
checkpoint.payloadStatus
|
|
1356
|
-
)) {
|
|
1358
|
+
for (const descendantBlock of this.forkChoice.forwardIterateDescendantsDefaultStatus(checkpoint.rootHex)) {
|
|
1357
1359
|
if (computeEpochAtSlot(descendantBlock.slot) === checkpoint.epoch) {
|
|
1358
1360
|
const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
|
|
1359
1361
|
if (descendantBlockState) {
|
|
@@ -1369,10 +1371,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1369
1371
|
|
|
1370
1372
|
// Find a state in the same branch of checkpoint at a latter epoch. Balances are not the same, but should be close
|
|
1371
1373
|
// Note: must call .forwardIterateDescendants() again since nodes are not sorted
|
|
1372
|
-
for (const descendantBlock of this.forkChoice.
|
|
1373
|
-
checkpoint.rootHex,
|
|
1374
|
-
checkpoint.payloadStatus
|
|
1375
|
-
)) {
|
|
1374
|
+
for (const descendantBlock of this.forkChoice.forwardIterateDescendantsDefaultStatus(checkpoint.rootHex)) {
|
|
1376
1375
|
if (computeEpochAtSlot(descendantBlock.slot) > checkpoint.epoch) {
|
|
1377
1376
|
const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
|
|
1378
1377
|
if (descendantBlockState) {
|
|
@@ -1442,6 +1441,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1442
1441
|
this.payloadAttestationPool.prune(slot);
|
|
1443
1442
|
this.executionPayloadBidPool.prune(slot);
|
|
1444
1443
|
this.seenExecutionPayloadBids.prune(slot);
|
|
1444
|
+
this.seenProposerPreferences.prune(slot);
|
|
1445
1445
|
this.seenAttestationDatas.onSlot(slot);
|
|
1446
1446
|
this.reprocessController.onSlot(slot);
|
|
1447
1447
|
|
|
@@ -1476,7 +1476,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1476
1476
|
this.seenContributionAndProof.prune(head.slot);
|
|
1477
1477
|
}
|
|
1478
1478
|
|
|
1479
|
-
private onForkChoiceJustified(this: BeaconChain, cp:
|
|
1479
|
+
private onForkChoiceJustified(this: BeaconChain, cp: CheckpointWithHex): void {
|
|
1480
1480
|
this.logger.verbose("Fork choice justified", {epoch: cp.epoch, root: cp.rootHex});
|
|
1481
1481
|
}
|
|
1482
1482
|
|
|
@@ -1487,7 +1487,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1487
1487
|
});
|
|
1488
1488
|
}
|
|
1489
1489
|
|
|
1490
|
-
private async onForkChoiceFinalized(this: BeaconChain, cp:
|
|
1490
|
+
private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithHex): Promise<void> {
|
|
1491
1491
|
this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
|
|
1492
1492
|
const finalizedSlot = computeStartSlotAtEpoch(cp.epoch);
|
|
1493
1493
|
this.seenBlockProposers.prune(finalizedSlot);
|
|
@@ -1528,7 +1528,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1528
1528
|
}
|
|
1529
1529
|
}
|
|
1530
1530
|
|
|
1531
|
-
private async updateValidatorsCustodyRequirement(finalizedCheckpoint:
|
|
1531
|
+
private async updateValidatorsCustodyRequirement(finalizedCheckpoint: CheckpointWithHex): Promise<void> {
|
|
1532
1532
|
if (this.custodyConfig.targetCustodyGroupCount === this.config.NUMBER_OF_CUSTODY_GROUPS) {
|
|
1533
1533
|
// Custody requirements can only be increased, we can disable dynamic custody updates
|
|
1534
1534
|
// if the node already maintains custody of all custody groups in case it is configured
|
package/src/chain/emitter.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {EventEmitter} from "node:events";
|
|
2
2
|
import {StrictEventEmitter} from "strict-event-emitter-types";
|
|
3
3
|
import {routes} from "@lodestar/api";
|
|
4
|
-
import {
|
|
4
|
+
import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
5
5
|
import {IBeaconStateView} from "@lodestar/state-transition";
|
|
6
6
|
import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
|
|
7
|
-
import {SignedExecutionPayloadEnvelope} from "@lodestar/types/gloas";
|
|
8
7
|
import {PeerIdStr} from "../util/peerId.js";
|
|
9
8
|
import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
|
|
9
|
+
import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Important chain events that occur during normal chain operation.
|
|
@@ -59,10 +59,6 @@ export enum ChainEvent {
|
|
|
59
59
|
* Post-gloas, missing parent could be a SignedBeaconBlock and/or a SignedExecutionPayloadEnvelope
|
|
60
60
|
*/
|
|
61
61
|
blockUnknownParent = "blockUnknownParent",
|
|
62
|
-
/**
|
|
63
|
-
* Trigger BlockInputSync to find a SignedBeaconBlock given a SignedExecutionPayloadEnvelop received
|
|
64
|
-
*/
|
|
65
|
-
envelopeUnknownBlock = "envelopeUnknownBlock",
|
|
66
62
|
/**
|
|
67
63
|
* Trigger BlockInputSync to find a SignedBeaconBlock with specified block root.
|
|
68
64
|
*/
|
|
@@ -76,6 +72,11 @@ export enum ChainEvent {
|
|
|
76
72
|
* cut-off window passes for waiting on gossip
|
|
77
73
|
*/
|
|
78
74
|
incompleteBlockInput = "incompleteBlockInput",
|
|
75
|
+
/**
|
|
76
|
+
* Post-gloas: trigger BlockInputSync for payload envelopes whose envelope and/or sampled columns are partially
|
|
77
|
+
* received via gossip but are not complete by time the cut-off window passes for waiting on gossip
|
|
78
|
+
*/
|
|
79
|
+
incompletePayloadEnvelope = "incompletePayloadEnvelope",
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
export type HeadEventData = routes.events.EventData[routes.events.EventType.head];
|
|
@@ -86,21 +87,21 @@ type ApiEvents = {[K in routes.events.EventType]: (data: routes.events.EventData
|
|
|
86
87
|
|
|
87
88
|
export type ChainEventData = {
|
|
88
89
|
[ChainEvent.blockUnknownParent]: {blockInput: IBlockInput; peer: PeerIdStr; source: BlockInputSource};
|
|
89
|
-
[ChainEvent.envelopeUnknownBlock]: {
|
|
90
|
-
envelope: SignedExecutionPayloadEnvelope;
|
|
91
|
-
peer?: PeerIdStr;
|
|
92
|
-
source: BlockInputSource;
|
|
93
|
-
};
|
|
94
90
|
[ChainEvent.unknownBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
|
|
95
91
|
[ChainEvent.incompleteBlockInput]: {blockInput: IBlockInput; peer: PeerIdStr; source: BlockInputSource};
|
|
92
|
+
[ChainEvent.incompletePayloadEnvelope]: {
|
|
93
|
+
payloadInput: PayloadEnvelopeInput;
|
|
94
|
+
peer: PeerIdStr;
|
|
95
|
+
source: BlockInputSource;
|
|
96
|
+
};
|
|
96
97
|
[ChainEvent.unknownEnvelopeBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
export type IChainEvents = ApiEvents & {
|
|
100
101
|
[ChainEvent.checkpoint]: (checkpoint: phase0.Checkpoint, state: IBeaconStateView) => void;
|
|
101
102
|
|
|
102
|
-
[ChainEvent.forkChoiceJustified]: (checkpoint:
|
|
103
|
-
[ChainEvent.forkChoiceFinalized]: (checkpoint:
|
|
103
|
+
[ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithHex) => void;
|
|
104
|
+
[ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithHex) => void;
|
|
104
105
|
|
|
105
106
|
[ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
|
|
106
107
|
|
|
@@ -113,9 +114,9 @@ export type IChainEvents = ApiEvents & {
|
|
|
113
114
|
// Sync events that are chain->chain. Initiated from network requests but do not cross the network
|
|
114
115
|
// barrier so are considered ChainEvent(s).
|
|
115
116
|
[ChainEvent.blockUnknownParent]: (data: ChainEventData[ChainEvent.blockUnknownParent]) => void;
|
|
116
|
-
[ChainEvent.envelopeUnknownBlock]: (data: ChainEventData[ChainEvent.envelopeUnknownBlock]) => void;
|
|
117
117
|
[ChainEvent.unknownBlockRoot]: (data: ChainEventData[ChainEvent.unknownBlockRoot]) => void;
|
|
118
118
|
[ChainEvent.incompleteBlockInput]: (data: ChainEventData[ChainEvent.incompleteBlockInput]) => void;
|
|
119
|
+
[ChainEvent.incompletePayloadEnvelope]: (data: ChainEventData[ChainEvent.incompletePayloadEnvelope]) => void;
|
|
119
120
|
[ChainEvent.unknownEnvelopeBlockRoot]: (data: ChainEventData[ChainEvent.unknownEnvelopeBlockRoot]) => void;
|
|
120
121
|
};
|
|
121
122
|
|
|
@@ -74,6 +74,8 @@ export enum BlockErrorCode {
|
|
|
74
74
|
PARENT_EXECUTION_INVALID = "BLOCK_ERROR_PARENT_EXECUTION_INVALID",
|
|
75
75
|
/** The block's parent execution payload (defined by bid.parent_block_hash) has not been seen */
|
|
76
76
|
PARENT_PAYLOAD_UNKNOWN = "BLOCK_ERROR_PARENT_PAYLOAD_UNKNOWN",
|
|
77
|
+
/** An execution payload envelope in the chain segment references a block root that does not match its slot's block */
|
|
78
|
+
ENVELOPE_BLOCK_ROOT_MISMATCH = "BLOCK_ERROR_ENVELOPE_BLOCK_ROOT_MISMATCH",
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
type ExecutionErrorStatus = Exclude<
|
|
@@ -107,6 +109,7 @@ export type BlockErrorType =
|
|
|
107
109
|
| {code: BlockErrorCode.NOT_LATER_THAN_PARENT; parentSlot: Slot; slot: Slot}
|
|
108
110
|
| {code: BlockErrorCode.NON_LINEAR_PARENT_ROOTS}
|
|
109
111
|
| {code: BlockErrorCode.NON_LINEAR_SLOTS}
|
|
112
|
+
| {code: BlockErrorCode.ENVELOPE_BLOCK_ROOT_MISMATCH; envelopeBlockRoot: RootHex; blockRoot: RootHex}
|
|
110
113
|
| {code: BlockErrorCode.PER_BLOCK_PROCESSING_ERROR; error: Error}
|
|
111
114
|
| {code: BlockErrorCode.BEACON_CHAIN_ERROR; error: Error}
|
|
112
115
|
| {code: BlockErrorCode.KNOWN_BAD_BLOCK}
|
|
@@ -120,7 +123,7 @@ export type BlockErrorType =
|
|
|
120
123
|
| {code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS; blobKzgCommitmentsLen: number; commitmentLimit: number}
|
|
121
124
|
| {code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH; bidParentRoot: RootHex; blockParentRoot: RootHex}
|
|
122
125
|
| {code: BlockErrorCode.PARENT_EXECUTION_INVALID; parentRoot: RootHex}
|
|
123
|
-
| {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentBlockHash: RootHex};
|
|
126
|
+
| {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentRoot: RootHex; parentBlockHash: RootHex};
|
|
124
127
|
|
|
125
128
|
export class BlockGossipError extends GossipActionError<BlockErrorType> {}
|
|
126
129
|
|