@lodestar/beacon-node 1.50.0-dev.8ba9d1dd30 → 1.50.0-dev.9203d3d7da
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 +13 -3
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/index.js +13 -0
- package/lib/api/impl/beacon/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/index.js +28 -6
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +26 -18
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts +1 -0
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +80 -18
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +0 -2
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +4 -5
- package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +5 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +14 -24
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +1 -1
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/pruneHistory.d.ts +1 -1
- package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/pruneHistory.js +2 -1
- package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
- package/lib/chain/beaconProposerCache.d.ts +6 -0
- package/lib/chain/beaconProposerCache.d.ts.map +1 -1
- package/lib/chain/beaconProposerCache.js +16 -0
- package/lib/chain/beaconProposerCache.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -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 +20 -11
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +7 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/chain.d.ts +10 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +105 -35
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +7 -1
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +5 -0
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
- package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
- package/lib/chain/errors/envelopeReconstructionError.js +2 -0
- package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
- package/lib/chain/errors/gossipValidation.d.ts +1 -0
- package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
- package/lib/chain/errors/gossipValidation.js +1 -0
- package/lib/chain/errors/gossipValidation.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +2 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +6 -3
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -2
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +30 -8
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +1 -23
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.d.ts +8 -4
- package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.js +27 -12
- package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +11 -0
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +22 -0
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/options.d.ts +2 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +15 -6
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +8 -0
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +48 -34
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +2 -0
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +10 -4
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/reprocess.d.ts +2 -1
- package/lib/chain/reprocess.d.ts.map +1 -1
- package/lib/chain/reprocess.js +2 -1
- package/lib/chain/reprocess.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -0
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +22 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +9 -2
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +23 -13
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/shufflingCache.d.ts +18 -8
- package/lib/chain/shufflingCache.d.ts.map +1 -1
- package/lib/chain/shufflingCache.js +72 -18
- package/lib/chain/shufflingCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +5 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +70 -58
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/constants/constants.d.ts +1 -0
- package/lib/constants/constants.d.ts.map +1 -1
- package/lib/constants/constants.js +1 -0
- package/lib/constants/constants.js.map +1 -1
- package/lib/db/beacon.d.ts +4 -1
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +6 -1
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +3 -1
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +2 -0
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +4 -1
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.js +2 -2
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +3 -3
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.js +1 -2
- package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
- package/lib/db/repositories/earliestAvailableSlot.d.ts +11 -0
- package/lib/db/repositories/earliestAvailableSlot.d.ts.map +1 -0
- package/lib/db/repositories/earliestAvailableSlot.js +19 -0
- package/lib/db/repositories/earliestAvailableSlot.js.map +1 -0
- package/lib/db/repositories/index.d.ts +1 -0
- package/lib/db/repositories/index.d.ts.map +1 -1
- package/lib/db/repositories/index.js +1 -0
- package/lib/db/repositories/index.js.map +1 -1
- package/lib/db/repositories/proposerPreferences.d.ts +14 -0
- package/lib/db/repositories/proposerPreferences.d.ts.map +1 -0
- package/lib/db/repositories/proposerPreferences.js +21 -0
- package/lib/db/repositories/proposerPreferences.js.map +1 -0
- package/lib/execution/engine/blobVersionedHashes.d.ts +9 -0
- package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -0
- package/lib/execution/engine/blobVersionedHashes.js +74 -0
- package/lib/execution/engine/blobVersionedHashes.js.map +1 -0
- package/lib/execution/engine/disabled.d.ts +0 -2
- package/lib/execution/engine/disabled.d.ts.map +1 -1
- package/lib/execution/engine/disabled.js +0 -6
- package/lib/execution/engine/disabled.js.map +1 -1
- package/lib/execution/engine/http.d.ts +46 -16
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +236 -213
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/index.d.ts +3 -2
- package/lib/execution/engine/index.d.ts.map +1 -1
- package/lib/execution/engine/index.js +33 -8
- package/lib/execution/engine/index.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +2 -4
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/jsonRpcTransport.d.ts +25 -0
- package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -0
- package/lib/execution/engine/jsonRpcTransport.js +158 -0
- package/lib/execution/engine/jsonRpcTransport.js.map +1 -0
- package/lib/execution/engine/mock.d.ts +0 -2
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +0 -8
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/restHttpClient.d.ts +71 -0
- package/lib/execution/engine/restHttpClient.d.ts.map +1 -0
- package/lib/execution/engine/restHttpClient.js +201 -0
- package/lib/execution/engine/restHttpClient.js.map +1 -0
- package/lib/execution/engine/restTransport.d.ts +46 -0
- package/lib/execution/engine/restTransport.d.ts.map +1 -0
- package/lib/execution/engine/restTransport.js +399 -0
- package/lib/execution/engine/restTransport.js.map +1 -0
- package/lib/execution/engine/sszTypes.d.ts +1261 -0
- package/lib/execution/engine/sszTypes.d.ts.map +1 -0
- package/lib/execution/engine/sszTypes.js +216 -0
- package/lib/execution/engine/sszTypes.js.map +1 -0
- package/lib/execution/engine/transport.d.ts +39 -0
- package/lib/execution/engine/transport.d.ts.map +1 -0
- package/lib/execution/engine/transport.js +2 -0
- package/lib/execution/engine/transport.js.map +1 -0
- package/lib/execution/engine/types.d.ts +2 -8
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +24 -57
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/execution/engine/utils.d.ts.map +1 -1
- package/lib/execution/engine/utils.js +9 -2
- package/lib/execution/engine/utils.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +10 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +22 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/metrics/metrics.d.ts +7 -3
- package/lib/metrics/metrics.d.ts.map +1 -1
- package/lib/metrics/metrics.js +4 -4
- package/lib/metrics/metrics.js.map +1 -1
- package/lib/network/core/events.d.ts +5 -1
- package/lib/network/core/events.d.ts.map +1 -1
- package/lib/network/core/events.js +8 -0
- package/lib/network/core/events.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +0 -14
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +63 -64
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipValidatorFn.d.ts +4 -2
- package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
- package/lib/network/processor/gossipValidatorFn.js +6 -2
- package/lib/network/processor/gossipValidatorFn.js.map +1 -1
- package/lib/network/processor/index.d.ts +8 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +52 -5
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
- package/lib/network/reqresp/rateLimit.js +2 -2
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/subnets/attnetsService.d.ts.map +1 -1
- package/lib/network/subnets/attnetsService.js +3 -1
- package/lib/network/subnets/attnetsService.js.map +1 -1
- package/lib/node/nodejs.d.ts +3 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +27 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.d.ts.map +1 -1
- package/lib/node/notifier.js +12 -13
- package/lib/node/notifier.js.map +1 -1
- package/lib/node/options.d.ts +3 -2
- package/lib/node/options.d.ts.map +1 -1
- package/lib/node/options.js +2 -2
- package/lib/node/options.js.map +1 -1
- package/lib/sync/range/batch.d.ts +11 -5
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +21 -17
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +4 -4
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +12 -6
- 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 +75 -29
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +5 -2
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +52 -26
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +38 -14
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +84 -39
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/util/asyncIterableToEvents.d.ts +10 -2
- package/lib/util/asyncIterableToEvents.d.ts.map +1 -1
- package/lib/util/asyncIterableToEvents.js +29 -3
- package/lib/util/asyncIterableToEvents.js.map +1 -1
- package/lib/util/clock.d.ts.map +1 -1
- package/lib/util/clock.js +3 -4
- package/lib/util/clock.js.map +1 -1
- package/lib/util/execution.d.ts +9 -11
- package/lib/util/execution.d.ts.map +1 -1
- package/lib/util/execution.js +5 -1
- package/lib/util/execution.js.map +1 -1
- package/lib/util/metadata.d.ts.map +1 -1
- package/lib/util/metadata.js +2 -1
- package/lib/util/metadata.js.map +1 -1
- package/lib/util/sszBytes.d.ts +2 -2
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +22 -14
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +18 -17
- package/src/api/impl/beacon/blocks/index.ts +17 -7
- package/src/api/impl/beacon/index.ts +15 -0
- package/src/api/impl/beacon/state/index.ts +43 -6
- package/src/api/impl/debug/index.ts +28 -19
- package/src/api/impl/validator/index.ts +102 -21
- package/src/chain/ColumnReconstructionTracker.ts +4 -6
- package/src/chain/archiveStore/archiveStore.ts +19 -25
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
- package/src/chain/archiveStore/historicalState/types.ts +2 -2
- package/src/chain/archiveStore/historicalState/worker.ts +1 -2
- package/src/chain/archiveStore/interface.ts +1 -1
- package/src/chain/archiveStore/utils/pruneHistory.ts +4 -1
- package/src/chain/beaconProposerCache.ts +19 -1
- package/src/chain/blocks/blockInput/blockInput.ts +1 -1
- package/src/chain/blocks/importBlock.ts +24 -10
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
- package/src/chain/blocks/verifyBlock.ts +8 -6
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
- package/src/chain/chain.ts +135 -37
- package/src/chain/emitter.ts +7 -1
- package/src/chain/errors/envelopeReconstructionError.ts +3 -0
- package/src/chain/errors/gossipValidation.ts +1 -0
- package/src/chain/forkChoice/index.ts +2 -0
- package/src/chain/interface.ts +7 -3
- package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
- package/src/chain/opPools/opPool.ts +1 -31
- package/src/chain/opPools/proposerPreferencesPool.ts +34 -11
- package/src/chain/opPools/utils.ts +31 -0
- package/src/chain/options.ts +3 -3
- package/src/chain/prepareNextSlot.ts +22 -6
- package/src/chain/produceBlock/computeNewStateRoot.ts +10 -3
- package/src/chain/produceBlock/produceBlockBody.ts +78 -39
- package/src/chain/regen/regen.ts +12 -4
- package/src/chain/reprocess.ts +2 -1
- package/src/chain/seenCache/seenGossipBlockInput.ts +25 -1
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
- package/src/chain/shufflingCache.ts +84 -22
- package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
- package/src/chain/validatorMonitor.ts +82 -61
- package/src/constants/constants.ts +1 -0
- package/src/db/beacon.ts +6 -0
- package/src/db/buckets.ts +2 -0
- package/src/db/interface.ts +4 -0
- package/src/db/repositories/blockArchive.ts +2 -2
- package/src/db/repositories/blockArchiveIndex.ts +2 -3
- package/src/db/repositories/earliestAvailableSlot.ts +19 -0
- package/src/db/repositories/index.ts +1 -0
- package/src/db/repositories/proposerPreferences.ts +23 -0
- package/src/execution/engine/blobVersionedHashes.ts +72 -0
- package/src/execution/engine/disabled.ts +0 -8
- package/src/execution/engine/http.ts +304 -300
- package/src/execution/engine/index.ts +41 -7
- package/src/execution/engine/interface.ts +2 -6
- package/src/execution/engine/jsonRpcTransport.ts +247 -0
- package/src/execution/engine/mock.ts +1 -19
- package/src/execution/engine/restHttpClient.ts +269 -0
- package/src/execution/engine/restTransport.ts +544 -0
- package/src/execution/engine/sszTypes.ts +354 -0
- package/src/execution/engine/transport.ts +61 -0
- package/src/execution/engine/types.ts +34 -84
- package/src/execution/engine/utils.ts +12 -2
- package/src/metrics/metrics/lodestar.ts +23 -0
- package/src/metrics/metrics.ts +21 -6
- package/src/network/core/events.ts +16 -1
- package/src/network/processor/gossipHandlers.ts +94 -77
- package/src/network/processor/gossipValidatorFn.ts +12 -2
- package/src/network/processor/index.ts +58 -5
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +1 -1
- package/src/network/reqresp/rateLimit.ts +2 -2
- package/src/network/subnets/attnetsService.ts +8 -3
- package/src/node/nodejs.ts +35 -3
- package/src/node/notifier.ts +14 -13
- package/src/node/options.ts +10 -1
- package/src/sync/range/batch.ts +25 -19
- package/src/sync/range/chain.ts +15 -8
- package/src/sync/range/range.ts +76 -30
- package/src/sync/unknownBlock.ts +65 -27
- package/src/sync/utils/downloadByRange.ts +123 -58
- package/src/util/asyncIterableToEvents.ts +44 -5
- package/src/util/clock.ts +3 -4
- package/src/util/execution.ts +16 -8
- package/src/util/metadata.ts +2 -1
- package/src/util/sszBytes.ts +25 -12
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
BUILDER_INDEX_SELF_BUILD,
|
|
6
6
|
ForkName,
|
|
7
7
|
ForkPostBellatrix,
|
|
8
|
+
ForkPostDeneb,
|
|
9
|
+
ForkPreDeneb,
|
|
8
10
|
ForkPreGloas,
|
|
9
11
|
ForkSeq,
|
|
10
12
|
GENESIS_SLOT,
|
|
@@ -111,14 +113,13 @@ import {
|
|
|
111
113
|
* Post this time, race execution and builder to pick whatever resolves first.
|
|
112
114
|
*
|
|
113
115
|
* Empirically the builder block resolves in ~1 second, and execution block resolves in <500 ms.
|
|
114
|
-
* A cutoff of 2 seconds gives enough time and if there are unexpected delays
|
|
115
|
-
* in time as proposals
|
|
116
|
+
* A cutoff of 1667 BPS (2 seconds for 12s slots) gives enough time and if there are unexpected delays
|
|
117
|
+
* it ensures we publish in time as proposals after the attestation deadline will likely be orphaned
|
|
118
|
+
* due to proposer boost reorg.
|
|
116
119
|
*
|
|
117
120
|
* TODO GLOAS: re-evaluate cutoff timing due to attestation deadline changes in gloas
|
|
118
121
|
*/
|
|
119
|
-
const
|
|
120
|
-
/** Overall timeout for execution and block production apis */
|
|
121
|
-
const BLOCK_PRODUCTION_RACE_TIMEOUT_MS = 12_000;
|
|
122
|
+
const BLOCK_PRODUCTION_RACE_CUTOFF_BPS = 1667;
|
|
122
123
|
/** Rejection message of the bid block branch when there is no viable bid to commit to */
|
|
123
124
|
const NO_BID_AVAILABLE = "No builder bid available";
|
|
124
125
|
|
|
@@ -167,8 +168,8 @@ function compareBidCandidates(a: BidCandidate, b: BidCandidate): number {
|
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
type ProduceBlockContentsRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
|
|
170
|
-
data: BlockContents
|
|
171
|
-
version:
|
|
171
|
+
data: BlockContents<ForkPreGloas>;
|
|
172
|
+
version: ForkPreGloas;
|
|
172
173
|
};
|
|
173
174
|
type ProduceBlindedBlockRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
|
|
174
175
|
data: BlindedBeaconBlock;
|
|
@@ -189,6 +190,7 @@ export enum EngineBlockSelectionReason {
|
|
|
189
190
|
BuilderTimeout = "builder_timeout",
|
|
190
191
|
BuilderPending = "builder_pending",
|
|
191
192
|
BuilderNoBid = "builder_no_bid",
|
|
193
|
+
BuilderCircuitBreaker = "builder_circuit_breaker",
|
|
192
194
|
BuilderCensorship = "builder_censorship",
|
|
193
195
|
BlockValue = "block_value",
|
|
194
196
|
EnginePreferred = "engine_preferred",
|
|
@@ -300,8 +302,8 @@ export function getValidatorApi(
|
|
|
300
302
|
*/
|
|
301
303
|
function msToNextEpoch(): number {
|
|
302
304
|
const nextEpoch = chain.clock.currentEpoch + 1;
|
|
303
|
-
const
|
|
304
|
-
const nextEpochStartSec = chain.genesisTime
|
|
305
|
+
const nextEpochSlot = computeStartSlotAtEpoch(nextEpoch);
|
|
306
|
+
const nextEpochStartSec = computeTimeAtSlot(config, nextEpochSlot, chain.genesisTime);
|
|
305
307
|
return nextEpochStartSec * 1000 - Date.now();
|
|
306
308
|
}
|
|
307
309
|
|
|
@@ -510,6 +512,10 @@ export function getValidatorApi(
|
|
|
510
512
|
parentBlock: ProtoBlock;
|
|
511
513
|
}
|
|
512
514
|
): Promise<ProduceBlockContentsRes & {shouldOverrideBuilder?: boolean}> {
|
|
515
|
+
const version = config.getForkName(slot);
|
|
516
|
+
if (isForkPostGloas(version)) {
|
|
517
|
+
throw Error(`produceEngineBlockContents called for post-gloas fork=${version}`);
|
|
518
|
+
}
|
|
513
519
|
const source = ProducedBlockSource.engine;
|
|
514
520
|
metrics?.blockProductionRequests.inc({source});
|
|
515
521
|
|
|
@@ -524,7 +530,6 @@ export function getValidatorApi(
|
|
|
524
530
|
feeRecipient,
|
|
525
531
|
commonBlockBodyPromise,
|
|
526
532
|
});
|
|
527
|
-
const version = config.getForkName(block.slot);
|
|
528
533
|
if (strictFeeRecipientCheck && feeRecipient && isForkPostBellatrix(version)) {
|
|
529
534
|
const blockFeeRecipient = toHex((block as bellatrix.BeaconBlock).body.executionPayload.feeRecipient);
|
|
530
535
|
if (blockFeeRecipient !== feeRecipient) {
|
|
@@ -562,7 +567,7 @@ export function getValidatorApi(
|
|
|
562
567
|
|
|
563
568
|
return {
|
|
564
569
|
data: {
|
|
565
|
-
block
|
|
570
|
+
block: block as BeaconBlock<ForkPostDeneb & ForkPreGloas>,
|
|
566
571
|
blobs: blobsBundle.blobs,
|
|
567
572
|
kzgProofs: blobsBundle.proofs,
|
|
568
573
|
},
|
|
@@ -573,7 +578,13 @@ export function getValidatorApi(
|
|
|
573
578
|
};
|
|
574
579
|
}
|
|
575
580
|
|
|
576
|
-
return {
|
|
581
|
+
return {
|
|
582
|
+
data: {block: block as BeaconBlock<ForkPreDeneb>},
|
|
583
|
+
version,
|
|
584
|
+
executionPayloadValue,
|
|
585
|
+
consensusBlockValue,
|
|
586
|
+
shouldOverrideBuilder,
|
|
587
|
+
};
|
|
577
588
|
} finally {
|
|
578
589
|
if (timer) timer({source});
|
|
579
590
|
}
|
|
@@ -679,17 +690,21 @@ export function getValidatorApi(
|
|
|
679
690
|
});
|
|
680
691
|
|
|
681
692
|
// Calculate cutoff time based on start of the slot
|
|
682
|
-
const cutoffMs = Math.max(
|
|
693
|
+
const cutoffMs = Math.max(
|
|
694
|
+
0,
|
|
695
|
+
config.getSlotComponentDurationMs(fork, BLOCK_PRODUCTION_RACE_CUTOFF_BPS) - chain.clock.msFromSlot(slot)
|
|
696
|
+
);
|
|
697
|
+
const blockProductionTimeoutMs = config.getSlotDurationMs(fork);
|
|
683
698
|
|
|
684
699
|
logger.verbose("Block production race (builder vs execution) starting", {
|
|
685
700
|
...loggerContext,
|
|
686
701
|
cutoffMs,
|
|
687
|
-
timeoutMs:
|
|
702
|
+
timeoutMs: blockProductionTimeoutMs,
|
|
688
703
|
});
|
|
689
704
|
|
|
690
705
|
const blockProductionRacePromise = resolveOrRacePromises([builderPromise, enginePromise], {
|
|
691
706
|
resolveTimeoutMs: cutoffMs,
|
|
692
|
-
raceTimeoutMs:
|
|
707
|
+
raceTimeoutMs: blockProductionTimeoutMs,
|
|
693
708
|
signal: controller.signal,
|
|
694
709
|
});
|
|
695
710
|
|
|
@@ -877,6 +892,10 @@ export function getValidatorApi(
|
|
|
877
892
|
|
|
878
893
|
return {
|
|
879
894
|
async produceBlockV3({slot, randaoReveal, graffiti, skipRandaoVerification, builderBoostFactor, ...opts}) {
|
|
895
|
+
const forkName = config.getForkName(slot);
|
|
896
|
+
if (isForkPostGloas(forkName)) {
|
|
897
|
+
throw new ApiError(400, `produceBlockV3 not supported for post-gloas fork=${forkName}, use produceBlockV4`);
|
|
898
|
+
}
|
|
880
899
|
const {data, ...meta} = await produceEngineOrBuilderBlock(
|
|
881
900
|
slot,
|
|
882
901
|
randaoReveal,
|
|
@@ -1094,7 +1113,10 @@ export function getValidatorApi(
|
|
|
1094
1113
|
|
|
1095
1114
|
// Calculate cutoff time based on start of the slot, ensures a slow local payload build does
|
|
1096
1115
|
// not delay the proposal when a builder bid block is available (and vice versa)
|
|
1097
|
-
const cutoffMs = Math.max(
|
|
1116
|
+
const cutoffMs = Math.max(
|
|
1117
|
+
0,
|
|
1118
|
+
config.getSlotComponentDurationMs(fork, BLOCK_PRODUCTION_RACE_CUTOFF_BPS) - chain.clock.msFromSlot(slot)
|
|
1119
|
+
);
|
|
1098
1120
|
|
|
1099
1121
|
// use abort controller to stop waiting for the bid block if the engine block will be selected
|
|
1100
1122
|
const controller = new AbortController();
|
|
@@ -1122,7 +1144,7 @@ export function getValidatorApi(
|
|
|
1122
1144
|
|
|
1123
1145
|
const [engineResult, bidBlockResult] = await resolveOrRacePromises([enginePromise, bidBlockPromise], {
|
|
1124
1146
|
resolveTimeoutMs: cutoffMs,
|
|
1125
|
-
raceTimeoutMs:
|
|
1147
|
+
raceTimeoutMs: config.getSlotDurationMs(fork),
|
|
1126
1148
|
signal: controller.signal,
|
|
1127
1149
|
});
|
|
1128
1150
|
|
|
@@ -1160,8 +1182,21 @@ export function getValidatorApi(
|
|
|
1160
1182
|
: {}),
|
|
1161
1183
|
};
|
|
1162
1184
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1185
|
+
if (circuitBreakerActive && engineResult.status === "fulfilled") {
|
|
1186
|
+
source = ProducedBlockSource.engine;
|
|
1187
|
+
bestResult = engineResult;
|
|
1188
|
+
metrics?.blockProductionSelectionResults.inc({
|
|
1189
|
+
source: ProducedBlockSource.engine,
|
|
1190
|
+
reason: EngineBlockSelectionReason.BuilderCircuitBreaker,
|
|
1191
|
+
});
|
|
1192
|
+
logger.info("Selected local block: builder circuit breaker is active", {
|
|
1193
|
+
reason: EngineBlockSelectionReason.BuilderCircuitBreaker,
|
|
1194
|
+
...logCtx,
|
|
1195
|
+
durationMs: engineResult.durationMs,
|
|
1196
|
+
...getBlockValueLogInfo(engineResult.value),
|
|
1197
|
+
});
|
|
1198
|
+
} else if (
|
|
1199
|
+
// handle shouldOverrideBuilder separately
|
|
1165
1200
|
engineResult.status === "fulfilled" &&
|
|
1166
1201
|
engineResult.value.shouldOverrideBuilder &&
|
|
1167
1202
|
(builderBidExpected || bidBlockResult.status === "fulfilled")
|
|
@@ -1286,6 +1321,10 @@ export function getValidatorApi(
|
|
|
1286
1321
|
blobs: blobsBundle.blobs,
|
|
1287
1322
|
};
|
|
1288
1323
|
|
|
1324
|
+
if (chain.opts.persistProducedPayloadEnvelopes) {
|
|
1325
|
+
chain.persistExecutionPayloadEnvelope(blockContents.executionPayloadEnvelope);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1289
1328
|
return {
|
|
1290
1329
|
data: blockContents,
|
|
1291
1330
|
meta: {version: fork, consensusBlockValue, executionPayloadValue, executionPayloadIncluded: true},
|
|
@@ -1399,7 +1438,7 @@ export function getValidatorApi(
|
|
|
1399
1438
|
// Spec: set payload_present only if the envelope was seen before get_payload_due_ms()
|
|
1400
1439
|
// into the slot. Use the envelope's own arrival time (getPayloadEnvelopeSource), not
|
|
1401
1440
|
// the input's creation time.
|
|
1402
|
-
const payloadDueSec = config.getPayloadDueMs() / 1000;
|
|
1441
|
+
const payloadDueSec = config.getPayloadDueMs(fork) / 1000;
|
|
1403
1442
|
const payloadSeenSec =
|
|
1404
1443
|
payloadInput?.hasPayloadEnvelope() === true
|
|
1405
1444
|
? chain.clock.secFromSlot(slot, payloadInput.getPayloadEnvelopeSource().seenTimestampSec)
|
|
@@ -1476,8 +1515,9 @@ export function getValidatorApi(
|
|
|
1476
1515
|
const currentEpoch = currentEpochWithDisparity();
|
|
1477
1516
|
const nextEpoch = currentEpoch + 1;
|
|
1478
1517
|
const startSlot = computeStartSlotAtEpoch(epoch);
|
|
1518
|
+
const prepareFork = config.getForkName(computeStartSlotAtEpoch(nextEpoch) - 1);
|
|
1479
1519
|
const prepareNextSlotLookAheadMs =
|
|
1480
|
-
config.
|
|
1520
|
+
config.getSlotDurationMs(prepareFork) - config.getSlotComponentDurationMs(prepareFork, PREPARE_NEXT_SLOT_BPS);
|
|
1481
1521
|
const toNextEpochMs = msToNextEpoch();
|
|
1482
1522
|
const nearNextEpoch = toNextEpochMs < prepareNextSlotLookAheadMs;
|
|
1483
1523
|
// Post-Fulu the proposer lookahead is deterministic and known a full epoch ahead, so
|
|
@@ -1914,6 +1954,17 @@ export function getValidatorApi(
|
|
|
1914
1954
|
},
|
|
1915
1955
|
|
|
1916
1956
|
async prepareBeaconCommitteeSubnet({subscriptions}) {
|
|
1957
|
+
// The subscribing validators use this node for duties regardless of its sync state and
|
|
1958
|
+
// the subscription must not fail on the tracking, e.g. if the finalized state is unavailable
|
|
1959
|
+
try {
|
|
1960
|
+
await chain.updateAttachedValidators(
|
|
1961
|
+
chain.clock.currentEpoch,
|
|
1962
|
+
Array.from(new Set(subscriptions.map(({validatorIndex}) => validatorIndex)))
|
|
1963
|
+
);
|
|
1964
|
+
} catch (e) {
|
|
1965
|
+
logger.warn("Error tracking attached validators", {count: subscriptions.length}, e as Error);
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1917
1968
|
notWhileSyncing(chain, sync.state);
|
|
1918
1969
|
|
|
1919
1970
|
await network.prepareBeaconCommitteeSubnets(
|
|
@@ -1977,6 +2028,13 @@ export function getValidatorApi(
|
|
|
1977
2028
|
},
|
|
1978
2029
|
|
|
1979
2030
|
async prepareBeaconProposer({proposers}) {
|
|
2031
|
+
if (isForkPostGloas(config.getForkName(chain.clock.currentSlot))) {
|
|
2032
|
+
throw new ApiError(
|
|
2033
|
+
410,
|
|
2034
|
+
"prepareBeaconProposer is no longer supported from gloas, submit signed proposer preferences via POST /eth/v1/validator/proposer_preferences instead"
|
|
2035
|
+
);
|
|
2036
|
+
}
|
|
2037
|
+
|
|
1980
2038
|
await chain.updateBeaconProposerData(chain.clock.currentEpoch, proposers);
|
|
1981
2039
|
},
|
|
1982
2040
|
|
|
@@ -2011,6 +2069,13 @@ export function getValidatorApi(
|
|
|
2011
2069
|
},
|
|
2012
2070
|
|
|
2013
2071
|
async registerValidator({registrations}) {
|
|
2072
|
+
if (isForkPostGloas(config.getForkName(chain.clock.currentSlot))) {
|
|
2073
|
+
throw new ApiError(
|
|
2074
|
+
410,
|
|
2075
|
+
"registerValidator is no longer supported from gloas, submit builder preferences via POST /eth/v1/validator/builder_preferences instead"
|
|
2076
|
+
);
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2014
2079
|
if (!chain.executionBuilder) {
|
|
2015
2080
|
throw Error("External builder not configured");
|
|
2016
2081
|
}
|
|
@@ -2046,11 +2111,14 @@ export function getValidatorApi(
|
|
|
2046
2111
|
|
|
2047
2112
|
async submitProposerPreferences({signedProposerPreferences}) {
|
|
2048
2113
|
const failures: FailureList = [];
|
|
2114
|
+
// Preferences submitted here are signed by validators using this node, gossiped ones are not
|
|
2115
|
+
const attachedValidatorIndices: ValidatorIndex[] = [];
|
|
2049
2116
|
|
|
2050
2117
|
await Promise.all(
|
|
2051
2118
|
signedProposerPreferences.map(async (signed, i) => {
|
|
2052
2119
|
try {
|
|
2053
2120
|
await validateGossipProposerPreferences(chain, signed);
|
|
2121
|
+
attachedValidatorIndices.push(signed.message.validatorIndex);
|
|
2054
2122
|
|
|
2055
2123
|
chain.proposerPreferencesPool.add(signed);
|
|
2056
2124
|
await network.publishProposerPreferences(signed);
|
|
@@ -2066,6 +2134,7 @@ export function getValidatorApi(
|
|
|
2066
2134
|
};
|
|
2067
2135
|
|
|
2068
2136
|
if (e instanceof ProposerPreferencesError && e.type.code === ProposerPreferencesErrorCode.ALREADY_KNOWN) {
|
|
2137
|
+
attachedValidatorIndices.push(signed.message.validatorIndex);
|
|
2069
2138
|
logger.debug("Ignoring known signed proposer preferences", logCtx);
|
|
2070
2139
|
return;
|
|
2071
2140
|
}
|
|
@@ -2079,6 +2148,14 @@ export function getValidatorApi(
|
|
|
2079
2148
|
})
|
|
2080
2149
|
);
|
|
2081
2150
|
|
|
2151
|
+
if (attachedValidatorIndices.length > 0) {
|
|
2152
|
+
try {
|
|
2153
|
+
await chain.updateAttachedValidators(chain.clock.currentEpoch, attachedValidatorIndices);
|
|
2154
|
+
} catch (e) {
|
|
2155
|
+
logger.warn("Error tracking attached validators", {count: attachedValidatorIndices.length}, e as Error);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2082
2159
|
if (failures.length > 0) {
|
|
2083
2160
|
throw new IndexedError("Error processing signed proposer preferences", failures);
|
|
2084
2161
|
}
|
|
@@ -2173,6 +2250,10 @@ export function getValidatorApi(
|
|
|
2173
2250
|
blockHash: toRootHex(executionPayload.blockHash),
|
|
2174
2251
|
});
|
|
2175
2252
|
|
|
2253
|
+
if (chain.opts.persistProducedPayloadEnvelopes) {
|
|
2254
|
+
chain.persistExecutionPayloadEnvelope(envelope);
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2176
2257
|
return {
|
|
2177
2258
|
data: envelope,
|
|
2178
2259
|
meta: {
|
|
@@ -42,16 +42,11 @@ export class ColumnReconstructionTracker {
|
|
|
42
42
|
/** Track if a reconstruction attempt is in-flight */
|
|
43
43
|
running = false;
|
|
44
44
|
|
|
45
|
-
private readonly minDelayMs: number;
|
|
46
|
-
private readonly maxDelayMs: number;
|
|
47
|
-
|
|
48
45
|
constructor(init: ColumnReconstructionTrackerInit) {
|
|
49
46
|
this.logger = init.logger;
|
|
50
47
|
this.emitter = init.emitter;
|
|
51
48
|
this.metrics = init.metrics;
|
|
52
49
|
this.config = init.config;
|
|
53
|
-
this.minDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MIN_BPS);
|
|
54
|
-
this.maxDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MAX_BPS);
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
triggerColumnReconstruction(input: BlockInputColumns | PayloadEnvelopeInput): void {
|
|
@@ -67,7 +62,10 @@ export class ColumnReconstructionTracker {
|
|
|
67
62
|
// just that it has been triggered for this block root.
|
|
68
63
|
this.running = true;
|
|
69
64
|
this.lastBlockRootHex = input.blockRootHex;
|
|
70
|
-
const
|
|
65
|
+
const fork = this.config.getForkName(input.slot);
|
|
66
|
+
const minDelayMs = this.config.getSlotComponentDurationMs(fork, RECONSTRUCTION_DELAY_MIN_BPS);
|
|
67
|
+
const maxDelayMs = this.config.getSlotComponentDurationMs(fork, RECONSTRUCTION_DELAY_MAX_BPS);
|
|
68
|
+
const delay = minDelayMs + Math.random() * (maxDelayMs - minDelayMs);
|
|
71
69
|
sleep(delay)
|
|
72
70
|
.then(() => {
|
|
73
71
|
const logCtx = {slot: input.slot, root: input.blockRootHex};
|
|
@@ -113,7 +113,9 @@ export class ArchiveStore {
|
|
|
113
113
|
this.logger,
|
|
114
114
|
this.metrics,
|
|
115
115
|
this.opts.anchorState.finalizedCheckpoint.epoch,
|
|
116
|
-
this.chain.clock.currentEpoch
|
|
116
|
+
this.chain.clock.currentEpoch,
|
|
117
|
+
this.statePruneFromSlot,
|
|
118
|
+
this.advanceEarliestAvailableSlot
|
|
117
119
|
),
|
|
118
120
|
() => this.logger.info("Still pruning historical data, please wait..."),
|
|
119
121
|
30_000,
|
|
@@ -122,33 +124,13 @@ export class ArchiveStore {
|
|
|
122
124
|
this.statePruneFromSlot = stateCutoffSlot;
|
|
123
125
|
}
|
|
124
126
|
|
|
125
|
-
// Initialize earliestAvailableSlot from the earliest block actually retained (after any pruning
|
|
126
|
-
// above), rather than the anchor state slot set in the constructor. On an in-place restart the DB
|
|
127
|
-
// still holds finalized history below the anchor; leaving the value at the anchor makes the node
|
|
128
|
-
// reject by_range requests (beacon_blocks, execution_payload_envelopes and data_column_sidecars
|
|
129
|
-
// all gate on this slot) for data it still retains. An empty archive (e.g. a fresh checkpoint
|
|
130
|
-
// sync with nothing below the anchor) leaves the constructor's anchor slot in place.
|
|
131
|
-
const earliestArchivedBlockSlot = await this.db.blockArchive.firstKey();
|
|
132
|
-
if (earliestArchivedBlockSlot != null) {
|
|
133
|
-
const oldEarliestAvailableSlot = this.chain.earliestAvailableSlot;
|
|
134
|
-
this.chain.earliestAvailableSlot = earliestArchivedBlockSlot;
|
|
135
|
-
this.logger.verbose("Initialized earliestAvailableSlot from retained block archive", {
|
|
136
|
-
oldEarliestAvailableSlot,
|
|
137
|
-
newEarliestAvailableSlot: earliestArchivedBlockSlot,
|
|
138
|
-
});
|
|
139
|
-
} else {
|
|
140
|
-
this.logger.verbose("Empty block archive on init, keeping anchor earliestAvailableSlot", {
|
|
141
|
-
earliestAvailableSlot: this.chain.earliestAvailableSlot,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
127
|
if (this.opts.serveHistoricalState) {
|
|
146
128
|
this.historicalStateRegen = await HistoricalStateRegen.init({
|
|
147
129
|
opts: {
|
|
148
130
|
genesisTime: this.chain.clock.genesisTime,
|
|
149
131
|
dbLocation: this.opts.dbName,
|
|
150
132
|
dataColumnDir: this.opts.dataColumnDir,
|
|
151
|
-
|
|
133
|
+
nativeStateTransition: this.opts.nativeStateTransition ?? false,
|
|
152
134
|
},
|
|
153
135
|
config: this.chain.config,
|
|
154
136
|
metrics: this.metrics,
|
|
@@ -158,6 +140,18 @@ export class ArchiveStore {
|
|
|
158
140
|
}
|
|
159
141
|
}
|
|
160
142
|
|
|
143
|
+
/**
|
|
144
|
+
* The CLI owns the initial value; this only advances it during pruneHistory.
|
|
145
|
+
* Persisted before any deletion so a crash mid-prune never leaves the floor below deleted data.
|
|
146
|
+
*/
|
|
147
|
+
private advanceEarliestAvailableSlot = async (blockCutoffSlot: Slot): Promise<void> => {
|
|
148
|
+
const earliestAvailableSlot = Math.max(this.chain.earliestAvailableSlot, blockCutoffSlot);
|
|
149
|
+
if (earliestAvailableSlot !== this.chain.earliestAvailableSlot) {
|
|
150
|
+
await this.db.earliestAvailableSlot.set(earliestAvailableSlot);
|
|
151
|
+
this.chain.earliestAvailableSlot = earliestAvailableSlot;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
161
155
|
async close(): Promise<void> {
|
|
162
156
|
await this.historicalStateRegen?.close();
|
|
163
157
|
}
|
|
@@ -259,17 +253,17 @@ export class ArchiveStore {
|
|
|
259
253
|
|
|
260
254
|
if (this.opts.pruneHistory) {
|
|
261
255
|
timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
|
|
262
|
-
const {
|
|
256
|
+
const {stateCutoffSlot} = await pruneHistory(
|
|
263
257
|
this.chain.config,
|
|
264
258
|
this.db,
|
|
265
259
|
this.logger,
|
|
266
260
|
this.metrics,
|
|
267
261
|
finalizedEpoch,
|
|
268
262
|
this.chain.clock.currentEpoch,
|
|
269
|
-
this.statePruneFromSlot
|
|
263
|
+
this.statePruneFromSlot,
|
|
264
|
+
this.advanceEarliestAvailableSlot
|
|
270
265
|
);
|
|
271
266
|
this.statePruneFromSlot = stateCutoffSlot;
|
|
272
|
-
this.chain.earliestAvailableSlot = Math.max(this.chain.earliestAvailableSlot, blockCutoffSlot);
|
|
273
267
|
timer?.({source: ArchiveStoreTask.PruneHistory});
|
|
274
268
|
}
|
|
275
269
|
|
|
@@ -17,7 +17,7 @@ export async function getNearestState(
|
|
|
17
17
|
slot: number,
|
|
18
18
|
config: BeaconConfig,
|
|
19
19
|
db: IBeaconDb,
|
|
20
|
-
|
|
20
|
+
nativeStateTransition: boolean
|
|
21
21
|
): Promise<IBeaconStateView> {
|
|
22
22
|
const stateBytesArr = await db.stateArchive.binaries({limit: 1, lte: slot, reverse: true});
|
|
23
23
|
if (!stateBytesArr.length) {
|
|
@@ -25,9 +25,7 @@ export async function getNearestState(
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const stateBytes = stateBytesArr[0];
|
|
28
|
-
return
|
|
29
|
-
? createBeaconStateViewForHistoricalRegen({useNative: true, stateBytes})
|
|
30
|
-
: createBeaconStateViewForHistoricalRegen({useNative: false, config, stateBytes});
|
|
28
|
+
return createBeaconStateViewForHistoricalRegen({nativeStateTransition: nativeStateTransition, config, stateBytes});
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
/**
|
|
@@ -37,13 +35,13 @@ export async function getHistoricalState(
|
|
|
37
35
|
slot: number,
|
|
38
36
|
config: BeaconConfig,
|
|
39
37
|
db: IBeaconDb,
|
|
40
|
-
|
|
38
|
+
nativeStateTransition: boolean,
|
|
41
39
|
metrics?: HistoricalStateRegenMetrics
|
|
42
40
|
): Promise<Uint8Array> {
|
|
43
41
|
const regenTimer = metrics?.regenTime.startTimer();
|
|
44
42
|
|
|
45
43
|
const loadStateTimer = metrics?.loadStateTime.startTimer();
|
|
46
|
-
let state = await getNearestState(slot, config, db,
|
|
44
|
+
let state = await getNearestState(slot, config, db, nativeStateTransition).catch((e) => {
|
|
47
45
|
metrics?.regenErrorCount.inc({reason: RegenErrorType.loadState});
|
|
48
46
|
throw e;
|
|
49
47
|
});
|
|
@@ -54,7 +52,7 @@ export async function getHistoricalState(
|
|
|
54
52
|
for await (const block of db.blockArchive.valuesStream({gt: state.slot, lte: slot})) {
|
|
55
53
|
try {
|
|
56
54
|
state = state.stateTransition(
|
|
57
|
-
block,
|
|
55
|
+
{block},
|
|
58
56
|
{
|
|
59
57
|
verifyProposer: false,
|
|
60
58
|
verifySignatures: false,
|
|
@@ -36,7 +36,7 @@ export class HistoricalStateRegen implements HistoricalStateWorkerApi {
|
|
|
36
36
|
dataColumnDir: modules.opts.dataColumnDir,
|
|
37
37
|
metricsEnabled: Boolean(modules.metrics),
|
|
38
38
|
loggerOpts: modules.logger.toOpts(),
|
|
39
|
-
|
|
39
|
+
nativeStateTransition: modules.opts.nativeStateTransition,
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const worker = new Worker(path.join(WORKER_DIR, "worker.js"), {
|
|
@@ -8,7 +8,7 @@ export type HistoricalStateRegenInitModules = {
|
|
|
8
8
|
genesisTime: number;
|
|
9
9
|
dbLocation: string;
|
|
10
10
|
dataColumnDir: string;
|
|
11
|
-
|
|
11
|
+
nativeStateTransition: boolean;
|
|
12
12
|
};
|
|
13
13
|
config: BeaconConfig;
|
|
14
14
|
logger: LoggerNode;
|
|
@@ -29,7 +29,7 @@ export type HistoricalStateWorkerData = {
|
|
|
29
29
|
dataColumnDir: string;
|
|
30
30
|
metricsEnabled: boolean;
|
|
31
31
|
loggerOpts: LoggerNodeOpts;
|
|
32
|
-
|
|
32
|
+
nativeStateTransition: boolean;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export type HistoricalStateWorkerApi = {
|
|
@@ -36,7 +36,6 @@ const abortController = new AbortController();
|
|
|
36
36
|
const metricsRegister = workerData.metricsEnabled ? new RegistryMetricCreator() : null;
|
|
37
37
|
let historicalStateRegenMetrics: HistoricalStateRegenMetrics | undefined;
|
|
38
38
|
let queueMetrics: QueueMetrics | undefined;
|
|
39
|
-
|
|
40
39
|
if (metricsRegister) {
|
|
41
40
|
const closeMetrics = collectNodeJSMetrics(metricsRegister, "lodestar_historical_state_worker_");
|
|
42
41
|
abortController.signal.addEventListener("abort", closeMetrics, {once: true});
|
|
@@ -65,7 +64,7 @@ const api: HistoricalStateWorkerApi = {
|
|
|
65
64
|
historicalStateRegenMetrics?.regenRequestCount.inc();
|
|
66
65
|
|
|
67
66
|
const stateBytes = await queue.push<Uint8Array>(() =>
|
|
68
|
-
getHistoricalState(slot, config, db, workerData.
|
|
67
|
+
getHistoricalState(slot, config, db, workerData.nativeStateTransition, historicalStateRegenMetrics)
|
|
69
68
|
);
|
|
70
69
|
const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
|
|
71
70
|
|
|
@@ -12,7 +12,8 @@ export async function pruneHistory(
|
|
|
12
12
|
metrics: Metrics | null | undefined,
|
|
13
13
|
finalizedEpoch: Epoch,
|
|
14
14
|
currentEpoch: Epoch,
|
|
15
|
-
statePruneFromSlot: Slot
|
|
15
|
+
statePruneFromSlot: Slot,
|
|
16
|
+
beforePrune: (blockCutoffSlot: Slot) => Promise<void>
|
|
16
17
|
): Promise<{blockCutoffSlot: Slot; stateCutoffSlot: Slot}> {
|
|
17
18
|
const blockCutoffEpoch = Math.min(
|
|
18
19
|
// set by config, with underflow protection
|
|
@@ -51,6 +52,8 @@ export async function pruneHistory(
|
|
|
51
52
|
stateSlots: prettyPrintIndices(states),
|
|
52
53
|
});
|
|
53
54
|
|
|
55
|
+
await beforePrune(blockCutoffSlot);
|
|
56
|
+
|
|
54
57
|
const step1 = metrics?.pruneHistory.pruneKeys.startTimer();
|
|
55
58
|
await Promise.all([
|
|
56
59
|
// ->
|
|
@@ -6,7 +6,7 @@ const PROPOSER_PRESERVE_EPOCHS = 2;
|
|
|
6
6
|
export type ProposerPreparationData = routes.validator.ProposerPreparationData;
|
|
7
7
|
|
|
8
8
|
export class BeaconProposerCache {
|
|
9
|
-
private readonly feeRecipientByValidatorIndex: Map<number, {epoch: Epoch; feeRecipient
|
|
9
|
+
private readonly feeRecipientByValidatorIndex: Map<number, {epoch: Epoch; feeRecipient?: string}>;
|
|
10
10
|
constructor(readonly opts: {suggestedFeeRecipient: string}) {
|
|
11
11
|
this.feeRecipientByValidatorIndex = new Map();
|
|
12
12
|
}
|
|
@@ -15,6 +15,24 @@ export class BeaconProposerCache {
|
|
|
15
15
|
this.feeRecipientByValidatorIndex.set(validatorIndex, {epoch, feeRecipient});
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Track a validator that uses this node for duties, keeping the fee recipient it may have
|
|
20
|
+
* registered. Returns true if the validator was not tracked before.
|
|
21
|
+
*/
|
|
22
|
+
track(epoch: Epoch, validatorIndex: number): boolean {
|
|
23
|
+
const entry = this.feeRecipientByValidatorIndex.get(validatorIndex);
|
|
24
|
+
if (entry !== undefined) {
|
|
25
|
+
entry.epoch = epoch;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
this.feeRecipientByValidatorIndex.set(validatorIndex, {epoch});
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
has(validatorIndex: number): boolean {
|
|
33
|
+
return this.feeRecipientByValidatorIndex.has(validatorIndex);
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
prune(epoch: Epoch): void {
|
|
19
37
|
// This is not so optimized function, but could maintain a 2d array may be?
|
|
20
38
|
for (const [validatorIndex, feeRecipientEntry] of this.feeRecipientByValidatorIndex.entries()) {
|
|
@@ -210,7 +210,7 @@ export class BlockInputPreData extends AbstractBlockInput<ForkPreDeneb, null> {
|
|
|
210
210
|
this.blockPromise.resolve(state.block);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
static createFromBlock(props: AddBlock & CreateBlockInputMeta): BlockInputPreData {
|
|
213
|
+
static createFromBlock(props: AddBlock<ForkPreDeneb> & CreateBlockInputMeta): BlockInputPreData {
|
|
214
214
|
const init: BlockInputInit = {
|
|
215
215
|
daOutOfRange: props.daOutOfRange,
|
|
216
216
|
timeCreated: props.seenTimestampSec,
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
RootCache,
|
|
23
23
|
computeEpochAtSlot,
|
|
24
24
|
computeTimeAtSlot,
|
|
25
|
+
getBeaconCommittees,
|
|
25
26
|
isStatePostAltair,
|
|
26
27
|
isStatePostBellatrix,
|
|
27
28
|
} from "@lodestar/state-transition";
|
|
@@ -44,7 +45,7 @@ import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
|
44
45
|
import type {BeaconChain} from "../chain.js";
|
|
45
46
|
import {ChainEvent, ReorgEventData} from "../emitter.js";
|
|
46
47
|
import {ForkchoiceCaller} from "../forkChoice/index.js";
|
|
47
|
-
import {
|
|
48
|
+
import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS} from "../reprocess.js";
|
|
48
49
|
import {toCheckpointHex} from "../stateCache/persistentCheckpointsCache.js";
|
|
49
50
|
import {isBlockInputBlobs, isBlockInputColumns} from "./blockInput/blockInput.js";
|
|
50
51
|
import {AttestationImportOpt, FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
|
|
@@ -129,11 +130,17 @@ export async function importBlock(
|
|
|
129
130
|
|
|
130
131
|
// Should compute checkpoint balances before forkchoice.onBlock
|
|
131
132
|
this.checkpointBalancesCache.processState(blockRootHex, postState);
|
|
132
|
-
if (
|
|
133
|
+
if (isGloasBeaconBlock(block.message)) {
|
|
134
|
+
// A gloas block has no payload of its own, it inherits the status of the payload it builds on,
|
|
135
|
+
// i.e. the parent variant matching the bid's parent block hash. The parent's default (PENDING)
|
|
136
|
+
// variant does not reflect a SYNCING parent payload, and onBlock would then mark that payload VALID.
|
|
133
137
|
const parentRootHex = toRootHex(block.message.parentRoot);
|
|
134
|
-
const
|
|
138
|
+
const parentBlockHashHex = toRootHex(block.message.body.signedExecutionPayloadBid.message.parentBlockHash);
|
|
139
|
+
const parentBlock = this.forkChoice.getBlockHexAndBlockHash(parentRootHex, parentBlockHashHex);
|
|
135
140
|
if (parentBlock === null) {
|
|
136
|
-
throw Error(
|
|
141
|
+
throw Error(
|
|
142
|
+
`Parent block not found in forkChoice, parentRoot=${parentRootHex} parentBlockHash=${parentBlockHashHex}`
|
|
143
|
+
);
|
|
137
144
|
}
|
|
138
145
|
if (parentBlock.executionStatus === ExecutionStatus.Invalid) {
|
|
139
146
|
throw Error(`Parent block has invalid execution status, parentRoot=${parentRootHex}`);
|
|
@@ -328,7 +335,8 @@ export async function importBlock(
|
|
|
328
335
|
this.metrics.headSlot.set(newHead.slot);
|
|
329
336
|
// Only track "recent" blocks. Otherwise sync can distort this metrics heavily.
|
|
330
337
|
// We want to track recent blocks coming from gossip, unknown block sync, and API.
|
|
331
|
-
|
|
338
|
+
const headFork = this.config.getForkName(newHead.slot);
|
|
339
|
+
if (delaySec < (SLOTS_PER_EPOCH * this.config.getSlotDurationMs(headFork)) / 1000) {
|
|
332
340
|
this.metrics.importBlock.elapsedTimeTillBecomeHead.observe(delaySec);
|
|
333
341
|
const cutOffSec = this.config.getAttestationDueMs(this.config.getForkName(blockSlot)) / 1000;
|
|
334
342
|
if (delaySec > cutOffSec) {
|
|
@@ -400,9 +408,8 @@ export async function importBlock(
|
|
|
400
408
|
const proposalSlot = blockSlot + 1;
|
|
401
409
|
try {
|
|
402
410
|
const proposerIndex = postState.getBeaconProposer(proposalSlot);
|
|
403
|
-
const feeRecipient = this.beaconProposerCache.get(proposerIndex);
|
|
404
411
|
|
|
405
|
-
if (
|
|
412
|
+
if (this.beaconProposerCache.has(proposerIndex)) {
|
|
406
413
|
// We would set this to true if
|
|
407
414
|
// 1) This is a gossip block
|
|
408
415
|
// 2) We are proposer of next slot
|
|
@@ -594,7 +601,10 @@ export async function importBlock(
|
|
|
594
601
|
}
|
|
595
602
|
}
|
|
596
603
|
|
|
597
|
-
const
|
|
604
|
+
const reprocessGuardSec =
|
|
605
|
+
this.config.getSlotComponentDurationMs(this.config.getForkName(blockSlot), REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS) /
|
|
606
|
+
1000;
|
|
607
|
+
const advancedSlot = this.clock.slotWithFutureTolerance(reprocessGuardSec);
|
|
598
608
|
|
|
599
609
|
// Gossip blocks need to be imported as soon as possible, waiting attestations could be processed
|
|
600
610
|
// in the next event loop. See https://github.com/ChainSafe/lodestar/issues/4789
|
|
@@ -657,8 +667,12 @@ export function addAttestationPostElectra(
|
|
|
657
667
|
} else {
|
|
658
668
|
const attSlot = attestation.data.slot;
|
|
659
669
|
const attEpoch = computeEpochAtSlot(attSlot);
|
|
660
|
-
|
|
661
|
-
|
|
670
|
+
// calling getShufflingAtEpoch may take some time for NativeBeaconStateView
|
|
671
|
+
// we should have the shuffling inside ShufflingCache most of the time
|
|
672
|
+
const shuffling =
|
|
673
|
+
this.shufflingCache.getSync(attEpoch, state.getShufflingDecisionRoot(attEpoch)) ??
|
|
674
|
+
state.getShufflingAtEpoch(attEpoch);
|
|
675
|
+
const committees = getBeaconCommittees(shuffling, attSlot, committeeIndices);
|
|
662
676
|
const aggregationBools = attestation.aggregationBits.toBoolArray();
|
|
663
677
|
let offset = 0;
|
|
664
678
|
for (let i = 0; i < committees.length; i++) {
|