@lodestar/beacon-node 1.43.0-dev.ade910fc78 → 1.43.0-dev.b05ea98d04
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 +68 -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/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 +34 -54
- 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 +89 -89
- 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 +7 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +29 -2
- 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 +79 -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 +43 -43
- 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/attestationError.d.ts +8 -1
- package/lib/chain/errors/attestationError.d.ts.map +1 -1
- package/lib/chain/errors/attestationError.js +4 -0
- package/lib/chain/errors/attestationError.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 +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/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/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 +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 +13 -8
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +68 -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 +22 -6
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +53 -17
- 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/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/aggregateAndProof.js +12 -0
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +12 -0
- package/lib/chain/validation/attestation.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 +24 -9
- 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 +21 -11
- 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 +91 -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 +13 -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 +60 -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/constants.d.ts +3 -1
- package/lib/sync/constants.d.ts.map +1 -1
- package/lib/sync/constants.js +3 -4
- package/lib/sync/constants.js.map +1 -1
- package/lib/sync/range/batch.d.ts +28 -2
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +146 -44
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +12 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +53 -9
- 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 +604 -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 +162 -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 +20 -5
- 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 +84 -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/blockInput/blockInput.ts +4 -1
- package/src/chain/blocks/importBlock.ts +34 -79
- package/src/chain/blocks/importExecutionPayload.ts +110 -102
- package/src/chain/blocks/index.ts +74 -24
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +37 -2
- 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 +134 -0
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +41 -0
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
- package/src/chain/chain.ts +61 -58
- package/src/chain/emitter.ts +15 -14
- package/src/chain/errors/attestationError.ts +6 -1
- 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 +47 -0
- package/src/chain/forkChoice/index.ts +8 -20
- package/src/chain/initState.ts +9 -1
- 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 +91 -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 +71 -20
- package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
- package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
- package/src/chain/stateCache/types.ts +0 -3
- package/src/chain/validation/aggregateAndProof.ts +13 -0
- package/src/chain/validation/attestation.ts +13 -0
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/executionPayloadBid.ts +25 -8
- package/src/chain/validation/executionPayloadEnvelope.ts +22 -12
- package/src/chain/validation/payloadAttestationMessage.ts +5 -3
- package/src/chain/validation/proposerPreferences.ts +110 -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 +79 -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/constants.ts +4 -4
- package/src/sync/range/batch.ts +204 -49
- package/src/sync/range/chain.ts +69 -11
- package/src/sync/range/range.ts +18 -6
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +762 -57
- package/src/sync/utils/downloadByRange.ts +272 -39
- package/src/sync/utils/downloadByRoot.ts +24 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
- package/src/util/sszBytes.ts +25 -5
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
ForkPostDeneb,
|
|
4
|
+
ForkPostFulu,
|
|
5
|
+
ForkPostGloas,
|
|
6
|
+
ForkPreFulu,
|
|
7
|
+
isForkPostFulu,
|
|
8
|
+
isForkPostGloas,
|
|
9
|
+
} from "@lodestar/params";
|
|
10
|
+
import {
|
|
11
|
+
DataColumnSidecar,
|
|
12
|
+
SignedBeaconBlock,
|
|
13
|
+
Slot,
|
|
14
|
+
deneb,
|
|
15
|
+
fulu,
|
|
16
|
+
gloas,
|
|
17
|
+
isGloasBeaconBlock,
|
|
18
|
+
isGloasDataColumnSidecar,
|
|
19
|
+
phase0,
|
|
20
|
+
} from "@lodestar/types";
|
|
4
21
|
import {LodestarError, Logger, byteArrayEquals, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
|
|
5
22
|
import {
|
|
6
23
|
BlockInputSource,
|
|
@@ -9,12 +26,18 @@ import {
|
|
|
9
26
|
isBlockInputBlobs,
|
|
10
27
|
isBlockInputColumns,
|
|
11
28
|
} from "../../chain/blocks/blockInput/index.js";
|
|
29
|
+
import {PayloadEnvelopeInput} from "../../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
30
|
+
import {PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/types.js";
|
|
12
31
|
import {SeenBlockInput} from "../../chain/seenCache/seenGossipBlockInput.js";
|
|
32
|
+
import {SeenPayloadEnvelopeInput} from "../../chain/seenCache/seenPayloadEnvelopeInput.js";
|
|
13
33
|
import {validateBlockBlobSidecars} from "../../chain/validation/blobSidecar.js";
|
|
14
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
validateFuluBlockDataColumnSidecars,
|
|
36
|
+
validateGloasBlockDataColumnSidecars,
|
|
37
|
+
} from "../../chain/validation/dataColumnSidecar.js";
|
|
15
38
|
import {BeaconMetrics} from "../../metrics/metrics/beacon.js";
|
|
16
39
|
import {INetwork} from "../../network/index.js";
|
|
17
|
-
import {getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
40
|
+
import {CustodyConfig, getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
18
41
|
import {PeerIdStr} from "../../util/peerId.js";
|
|
19
42
|
import {WarnResult} from "../../util/wrapError.js";
|
|
20
43
|
|
|
@@ -22,12 +45,14 @@ export type DownloadByRangeRequests = {
|
|
|
22
45
|
blocksRequest?: phase0.BeaconBlocksByRangeRequest;
|
|
23
46
|
blobsRequest?: deneb.BlobSidecarsByRangeRequest;
|
|
24
47
|
columnsRequest?: fulu.DataColumnSidecarsByRangeRequest;
|
|
48
|
+
envelopesRequest?: gloas.ExecutionPayloadEnvelopesByRangeRequest;
|
|
25
49
|
};
|
|
26
50
|
|
|
27
51
|
export type DownloadByRangeResponses = {
|
|
28
52
|
blocks?: SignedBeaconBlock[];
|
|
29
53
|
blobSidecars?: deneb.BlobSidecars;
|
|
30
|
-
columnSidecars?:
|
|
54
|
+
columnSidecars?: DataColumnSidecar[];
|
|
55
|
+
payloadEnvelopes?: gloas.SignedExecutionPayloadEnvelope[];
|
|
31
56
|
};
|
|
32
57
|
|
|
33
58
|
export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
|
|
@@ -41,9 +66,17 @@ export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
|
|
|
41
66
|
|
|
42
67
|
export type CacheByRangeResponsesProps = {
|
|
43
68
|
cache: SeenBlockInput;
|
|
69
|
+
seenPayloadEnvelopeInputCache: SeenPayloadEnvelopeInput;
|
|
44
70
|
peerIdStr: string;
|
|
45
71
|
responses: ValidatedResponses;
|
|
46
72
|
batchBlocks: IBlockInput[];
|
|
73
|
+
/** Raw envelopes downloaded in this batch, keyed by slot (from downloadByRange return) */
|
|
74
|
+
downloadedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null;
|
|
75
|
+
/** Envelopes already wrapped from previous partial downloads on this batch */
|
|
76
|
+
existingPayloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
77
|
+
/** Sampled/custody column indices for building PayloadEnvelopeInputs */
|
|
78
|
+
custodyConfig: Pick<CustodyConfig, "sampledColumns" | "custodyColumns">;
|
|
79
|
+
seenTimestampSec: number;
|
|
47
80
|
};
|
|
48
81
|
|
|
49
82
|
export type ValidatedBlock = {
|
|
@@ -58,7 +91,7 @@ export type ValidatedBlobSidecars = {
|
|
|
58
91
|
|
|
59
92
|
export type ValidatedColumnSidecars = {
|
|
60
93
|
blockRoot: Uint8Array;
|
|
61
|
-
columnSidecars:
|
|
94
|
+
columnSidecars: DataColumnSidecar[];
|
|
62
95
|
};
|
|
63
96
|
|
|
64
97
|
export type ValidatedResponses = {
|
|
@@ -72,12 +105,16 @@ export type ValidatedResponses = {
|
|
|
72
105
|
*/
|
|
73
106
|
export function cacheByRangeResponses({
|
|
74
107
|
cache,
|
|
108
|
+
seenPayloadEnvelopeInputCache,
|
|
75
109
|
peerIdStr,
|
|
76
110
|
responses,
|
|
77
111
|
batchBlocks,
|
|
78
|
-
|
|
112
|
+
downloadedPayloadEnvelopes,
|
|
113
|
+
existingPayloadEnvelopes,
|
|
114
|
+
custodyConfig,
|
|
115
|
+
seenTimestampSec,
|
|
116
|
+
}: CacheByRangeResponsesProps): {blocks: IBlockInput[]; payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null} {
|
|
79
117
|
const source = BlockInputSource.byRange;
|
|
80
|
-
const seenTimestampSec = Date.now() / 1000;
|
|
81
118
|
const updatedBatchBlocks = new Map<Slot, IBlockInput>(batchBlocks.map((block) => [block.slot, block]));
|
|
82
119
|
|
|
83
120
|
const blocks = responses.validatedBlocks ?? [];
|
|
@@ -149,16 +186,86 @@ export function cacheByRangeResponses({
|
|
|
149
186
|
}
|
|
150
187
|
}
|
|
151
188
|
|
|
189
|
+
// Seed seenPayloadEnvelopeInputCache for every gloas block in the batch, regardless of whether
|
|
190
|
+
// the peer returned its envelope. Without this, a block returned without its envelope would be
|
|
191
|
+
// imported with no cache entry, and later payload-by-root sync would throw
|
|
192
|
+
// "Missing PayloadEnvelopeInput for known block" (see issue #9306).
|
|
193
|
+
for (const blockInput of updatedBatchBlocks.values()) {
|
|
194
|
+
if (!blockInput.hasBlock() || !isForkPostGloas(blockInput.forkName)) continue;
|
|
195
|
+
seenPayloadEnvelopeInputCache.add({
|
|
196
|
+
blockRootHex: blockInput.blockRootHex,
|
|
197
|
+
block: blockInput.getBlock() as SignedBeaconBlock<ForkPostGloas>,
|
|
198
|
+
forkName: blockInput.forkName,
|
|
199
|
+
sampledColumns: custodyConfig.sampledColumns,
|
|
200
|
+
custodyColumns: custodyConfig.custodyColumns,
|
|
201
|
+
timeCreatedSec: seenTimestampSec,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
let payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null =
|
|
206
|
+
existingPayloadEnvelopes !== null ? new Map(existingPayloadEnvelopes) : null;
|
|
207
|
+
if (downloadedPayloadEnvelopes !== null) {
|
|
208
|
+
payloadEnvelopes ??= new Map();
|
|
209
|
+
for (const [slot, envelope] of downloadedPayloadEnvelopes) {
|
|
210
|
+
const blockInput = updatedBatchBlocks.get(slot);
|
|
211
|
+
if (!blockInput?.hasBlock() || !isForkPostGloas(blockInput.forkName)) {
|
|
212
|
+
// No block to pair this envelope with; drop silently
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const payloadInput = seenPayloadEnvelopeInputCache.get(blockInput.blockRootHex);
|
|
217
|
+
if (payloadInput === undefined) {
|
|
218
|
+
// Unreachable given the loop above seeded an entry for every gloas block in the batch.
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (!payloadInput.hasPayloadEnvelope()) {
|
|
223
|
+
payloadInput.addPayloadEnvelope({
|
|
224
|
+
envelope,
|
|
225
|
+
source: PayloadEnvelopeInputSource.byRange,
|
|
226
|
+
seenTimestampSec,
|
|
227
|
+
peerIdStr,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
payloadEnvelopes.set(slot, payloadInput);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
152
235
|
for (const {blockRoot, columnSidecars} of responses.validatedColumnSidecars ?? []) {
|
|
153
|
-
const
|
|
154
|
-
if (
|
|
236
|
+
const firstColumn = columnSidecars[0];
|
|
237
|
+
if (!firstColumn) {
|
|
155
238
|
throw new Error(
|
|
156
239
|
`Coding Error: empty columnSidecars returned for blockRoot=${toRootHex(blockRoot)} from validation functions`
|
|
157
240
|
);
|
|
158
241
|
}
|
|
159
|
-
|
|
242
|
+
|
|
160
243
|
const blockRootHex = toRootHex(blockRoot);
|
|
161
244
|
|
|
245
|
+
if (isGloasDataColumnSidecar(firstColumn)) {
|
|
246
|
+
// Gloas columns are attached to the matching PayloadEnvelopeInput, NOT to IBlockInput.
|
|
247
|
+
// Gloas DataColumnSidecar has `slot` directly (no signedBlockHeader).
|
|
248
|
+
const dataSlot = firstColumn.slot;
|
|
249
|
+
const payloadInput = payloadEnvelopes?.get(dataSlot);
|
|
250
|
+
if (!payloadInput) {
|
|
251
|
+
// Should not happen: we built payloadInputs for all gloas blocks above
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
for (const columnSidecar of columnSidecars as gloas.DataColumnSidecar[]) {
|
|
255
|
+
payloadInput.addColumn({
|
|
256
|
+
columnSidecar,
|
|
257
|
+
seenTimestampSec,
|
|
258
|
+
peerIdStr,
|
|
259
|
+
source: PayloadEnvelopeInputSource.byRange,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const fuluColumns = columnSidecars as fulu.DataColumnSidecar[];
|
|
266
|
+
const dataSlot = fuluColumns[0].signedBlockHeader.message.slot;
|
|
267
|
+
const existing = updatedBatchBlocks.get(dataSlot);
|
|
268
|
+
|
|
162
269
|
if (!existing) {
|
|
163
270
|
throw new Error("Coding error: blockInput must exist when adding columns");
|
|
164
271
|
}
|
|
@@ -172,7 +279,7 @@ export function cacheByRangeResponses({
|
|
|
172
279
|
actual: existing.type,
|
|
173
280
|
});
|
|
174
281
|
}
|
|
175
|
-
for (const columnSidecar of
|
|
282
|
+
for (const columnSidecar of fuluColumns) {
|
|
176
283
|
// will throw if root hex does not match (meaning we are following the wrong chain)
|
|
177
284
|
existing.addColumn(
|
|
178
285
|
{
|
|
@@ -187,7 +294,7 @@ export function cacheByRangeResponses({
|
|
|
187
294
|
}
|
|
188
295
|
}
|
|
189
296
|
|
|
190
|
-
return Array.from(updatedBatchBlocks.values());
|
|
297
|
+
return {blocks: Array.from(updatedBatchBlocks.values()), payloadEnvelopes};
|
|
191
298
|
}
|
|
192
299
|
|
|
193
300
|
export async function downloadByRange({
|
|
@@ -198,8 +305,14 @@ export async function downloadByRange({
|
|
|
198
305
|
blocksRequest,
|
|
199
306
|
blobsRequest,
|
|
200
307
|
columnsRequest,
|
|
308
|
+
envelopesRequest,
|
|
201
309
|
peerDasMetrics,
|
|
202
|
-
}: DownloadAndCacheByRangeProps): Promise<
|
|
310
|
+
}: DownloadAndCacheByRangeProps): Promise<
|
|
311
|
+
WarnResult<
|
|
312
|
+
{responses: ValidatedResponses; payloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null},
|
|
313
|
+
DownloadByRangeError
|
|
314
|
+
>
|
|
315
|
+
> {
|
|
203
316
|
let response: DownloadByRangeResponses;
|
|
204
317
|
try {
|
|
205
318
|
response = await requestByRange({
|
|
@@ -208,6 +321,7 @@ export async function downloadByRange({
|
|
|
208
321
|
blocksRequest,
|
|
209
322
|
blobsRequest,
|
|
210
323
|
columnsRequest,
|
|
324
|
+
envelopesRequest,
|
|
211
325
|
});
|
|
212
326
|
} catch (err) {
|
|
213
327
|
throw new DownloadByRangeError({
|
|
@@ -217,17 +331,16 @@ export async function downloadByRange({
|
|
|
217
331
|
});
|
|
218
332
|
}
|
|
219
333
|
|
|
220
|
-
|
|
334
|
+
return validateResponses({
|
|
221
335
|
config,
|
|
222
336
|
batchBlocks,
|
|
223
337
|
blocksRequest,
|
|
224
338
|
blobsRequest,
|
|
225
339
|
columnsRequest,
|
|
340
|
+
envelopesRequest,
|
|
226
341
|
peerDasMetrics,
|
|
227
342
|
...response,
|
|
228
343
|
});
|
|
229
|
-
|
|
230
|
-
return validated;
|
|
231
344
|
}
|
|
232
345
|
|
|
233
346
|
/**
|
|
@@ -239,13 +352,15 @@ export async function requestByRange({
|
|
|
239
352
|
blocksRequest,
|
|
240
353
|
blobsRequest,
|
|
241
354
|
columnsRequest,
|
|
355
|
+
envelopesRequest,
|
|
242
356
|
}: DownloadByRangeRequests & {
|
|
243
357
|
network: INetwork;
|
|
244
358
|
peerIdStr: PeerIdStr;
|
|
245
359
|
}): Promise<DownloadByRangeResponses> {
|
|
246
360
|
let blocks: undefined | SignedBeaconBlock[];
|
|
247
361
|
let blobSidecars: undefined | deneb.BlobSidecars;
|
|
248
|
-
let columnSidecars: undefined |
|
|
362
|
+
let columnSidecars: undefined | DataColumnSidecar[];
|
|
363
|
+
const payloadEnvelopes: gloas.SignedExecutionPayloadEnvelope[] = [];
|
|
249
364
|
|
|
250
365
|
const requests: Promise<unknown>[] = [];
|
|
251
366
|
|
|
@@ -253,6 +368,17 @@ export async function requestByRange({
|
|
|
253
368
|
requests.push(
|
|
254
369
|
network.sendBeaconBlocksByRange(peerIdStr, blocksRequest).then((blockResponse) => {
|
|
255
370
|
blocks = blockResponse;
|
|
371
|
+
const firstBlock = blockResponse.at(0);
|
|
372
|
+
if (firstBlock && isGloasBeaconBlock(firstBlock.message)) {
|
|
373
|
+
return network
|
|
374
|
+
.sendExecutionPayloadEnvelopesByRoot(peerIdStr, [
|
|
375
|
+
firstBlock.message.body.signedExecutionPayloadBid.message.parentBlockRoot,
|
|
376
|
+
])
|
|
377
|
+
.then((envelopeResponse) => {
|
|
378
|
+
payloadEnvelopes?.unshift(...envelopeResponse);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return undefined;
|
|
256
382
|
})
|
|
257
383
|
);
|
|
258
384
|
}
|
|
@@ -268,7 +394,15 @@ export async function requestByRange({
|
|
|
268
394
|
if (columnsRequest) {
|
|
269
395
|
requests.push(
|
|
270
396
|
network.sendDataColumnSidecarsByRange(peerIdStr, columnsRequest).then((columnResponse) => {
|
|
271
|
-
columnSidecars = columnResponse
|
|
397
|
+
columnSidecars = columnResponse;
|
|
398
|
+
})
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (envelopesRequest) {
|
|
403
|
+
requests.push(
|
|
404
|
+
network.sendExecutionPayloadEnvelopesByRange(peerIdStr, envelopesRequest).then((envelopeResponse) => {
|
|
405
|
+
payloadEnvelopes?.push(...envelopeResponse);
|
|
272
406
|
})
|
|
273
407
|
);
|
|
274
408
|
}
|
|
@@ -279,6 +413,7 @@ export async function requestByRange({
|
|
|
279
413
|
blocks,
|
|
280
414
|
blobSidecars,
|
|
281
415
|
columnSidecars,
|
|
416
|
+
payloadEnvelopes,
|
|
282
417
|
};
|
|
283
418
|
}
|
|
284
419
|
|
|
@@ -291,16 +426,23 @@ export async function validateResponses({
|
|
|
291
426
|
blocksRequest,
|
|
292
427
|
blobsRequest,
|
|
293
428
|
columnsRequest,
|
|
429
|
+
envelopesRequest,
|
|
294
430
|
blocks,
|
|
295
431
|
blobSidecars,
|
|
296
432
|
columnSidecars,
|
|
433
|
+
payloadEnvelopes,
|
|
297
434
|
peerDasMetrics,
|
|
298
435
|
}: DownloadByRangeRequests &
|
|
299
436
|
DownloadByRangeResponses & {
|
|
300
437
|
config: ChainForkConfig;
|
|
301
438
|
batchBlocks?: IBlockInput[];
|
|
302
439
|
peerDasMetrics?: BeaconMetrics["peerDas"] | null;
|
|
303
|
-
}): Promise<
|
|
440
|
+
}): Promise<
|
|
441
|
+
WarnResult<
|
|
442
|
+
{responses: ValidatedResponses; payloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null},
|
|
443
|
+
DownloadByRangeError
|
|
444
|
+
>
|
|
445
|
+
> {
|
|
304
446
|
// Blocks are always required for blob/column validation
|
|
305
447
|
// If a blocksRequest is provided, blocks have just been downloaded
|
|
306
448
|
// If no blocksRequest is provided, batchBlocks must have been provided from cache
|
|
@@ -326,8 +468,21 @@ export async function validateResponses({
|
|
|
326
468
|
}
|
|
327
469
|
|
|
328
470
|
const dataRequest = blobsRequest ?? columnsRequest;
|
|
471
|
+
if (!dataRequest && !envelopesRequest) {
|
|
472
|
+
return {result: {responses: validatedResponses, payloadEnvelopes: null}, warnings};
|
|
473
|
+
}
|
|
474
|
+
|
|
329
475
|
if (!dataRequest) {
|
|
330
|
-
|
|
476
|
+
// Only envelope validation needed
|
|
477
|
+
let validatedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null = null;
|
|
478
|
+
if (envelopesRequest) {
|
|
479
|
+
validatedPayloadEnvelopes = validateEnvelopesByRangeResponse(
|
|
480
|
+
validatedResponses.validatedBlocks ?? [],
|
|
481
|
+
batchBlocks,
|
|
482
|
+
payloadEnvelopes ?? []
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
return {result: {responses: validatedResponses, payloadEnvelopes: validatedPayloadEnvelopes}, warnings};
|
|
331
486
|
}
|
|
332
487
|
|
|
333
488
|
const blocksForDataValidation = getBlocksForDataValidation(
|
|
@@ -385,7 +540,17 @@ export async function validateResponses({
|
|
|
385
540
|
warnings = validatedColumnSidecarsResult.warnings;
|
|
386
541
|
}
|
|
387
542
|
|
|
388
|
-
|
|
543
|
+
// Validate envelopes if an envelopes request was made
|
|
544
|
+
let validatedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null = null;
|
|
545
|
+
if (envelopesRequest) {
|
|
546
|
+
validatedPayloadEnvelopes = validateEnvelopesByRangeResponse(
|
|
547
|
+
validatedResponses.validatedBlocks ?? [],
|
|
548
|
+
batchBlocks,
|
|
549
|
+
payloadEnvelopes ?? []
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return {result: {responses: validatedResponses, payloadEnvelopes: validatedPayloadEnvelopes}, warnings};
|
|
389
554
|
}
|
|
390
555
|
|
|
391
556
|
/**
|
|
@@ -615,19 +780,19 @@ export async function validateColumnsByRangeResponse(
|
|
|
615
780
|
config: ChainForkConfig,
|
|
616
781
|
request: fulu.DataColumnSidecarsByRangeRequest,
|
|
617
782
|
blocks: ValidatedBlock[],
|
|
618
|
-
columnSidecars:
|
|
783
|
+
columnSidecars: DataColumnSidecar[],
|
|
619
784
|
peerDasMetrics?: BeaconMetrics["peerDas"] | null
|
|
620
785
|
): Promise<WarnResult<ValidatedColumnSidecars[], DownloadByRangeError>> {
|
|
621
786
|
const warnings: DownloadByRangeError[] = [];
|
|
622
787
|
|
|
623
|
-
|
|
624
|
-
// validate against the block bid commitments instead of the fulu signed header shape
|
|
625
|
-
const seenColumns = new Map<Slot, Map<number, fulu.DataColumnSidecar>>();
|
|
788
|
+
const seenColumns = new Map<Slot, Map<number, DataColumnSidecar>>();
|
|
626
789
|
let currentSlot = -1;
|
|
627
790
|
let currentIndex = -1;
|
|
628
791
|
// Check for duplicates and order
|
|
629
792
|
for (const columnSidecar of columnSidecars) {
|
|
630
|
-
const slot = columnSidecar
|
|
793
|
+
const slot = isGloasDataColumnSidecar(columnSidecar)
|
|
794
|
+
? columnSidecar.slot
|
|
795
|
+
: columnSidecar.signedBlockHeader.message.slot;
|
|
631
796
|
let seenSlotColumns = seenColumns.get(slot);
|
|
632
797
|
if (!seenSlotColumns) {
|
|
633
798
|
seenSlotColumns = new Map();
|
|
@@ -686,20 +851,20 @@ export async function validateColumnsByRangeResponse(
|
|
|
686
851
|
const slot = block.message.slot;
|
|
687
852
|
const rootHex = toRootHex(blockRoot);
|
|
688
853
|
const forkName = config.getForkName(slot);
|
|
689
|
-
const columnSidecarsMap: Map<number,
|
|
854
|
+
const columnSidecarsMap: Map<number, DataColumnSidecar> = seenColumns.get(slot) ?? new Map();
|
|
690
855
|
const columnSidecars = Array.from(columnSidecarsMap.values()).sort((a, b) => a.index - b.index);
|
|
691
856
|
|
|
692
857
|
let blobCount: number;
|
|
693
858
|
if (!isForkPostFulu(forkName)) {
|
|
694
|
-
const dataSlot = columnSidecars.at(0)?.signedBlockHeader.message.slot;
|
|
695
859
|
throw new DownloadByRangeError({
|
|
696
860
|
code: DownloadByRangeErrorCode.MISMATCH_BLOCK_FORK,
|
|
697
861
|
slot,
|
|
698
862
|
blockFork: forkName,
|
|
699
|
-
dataFork:
|
|
863
|
+
dataFork: "unknown",
|
|
700
864
|
});
|
|
701
865
|
}
|
|
702
|
-
|
|
866
|
+
const kzgCommitments = getBlobKzgCommitments(forkName, block as SignedBeaconBlock<ForkPostFulu>);
|
|
867
|
+
blobCount = kzgCommitments.length;
|
|
703
868
|
|
|
704
869
|
if (columnSidecars.length === 0) {
|
|
705
870
|
if (!blobCount) {
|
|
@@ -768,15 +933,25 @@ export async function validateColumnsByRangeResponse(
|
|
|
768
933
|
);
|
|
769
934
|
}
|
|
770
935
|
|
|
936
|
+
const validatePromise = isForkPostGloas(forkName)
|
|
937
|
+
? validateGloasBlockDataColumnSidecars(
|
|
938
|
+
slot,
|
|
939
|
+
blockRoot,
|
|
940
|
+
kzgCommitments,
|
|
941
|
+
columnSidecars as gloas.DataColumnSidecar[],
|
|
942
|
+
peerDasMetrics
|
|
943
|
+
)
|
|
944
|
+
: validateFuluBlockDataColumnSidecars(
|
|
945
|
+
null, // do not pass chain here so we do not validate header signature
|
|
946
|
+
slot,
|
|
947
|
+
blockRoot,
|
|
948
|
+
blobCount,
|
|
949
|
+
columnSidecars as fulu.DataColumnSidecar[],
|
|
950
|
+
peerDasMetrics
|
|
951
|
+
);
|
|
952
|
+
|
|
771
953
|
validationPromises.push(
|
|
772
|
-
|
|
773
|
-
null, // do not pass chain here so we do not validate header signature
|
|
774
|
-
slot,
|
|
775
|
-
blockRoot,
|
|
776
|
-
blobCount,
|
|
777
|
-
columnSidecars,
|
|
778
|
-
peerDasMetrics
|
|
779
|
-
).then(() => ({
|
|
954
|
+
validatePromise.then(() => ({
|
|
780
955
|
blockRoot,
|
|
781
956
|
columnSidecars,
|
|
782
957
|
}))
|
|
@@ -882,6 +1057,9 @@ export enum DownloadByRangeErrorCode {
|
|
|
882
1057
|
/** Cached block input type mismatches new data */
|
|
883
1058
|
MISMATCH_BLOCK_FORK = "DOWNLOAD_BY_RANGE_ERROR_MISMATCH_BLOCK_FORK",
|
|
884
1059
|
MISMATCH_BLOCK_INPUT_TYPE = "DOWNLOAD_BY_RANGE_ERROR_MISMATCH_BLOCK_INPUT_TYPE",
|
|
1060
|
+
|
|
1061
|
+
/** Envelope beaconBlockRoot does not match the block's root */
|
|
1062
|
+
INVALID_ENVELOPE_BEACON_BLOCK_ROOT = "DOWNLOAD_BY_RANGE_ERROR_INVALID_ENVELOPE_BEACON_BLOCK_ROOT",
|
|
885
1063
|
}
|
|
886
1064
|
|
|
887
1065
|
export type DownloadByRangeErrorType =
|
|
@@ -973,6 +1151,61 @@ export type DownloadByRangeErrorType =
|
|
|
973
1151
|
blockRoot: string;
|
|
974
1152
|
expected: DAType;
|
|
975
1153
|
actual: DAType;
|
|
1154
|
+
}
|
|
1155
|
+
| {
|
|
1156
|
+
code: DownloadByRangeErrorCode.INVALID_ENVELOPE_BEACON_BLOCK_ROOT;
|
|
1157
|
+
slot: Slot;
|
|
1158
|
+
expected: string;
|
|
1159
|
+
actual: string;
|
|
976
1160
|
};
|
|
977
1161
|
|
|
978
1162
|
export class DownloadByRangeError extends LodestarError<DownloadByRangeErrorType> {}
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* Validates SignedExecutionPayloadEnvelopes received for a range request.
|
|
1166
|
+
* For each envelope whose slot appears in the downloaded blocks, verifies that
|
|
1167
|
+
* envelope.message.beaconBlockRoot matches the corresponding block's root.
|
|
1168
|
+
* Envelopes for slots not in the batch (orphaned payloads) are silently ignored.
|
|
1169
|
+
*/
|
|
1170
|
+
export function validateEnvelopesByRangeResponse(
|
|
1171
|
+
validatedBlocks: ValidatedBlock[],
|
|
1172
|
+
batchBlocks: IBlockInput[] | undefined,
|
|
1173
|
+
payloadEnvelopes: gloas.SignedExecutionPayloadEnvelope[]
|
|
1174
|
+
): Map<Slot, gloas.SignedExecutionPayloadEnvelope> {
|
|
1175
|
+
// Build a map of slot -> blockRoot for all blocks in the batch
|
|
1176
|
+
const batchBlockRoots = new Map<Slot, Uint8Array>();
|
|
1177
|
+
if (batchBlocks) {
|
|
1178
|
+
for (const blockInput of batchBlocks) {
|
|
1179
|
+
batchBlockRoots.set(blockInput.slot, fromHex(blockInput.blockRootHex));
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
for (const {block, blockRoot} of validatedBlocks) {
|
|
1183
|
+
batchBlockRoots.set(block.message.slot, blockRoot);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
const payloadEnvelopeMap = new Map<Slot, gloas.SignedExecutionPayloadEnvelope>();
|
|
1187
|
+
|
|
1188
|
+
for (const payloadEnvelope of payloadEnvelopes) {
|
|
1189
|
+
const slot = payloadEnvelope.message.payload.slotNumber;
|
|
1190
|
+
const batchBlockRoot = batchBlockRoots.get(slot);
|
|
1191
|
+
|
|
1192
|
+
// Envelopes for slots not in the batch are silently ignored (orphaned payloads or a parent payload)
|
|
1193
|
+
if (batchBlockRoot === undefined) {
|
|
1194
|
+
continue;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// Verify beaconBlockRoot matches the block's root
|
|
1198
|
+
if (!byteArrayEquals(payloadEnvelope.message.beaconBlockRoot, batchBlockRoot)) {
|
|
1199
|
+
throw new DownloadByRangeError({
|
|
1200
|
+
code: DownloadByRangeErrorCode.INVALID_ENVELOPE_BEACON_BLOCK_ROOT,
|
|
1201
|
+
slot,
|
|
1202
|
+
expected: toRootHex(batchBlockRoot),
|
|
1203
|
+
actual: toRootHex(payloadEnvelope.message.beaconBlockRoot),
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
payloadEnvelopeMap.set(slot, payloadEnvelope);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
return payloadEnvelopeMap;
|
|
1211
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ForkPostDeneb,
|
|
5
|
+
ForkPostFulu,
|
|
6
|
+
ForkPostGloas,
|
|
7
|
+
ForkPreFulu,
|
|
8
|
+
isForkPostDeneb,
|
|
9
|
+
isForkPostFulu,
|
|
10
|
+
isForkPostGloas,
|
|
11
|
+
} from "@lodestar/params";
|
|
4
12
|
import {BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
5
13
|
import {LodestarError, byteArrayEquals, fromHex, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
|
|
6
14
|
import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
|
|
@@ -107,6 +115,17 @@ export async function downloadByRoot({
|
|
|
107
115
|
});
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
if (isForkPostGloas(blockInput.forkName)) {
|
|
119
|
+
chain.seenPayloadEnvelopeInputCache.add({
|
|
120
|
+
blockRootHex: rootHex,
|
|
121
|
+
block: blockInput.getBlock() as SignedBeaconBlock<ForkPostGloas>,
|
|
122
|
+
forkName: blockInput.forkName,
|
|
123
|
+
sampledColumns: chain.custodyConfig.sampledColumns,
|
|
124
|
+
custodyColumns: chain.custodyConfig.custodyColumns,
|
|
125
|
+
timeCreatedSec: Date.now() / 1000,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
110
129
|
const hasAllDataPreDownload = blockInput.hasBlockAndAllData();
|
|
111
130
|
|
|
112
131
|
if (isBlockInputBlobs(blockInput) && !hasAllDataPreDownload) {
|
|
@@ -263,7 +282,10 @@ export async function fetchByRoot({
|
|
|
263
282
|
blockRoot,
|
|
264
283
|
});
|
|
265
284
|
const forkName = config.getForkName(block.message.slot);
|
|
266
|
-
if (
|
|
285
|
+
if (isForkPostGloas(forkName)) {
|
|
286
|
+
// Post-gloas block sync only needs the block body. Payload columns stay on the
|
|
287
|
+
// payload/envelope path and are queued independently in the network processor.
|
|
288
|
+
} else if (isForkPostFulu(forkName)) {
|
|
267
289
|
columnSidecarResult = await fetchAndValidateColumns({
|
|
268
290
|
config,
|
|
269
291
|
chain,
|
|
@@ -40,21 +40,6 @@ function addToDescendantBlocks(
|
|
|
40
40
|
return descendantBlocks;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export function getDescendantBlocks(
|
|
44
|
-
blockRootHex: RootHex,
|
|
45
|
-
blocks: Map<RootHex, BlockInputSyncCacheItem>
|
|
46
|
-
): BlockInputSyncCacheItem[] {
|
|
47
|
-
const descendantBlocks: BlockInputSyncCacheItem[] = [];
|
|
48
|
-
|
|
49
|
-
for (const block of blocks.values()) {
|
|
50
|
-
if ((isPendingBlockInput(block) ? block.blockInput.parentRootHex : undefined) === blockRootHex) {
|
|
51
|
-
descendantBlocks.push(block);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return descendantBlocks;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
43
|
export type UnknownAndAncestorBlocks = {
|
|
59
44
|
unknowns: BlockInputSyncCacheItem[];
|
|
60
45
|
ancestors: PendingBlockInput[];
|
package/src/util/sszBytes.ts
CHANGED
|
@@ -558,10 +558,11 @@ export function getBeaconBlockRootFromDataColumnSidecarSerialized(data: Uint8Arr
|
|
|
558
558
|
* └─ ExecutionPayloadEnvelope (starts at byte 100):
|
|
559
559
|
* ├─ 4 bytes: payload offset
|
|
560
560
|
* ├─ 4 bytes: executionRequests offset
|
|
561
|
-
* ├─ 8 bytes: builderIndex
|
|
562
|
-
* ├─ 32 bytes: beaconBlockRoot
|
|
563
|
-
* ├─
|
|
564
|
-
* └─
|
|
561
|
+
* ├─ 8 bytes: builderIndex (offset 108-115)
|
|
562
|
+
* ├─ 32 bytes: beaconBlockRoot (offset 116-147)
|
|
563
|
+
* ├─ 32 bytes: parentBeaconBlockRoot (offset 148-179) — new in Gloas alpha.6 (consensus-specs#5152)
|
|
564
|
+
* └─ variable: payload data (starts at envelope + 80)
|
|
565
|
+
* └─ ExecutionPayload fixed portion includes slotNumber at offset 532
|
|
565
566
|
*/
|
|
566
567
|
const SIGNED_EXECUTION_PAYLOAD_ENVELOPE_MESSAGE_OFFSET = 4;
|
|
567
568
|
const SIGNED_EXECUTION_PAYLOAD_ENVELOPE_SIGNATURE_SIZE = 96;
|
|
@@ -576,8 +577,27 @@ const BEACON_BLOCK_ROOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE =
|
|
|
576
577
|
EXECUTION_PAYLOAD_ENVELOPE_REQUESTS_OFFSET +
|
|
577
578
|
EXECUTION_PAYLOAD_ENVELOPE_BUILDER_INDEX_SIZE; // 116
|
|
578
579
|
|
|
580
|
+
// Envelope fixed portion: payload_offset(4) + requests_offset(4) + builderIndex(8) + beaconBlockRoot(32) + parentBeaconBlockRoot(32) = 80
|
|
581
|
+
const EXECUTION_PAYLOAD_ENVELOPE_FIXED_SIZE =
|
|
582
|
+
EXECUTION_PAYLOAD_ENVELOPE_PAYLOAD_OFFSET +
|
|
583
|
+
EXECUTION_PAYLOAD_ENVELOPE_REQUESTS_OFFSET +
|
|
584
|
+
EXECUTION_PAYLOAD_ENVELOPE_BUILDER_INDEX_SIZE +
|
|
585
|
+
ROOT_SIZE +
|
|
586
|
+
ROOT_SIZE; // 80
|
|
587
|
+
|
|
588
|
+
// slotNumber offset within ExecutionPayload fixed portion:
|
|
589
|
+
// parentHash(32) + feeRecipient(20) + stateRoot(32) + receiptsRoot(32) + logsBloom(256) +
|
|
590
|
+
// prevRandao(32) + blockNumber(8) + gasLimit(8) + gasUsed(8) + timestamp(8) +
|
|
591
|
+
// extraData_offset(4) + baseFeePerGas(32) + blockHash(32) + transactions_offset(4) +
|
|
592
|
+
// withdrawals_offset(4) + blobGasUsed(8) + excessBlobGas(8) + blockAccessList_offset(4) = 532
|
|
593
|
+
const SLOT_NUMBER_OFFSET_IN_EXECUTION_PAYLOAD = 532;
|
|
594
|
+
|
|
595
|
+
// Payload data starts right after the envelope's fixed portion
|
|
596
|
+
const ENVELOPE_START_IN_SIGNED =
|
|
597
|
+
SIGNED_EXECUTION_PAYLOAD_ENVELOPE_MESSAGE_OFFSET + SIGNED_EXECUTION_PAYLOAD_ENVELOPE_SIGNATURE_SIZE; // 100
|
|
598
|
+
|
|
579
599
|
const SLOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE =
|
|
580
|
-
|
|
600
|
+
ENVELOPE_START_IN_SIGNED + EXECUTION_PAYLOAD_ENVELOPE_FIXED_SIZE + SLOT_NUMBER_OFFSET_IN_EXECUTION_PAYLOAD; // 100 + 80 + 532 = 712
|
|
581
601
|
|
|
582
602
|
export function getSlotFromExecutionPayloadEnvelopeSerialized(data: Uint8Array): Slot | null {
|
|
583
603
|
if (data.length < SLOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE + SLOT_SIZE) {
|