@lodestar/beacon-node 1.50.0-dev.033e6b7138 → 1.50.0-dev.03c05fa09a
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/pool/index.js +4 -4
- package/lib/api/impl/beacon/pool/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 +6 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +18 -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 +4 -1
- package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/pruneHistory.js +5 -3
- 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 +25 -12
- 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 +108 -38
- 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 +3 -1
- package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
- package/lib/chain/errors/gossipValidation.js +2 -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/initState.d.ts +2 -9
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +5 -38
- package/lib/chain/initState.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 +5 -4
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +60 -38
- 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 +15 -1
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +33 -1
- 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 +20 -8
- 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 +11 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +54 -36
- 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/validation/attesterSlashing.d.ts +4 -4
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +3 -0
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.d.ts +3 -3
- package/lib/chain/validation/proposerSlashing.d.ts.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +3 -0
- package/lib/chain/validation/proposerSlashing.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 +8 -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/db/repositories/proposerSlashing.d.ts +1 -0
- package/lib/db/repositories/proposerSlashing.d.ts.map +1 -1
- package/lib/db/repositories/proposerSlashing.js +5 -1
- package/lib/db/repositories/proposerSlashing.js.map +1 -1
- 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 +31 -63
- 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/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.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 +67 -68
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipValidatorFn.d.ts +7 -3
- package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
- package/lib/network/processor/gossipValidatorFn.js +7 -3
- package/lib/network/processor/gossipValidatorFn.js.map +1 -1
- package/lib/network/processor/index.d.ts +9 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +80 -13
- 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 +14 -7
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +135 -68
- 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/pool/index.ts +4 -4
- 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 +26 -26
- 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 +9 -4
- package/src/chain/beaconProposerCache.ts +19 -1
- package/src/chain/blocks/blockInput/blockInput.ts +1 -1
- package/src/chain/blocks/importBlock.ts +29 -11
- 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 +138 -40
- package/src/chain/emitter.ts +7 -1
- package/src/chain/errors/envelopeReconstructionError.ts +3 -0
- package/src/chain/errors/gossipValidation.ts +2 -0
- package/src/chain/forkChoice/index.ts +2 -0
- package/src/chain/initState.ts +8 -60
- package/src/chain/interface.ts +7 -3
- package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
- package/src/chain/opPools/opPool.ts +89 -46
- package/src/chain/opPools/proposerPreferencesPool.ts +34 -11
- package/src/chain/opPools/utils.ts +62 -3
- package/src/chain/options.ts +3 -3
- package/src/chain/prepareNextSlot.ts +28 -9
- package/src/chain/produceBlock/computeNewStateRoot.ts +10 -3
- package/src/chain/produceBlock/produceBlockBody.ts +86 -40
- 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/validation/attesterSlashing.ts +7 -4
- package/src/chain/validation/proposerSlashing.ts +7 -4
- package/src/chain/validatorMonitor.ts +82 -61
- package/src/constants/constants.ts +1 -0
- package/src/db/beacon.ts +8 -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/db/repositories/proposerSlashing.ts +6 -1
- 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 +42 -90
- package/src/execution/engine/utils.ts +12 -2
- package/src/index.ts +1 -1
- 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 +98 -81
- package/src/network/processor/gossipValidatorFn.ts +13 -3
- package/src/network/processor/index.ts +92 -13
- 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 +159 -73
- 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
package/lib/sync/unknownBlock.js
CHANGED
|
@@ -11,7 +11,7 @@ import { BlockError, BlockErrorCode } from "../chain/errors/index.js";
|
|
|
11
11
|
import { ChainEvent } from "../chain/index.js";
|
|
12
12
|
import { validateGloasBlockDataColumnSidecars } from "../chain/validation/dataColumnSidecar.js";
|
|
13
13
|
import { validateGossipExecutionPayloadEnvelope } from "../chain/validation/executionPayloadEnvelope.js";
|
|
14
|
-
import { NetworkEvent, prettyPrintPeerIdStr } from "../network/index.js";
|
|
14
|
+
import { NetworkEvent, PeerAction, prettyPrintPeerIdStr } from "../network/index.js";
|
|
15
15
|
import { MAX_PEERS_PER_ROOT } from "../network/processor/constants.js";
|
|
16
16
|
import { ClockEvent } from "../util/clock.js";
|
|
17
17
|
import { shuffle } from "../util/shuffle.js";
|
|
@@ -34,8 +34,12 @@ const PRUNE_UNRESOLVED_SLOT_EPOCHS = 2;
|
|
|
34
34
|
*/
|
|
35
35
|
export const PAYLOAD_POLL_INTERVAL_MS = 1_000;
|
|
36
36
|
class UnknownBlockRateLimitedError extends Error {
|
|
37
|
-
|
|
37
|
+
retryAt;
|
|
38
|
+
constructor(message,
|
|
39
|
+
/** Earliest backoff expiry seen when the download was deferred, it is retried once that has passed */
|
|
40
|
+
retryAt) {
|
|
38
41
|
super(message);
|
|
42
|
+
this.retryAt = retryAt;
|
|
39
43
|
this.name = "UnknownBlockRateLimitedError";
|
|
40
44
|
}
|
|
41
45
|
}
|
|
@@ -378,6 +382,10 @@ export class BlockInputSync {
|
|
|
378
382
|
});
|
|
379
383
|
};
|
|
380
384
|
addByRootHex = (rootHex, peerIdStr) => {
|
|
385
|
+
if (this.knownBadBlocks.has(rootHex)) {
|
|
386
|
+
this.logger.debug("Ignoring known bad block root", { root: rootHex, peerIdStr: peerIdStr ?? "unknown peer" });
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
381
389
|
let pendingBlock = this.pendingBlocks.get(rootHex);
|
|
382
390
|
let added = false;
|
|
383
391
|
if (!pendingBlock) {
|
|
@@ -409,6 +417,10 @@ export class BlockInputSync {
|
|
|
409
417
|
return added;
|
|
410
418
|
};
|
|
411
419
|
addByBlockInput = (blockInput, peerIdStr) => {
|
|
420
|
+
if (this.knownBadBlocks.has(blockInput.blockRootHex)) {
|
|
421
|
+
this.logger.debug("Ignoring known bad block", { slot: blockInput.slot, root: blockInput.blockRootHex, peerIdStr });
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
412
424
|
let pendingBlock = this.pendingBlocks.get(blockInput.blockRootHex);
|
|
413
425
|
// if entry is missing or was added via rootHex and now we have more complete information overwrite
|
|
414
426
|
// the existing information with the more complete cache entry
|
|
@@ -441,6 +453,14 @@ export class BlockInputSync {
|
|
|
441
453
|
}
|
|
442
454
|
};
|
|
443
455
|
addByPayloadRootHex = (rootHex, peerIdStr, slot) => {
|
|
456
|
+
if (this.knownBadBlocks.has(rootHex)) {
|
|
457
|
+
this.logger.debug("Ignoring payload for known bad block root", {
|
|
458
|
+
slot: slot ?? "unknown",
|
|
459
|
+
root: rootHex,
|
|
460
|
+
peerIdStr,
|
|
461
|
+
});
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
444
464
|
let pendingPayload = this.pendingPayloads.get(rootHex);
|
|
445
465
|
let added = false;
|
|
446
466
|
if (!pendingPayload) {
|
|
@@ -499,6 +519,14 @@ export class BlockInputSync {
|
|
|
499
519
|
return this.chain.seenPayloadEnvelopeInputCache.get(rootHex)?.slot;
|
|
500
520
|
}
|
|
501
521
|
addByPayloadInput = (payloadInput, peerIdStr, envelope) => {
|
|
522
|
+
if (this.knownBadBlocks.has(payloadInput.blockRootHex)) {
|
|
523
|
+
this.logger.debug("Ignoring payload input for known bad block root", {
|
|
524
|
+
slot: payloadInput.slot,
|
|
525
|
+
root: payloadInput.blockRootHex,
|
|
526
|
+
peerIdStr,
|
|
527
|
+
});
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
502
530
|
const pendingPayload = this.toPendingPayloadInput(payloadInput, this.pendingPayloads.get(payloadInput.blockRootHex), envelope);
|
|
503
531
|
if (peerIdStr && pendingPayload.peerIdStrings.size < MAX_PEERS_PER_ROOT) {
|
|
504
532
|
pendingPayload.peerIdStrings.add(peerIdStr);
|
|
@@ -552,6 +580,7 @@ export class BlockInputSync {
|
|
|
552
580
|
if (this.chain.forkChoice.getBlockHexAndBlockHash(parentRootHex, parentBlockHashHex) !== null) {
|
|
553
581
|
return { kind: "ready" };
|
|
554
582
|
}
|
|
583
|
+
// The parent's payload is known but does not match `parentBlockHashHex`
|
|
555
584
|
if (this.chain.forkChoice.hasPayloadHexUnsafe(parentRootHex)) {
|
|
556
585
|
return { kind: "invalidParentPayload", parentRootHex, parentBlockHashHex };
|
|
557
586
|
}
|
|
@@ -693,21 +722,25 @@ export class BlockInputSync {
|
|
|
693
722
|
this.triggerUnknownBlockSearch();
|
|
694
723
|
}
|
|
695
724
|
};
|
|
725
|
+
/**
|
|
726
|
+
* Returns false if there is no backoff left to wait for, in which case no retry is scheduled.
|
|
727
|
+
*/
|
|
696
728
|
scheduleRateLimitBackoffRetry() {
|
|
697
729
|
this.clearRateLimitBackoffTimer();
|
|
698
730
|
if (!this.subscribedToNetworkEvents || (this.pendingBlocks.size === 0 && this.pendingPayloads.size === 0)) {
|
|
699
|
-
return;
|
|
731
|
+
return false;
|
|
700
732
|
}
|
|
701
733
|
const now = Date.now();
|
|
702
734
|
const retryAt = this.peerBalancer.getNextRateLimitRetryAt();
|
|
703
735
|
if (retryAt === null) {
|
|
704
|
-
return;
|
|
736
|
+
return false;
|
|
705
737
|
}
|
|
706
738
|
this.rateLimitBackoffTimeout = setTimeout(() => {
|
|
707
739
|
this.rateLimitBackoffTimeout = undefined;
|
|
708
740
|
this.triggerUnknownBlockSearch();
|
|
709
741
|
this.scheduleRateLimitBackoffRetry();
|
|
710
742
|
}, Math.max(0, retryAt - now));
|
|
743
|
+
return true;
|
|
711
744
|
}
|
|
712
745
|
clearRateLimitBackoffTimer() {
|
|
713
746
|
if (this.rateLimitBackoffTimeout !== undefined) {
|
|
@@ -745,13 +778,14 @@ export class BlockInputSync {
|
|
|
745
778
|
* Poll unknown payloads of the current slot.
|
|
746
779
|
*/
|
|
747
780
|
async pollPayloadsAtSlot(slot, signal) {
|
|
781
|
+
const fork = this.config.getForkName(slot);
|
|
748
782
|
// fixed tick count so the loop cannot outlive its slot: for mainnet, it's 6 ticks
|
|
749
|
-
const tickCount = Math.floor((this.config.
|
|
783
|
+
const tickCount = Math.floor((this.config.getSlotDurationMs(fork) - this.config.getPayloadDueMs(fork)) / PAYLOAD_POLL_INTERVAL_MS);
|
|
750
784
|
// a root still missing on several ticks is searched on each of them, recorded once
|
|
751
785
|
const searchedRoots = new Set();
|
|
752
786
|
let polls = 0;
|
|
753
787
|
try {
|
|
754
|
-
await sleep(Math.max(0, this.config.getPayloadDueMs() - this.chain.clock.msFromSlot(slot)), signal);
|
|
788
|
+
await sleep(Math.max(0, this.config.getPayloadDueMs(fork) - this.chain.clock.msFromSlot(slot)), signal);
|
|
755
789
|
for (polls = 0; polls < tickCount; polls++) {
|
|
756
790
|
let importedCount = 0;
|
|
757
791
|
for (const [rootHex, { slot: deferredSlot, source, peer }] of this.deferredPayloadRoots) {
|
|
@@ -882,7 +916,8 @@ export class BlockInputSync {
|
|
|
882
916
|
}
|
|
883
917
|
else if (blockSlot <= finalizedSlot) {
|
|
884
918
|
// the common ancestor of the downloading chain and canonical chain should be at least the finalized slot and
|
|
885
|
-
// we should found it through forkchoice. If not,
|
|
919
|
+
// we should found it through forkchoice. If not, drop the chain without penalizing peers because pending entries are
|
|
920
|
+
// block retained on failed download, so finalization can pass the block while it is still pending
|
|
886
921
|
// 0 - 1 - ... - n - finalizedSlot
|
|
887
922
|
// \
|
|
888
923
|
// parent 1 - parent 2 - ... - unknownParent block
|
|
@@ -890,7 +925,7 @@ export class BlockInputSync {
|
|
|
890
925
|
...logCtx2,
|
|
891
926
|
finalizedSlot,
|
|
892
927
|
});
|
|
893
|
-
this.
|
|
928
|
+
this.removeAllDescendants(block, DroppedItemReason.belowFinalized);
|
|
894
929
|
}
|
|
895
930
|
else {
|
|
896
931
|
this.onUnknownBlockRoot({ rootHex: pending.blockInput.parentRootHex, source: BlockInputSource.byRoot });
|
|
@@ -903,7 +938,11 @@ export class BlockInputSync {
|
|
|
903
938
|
pendingBlock.status = PendingBlockInputStatus.pending;
|
|
904
939
|
}
|
|
905
940
|
this.logger.debug("Deferring unknown block download due to peer rate limit", logCtx, res.err);
|
|
906
|
-
this.scheduleRateLimitBackoffRetry()
|
|
941
|
+
if (!this.scheduleRateLimitBackoffRetry() || res.err.retryAt <= Date.now()) {
|
|
942
|
+
// The backoff this download waited for expired in the meantime, a timer is only armed if another
|
|
943
|
+
// peer is still in backoff and would retry it later than needed
|
|
944
|
+
this.triggerUnknownBlockSearch();
|
|
945
|
+
}
|
|
907
946
|
return;
|
|
908
947
|
}
|
|
909
948
|
this.metrics?.blockInputSync.downloadedBlocksError.inc();
|
|
@@ -1009,14 +1048,17 @@ export class BlockInputSync {
|
|
|
1009
1048
|
this.removeAllDescendants(pendingBlock, DroppedItemReason.elError, DroppedItemReason.elError);
|
|
1010
1049
|
break;
|
|
1011
1050
|
case BlockErrorCode.EXECUTION_ENGINE_INVALID:
|
|
1012
|
-
//
|
|
1051
|
+
// Ban but do not downscore: optimistic-sync peers may forward and serve blocks whose payload is later
|
|
1052
|
+
// rejected by the execution engine. Per the spec, an INVALID execution payload SHOULD NOT cause a peer
|
|
1053
|
+
// to be down-scored or disconnected, only consensus-layer invalidity MAY.
|
|
1054
|
+
// https://github.com/ethereum/consensus-specs/blob/master/specs/bellatrix/p2p-interface.md#the-reqresp-domain
|
|
1013
1055
|
this.logger.debug("Execution engine rejected block from unknown parent sync", errorData, res.err);
|
|
1014
|
-
this.
|
|
1056
|
+
this.removeAndBanAllDescendants(pendingBlock, DroppedItemReason.elInvalid);
|
|
1015
1057
|
break;
|
|
1016
1058
|
default:
|
|
1017
1059
|
// Block is not correct with respect to our chain. Log error loudly
|
|
1018
1060
|
this.logger.debug("Error processing block from unknown parent sync", errorData, res.err);
|
|
1019
|
-
this.
|
|
1061
|
+
this.removeAllDescendants(pendingBlock, DroppedItemReason.invalidBlock);
|
|
1020
1062
|
}
|
|
1021
1063
|
}
|
|
1022
1064
|
// Probably a queue error or something unwanted happened, mark as pending to try again latter
|
|
@@ -1138,6 +1180,12 @@ export class BlockInputSync {
|
|
|
1138
1180
|
if (!isPendingPayloadEnvelope(payload)) {
|
|
1139
1181
|
payload.status = PendingPayloadInputStatus.pending;
|
|
1140
1182
|
}
|
|
1183
|
+
if (res.err instanceof UnknownBlockRateLimitedError &&
|
|
1184
|
+
(!this.scheduleRateLimitBackoffRetry() || res.err.retryAt <= Date.now())) {
|
|
1185
|
+
// The backoff this download waited for expired in the meantime, a timer is only armed if another
|
|
1186
|
+
// peer is still in backoff and would retry it later than needed
|
|
1187
|
+
this.triggerUnknownBlockSearch();
|
|
1188
|
+
}
|
|
1141
1189
|
}
|
|
1142
1190
|
async processPayload(pendingPayload) {
|
|
1143
1191
|
const rootHex = pendingPayload.payloadInput.blockRootHex;
|
|
@@ -1191,18 +1239,21 @@ export class BlockInputSync {
|
|
|
1191
1239
|
this.logger.debug("Execution engine error while processing payload from unknown sync", logCtx, res.err);
|
|
1192
1240
|
pendingPayload.status = PendingPayloadInputStatus.downloaded;
|
|
1193
1241
|
break;
|
|
1242
|
+
// The invalid envelope is evicted from the seen cache in the cases below, otherwise the next
|
|
1243
|
+
// attempt would reuse it instead of fetching another envelope from peers
|
|
1194
1244
|
case PayloadErrorCode.EXECUTION_ENGINE_INVALID:
|
|
1195
1245
|
this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
|
|
1246
|
+
this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
|
|
1196
1247
|
this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.elInvalid);
|
|
1197
1248
|
break;
|
|
1198
1249
|
case PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR:
|
|
1199
1250
|
this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
|
|
1251
|
+
this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
|
|
1200
1252
|
this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.invalidEnvelope);
|
|
1201
1253
|
break;
|
|
1202
1254
|
case PayloadErrorCode.INVALID_SIGNATURE:
|
|
1203
|
-
// TODO GLOAS: Decide how invalid payload inputs should eventually leave memory without
|
|
1204
|
-
// reintroducing envelope replacement / recreation flows.
|
|
1205
1255
|
this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
|
|
1256
|
+
this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
|
|
1206
1257
|
this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.invalidSignature);
|
|
1207
1258
|
break;
|
|
1208
1259
|
default:
|
|
@@ -1240,11 +1291,14 @@ export class BlockInputSync {
|
|
|
1240
1291
|
const pendingColumns = payloadInput?.hasAllData()
|
|
1241
1292
|
? new Set()
|
|
1242
1293
|
: new Set(payloadInput?.getMissingSampledColumnMeta().missing ?? []);
|
|
1294
|
+
// Same `now` for both calls, a backoff expiring in between would be reported as no peer available
|
|
1295
|
+
const now = Date.now();
|
|
1243
1296
|
// prefer peers that gossiped this payload root to us (#9923)
|
|
1244
|
-
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(pendingColumns, excludedPeers, cacheItem.peerIdStrings);
|
|
1297
|
+
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(pendingColumns, excludedPeers, cacheItem.peerIdStrings, now);
|
|
1245
1298
|
if (peerMeta === null) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1299
|
+
const retryAt = this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers, now);
|
|
1300
|
+
if (retryAt !== null) {
|
|
1301
|
+
throw new UnknownBlockRateLimitedError(`Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`, retryAt);
|
|
1248
1302
|
}
|
|
1249
1303
|
const reason = pendingColumns.size > 0
|
|
1250
1304
|
? `cannot find peer with needed columns=${prettyPrintIndices(Array.from(pendingColumns))}`
|
|
@@ -1254,10 +1308,10 @@ export class BlockInputSync {
|
|
|
1254
1308
|
throw Error(`Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: ${reason}`);
|
|
1255
1309
|
}
|
|
1256
1310
|
const { peerId, client: peerClient } = peerMeta;
|
|
1257
|
-
cacheItem.peerIdStrings.add(peerId);
|
|
1258
1311
|
try {
|
|
1259
1312
|
if (!envelope) {
|
|
1260
1313
|
envelope = await this.fetchExecutionPayloadEnvelope(peerId, blockRoot, rootHex);
|
|
1314
|
+
cacheItem.peerIdStrings.add(peerId);
|
|
1261
1315
|
const slotWasUnknown = typeof slot !== "number";
|
|
1262
1316
|
slot = envelope.message.payload.slotNumber;
|
|
1263
1317
|
if (slotWasUnknown) {
|
|
@@ -1292,6 +1346,8 @@ export class BlockInputSync {
|
|
|
1292
1346
|
const missing = pendingPayload.payloadInput.getMissingSampledColumnMeta().missing;
|
|
1293
1347
|
if (missing.length > 0) {
|
|
1294
1348
|
const columnSidecars = await this.fetchPayloadColumns(peerMeta, pendingPayload.payloadInput, missing);
|
|
1349
|
+
// toPendingPayloadInput copied cacheItem's set, so add to the object that is carried forward
|
|
1350
|
+
pendingPayload.peerIdStrings.add(peerId);
|
|
1295
1351
|
const seenTimestampSec = Date.now() / 1000;
|
|
1296
1352
|
for (const columnSidecar of columnSidecars) {
|
|
1297
1353
|
if (pendingPayload.payloadInput.hasColumn(columnSidecar.index)) {
|
|
@@ -1356,8 +1412,9 @@ export class BlockInputSync {
|
|
|
1356
1412
|
}
|
|
1357
1413
|
this.metrics?.blockInputSync.payloadFetchTime.observe({ result: FetchResult.FailureMaxAttempts }, Date.now() / 1000 - fetchStartSec);
|
|
1358
1414
|
this.metrics?.blockInputSync.payloadFetchPeers.set({ result: FetchResult.FailureMaxAttempts }, i - 1);
|
|
1359
|
-
|
|
1360
|
-
|
|
1415
|
+
const retryAt = deferredByRateLimit ? this.peerBalancer.getNextRateLimitRetryAt() : null;
|
|
1416
|
+
if (retryAt !== null) {
|
|
1417
|
+
throw new UnknownBlockRateLimitedError(`Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts: peers are rate-limited`, retryAt);
|
|
1361
1418
|
}
|
|
1362
1419
|
throw Error(`Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts.`);
|
|
1363
1420
|
}
|
|
@@ -1420,11 +1477,14 @@ export class BlockInputSync {
|
|
|
1420
1477
|
const pendingColumns = isPendingBlockInput(cacheItem) && isBlockInputColumns(cacheItem.blockInput)
|
|
1421
1478
|
? new Set(cacheItem.blockInput.getMissingSampledColumnMeta().missing)
|
|
1422
1479
|
: defaultPendingColumns;
|
|
1480
|
+
// Same `now` for both calls, a backoff expiring in between would be reported as no peer available
|
|
1481
|
+
const now = Date.now();
|
|
1423
1482
|
// prefer peers that gossiped this block root to us (#9923)
|
|
1424
|
-
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(pendingColumns, excludedPeers, cacheItem.peerIdStrings);
|
|
1483
|
+
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(pendingColumns, excludedPeers, cacheItem.peerIdStrings, now);
|
|
1425
1484
|
if (peerMeta === null) {
|
|
1426
|
-
|
|
1427
|
-
|
|
1485
|
+
const retryAt = this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers, now);
|
|
1486
|
+
if (retryAt !== null) {
|
|
1487
|
+
throw new UnknownBlockRateLimitedError(`Error fetching UnknownBlockRoot slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`, retryAt);
|
|
1428
1488
|
}
|
|
1429
1489
|
// no more peer with needed columns to try, throw error
|
|
1430
1490
|
const message = `Error fetching UnknownBlockRoot slot=${slot} root=${rootHex} after ${i}: cannot find peer with needed columns=${prettyPrintIndices(Array.from(pendingColumns))}`;
|
|
@@ -1433,7 +1493,6 @@ export class BlockInputSync {
|
|
|
1433
1493
|
throw Error(message);
|
|
1434
1494
|
}
|
|
1435
1495
|
const { peerId, client: peerClient } = peerMeta;
|
|
1436
|
-
cacheItem.peerIdStrings.add(peerId);
|
|
1437
1496
|
try {
|
|
1438
1497
|
const downloadResult = await downloadByRoot({
|
|
1439
1498
|
config: this.config,
|
|
@@ -1444,6 +1503,7 @@ export class BlockInputSync {
|
|
|
1444
1503
|
cacheItem,
|
|
1445
1504
|
});
|
|
1446
1505
|
cacheItem = downloadResult.result;
|
|
1506
|
+
cacheItem.peerIdStrings.add(peerId);
|
|
1447
1507
|
if (slot === undefined) {
|
|
1448
1508
|
slot = cacheItem.blockInput.slot;
|
|
1449
1509
|
// we were not able to observe the time into slot when starting the fetch, do it now
|
|
@@ -1520,8 +1580,9 @@ export class BlockInputSync {
|
|
|
1520
1580
|
}
|
|
1521
1581
|
} // end while loop over peers
|
|
1522
1582
|
const message = `Error fetching BlockInput with slot=${slot} root=${rootHex} after ${i - 1} attempts.`;
|
|
1523
|
-
|
|
1524
|
-
|
|
1583
|
+
const retryAt = deferredByRateLimit ? this.peerBalancer.getNextRateLimitRetryAt() : null;
|
|
1584
|
+
if (retryAt !== null) {
|
|
1585
|
+
throw new UnknownBlockRateLimitedError(`${message} Peers are rate-limited.`, retryAt);
|
|
1525
1586
|
}
|
|
1526
1587
|
if (!isPendingBlockInput(cacheItem)) {
|
|
1527
1588
|
throw Error(`${message} No block and no data was found.`);
|
|
@@ -1545,41 +1606,8 @@ export class BlockInputSync {
|
|
|
1545
1606
|
this.metrics?.blockInputSync.fetchPeers.set({ result: FetchResult.FailureMaxAttempts }, i - 1);
|
|
1546
1607
|
throw Error(message);
|
|
1547
1608
|
}
|
|
1548
|
-
/**
|
|
1549
|
-
* Gets all descendant blocks of `block` recursively from `pendingBlocks`.
|
|
1550
|
-
* Assumes that if a parent block does not exist or is not processable, all descendant blocks are bad too.
|
|
1551
|
-
* Downscore all peers that have referenced any of this bad blocks. May report peers multiple times if they have
|
|
1552
|
-
* referenced more than one bad block.
|
|
1553
|
-
*/
|
|
1554
|
-
removeAndDownScoreAllDescendants(block, headReason) {
|
|
1555
|
-
// Get all blocks that are a descendant of this one
|
|
1556
|
-
const badPendingBlocks = this.removeAllDescendants(block, headReason, DroppedItemReason.invalidParent);
|
|
1557
|
-
// just console log and do not penalize on pending/bad blocks for debugging
|
|
1558
|
-
// console.log("removeAndDownscoreAllDescendants", {block});
|
|
1559
|
-
for (const block of badPendingBlocks) {
|
|
1560
|
-
//
|
|
1561
|
-
// TODO(fulu): why is this commented out here?
|
|
1562
|
-
//
|
|
1563
|
-
// this.knownBadBlocks.add(block.blockRootHex);
|
|
1564
|
-
// for (const peerIdStr of block.peerIdStrings) {
|
|
1565
|
-
// // TODO: Refactor peerRpcScores to work with peerIdStr only
|
|
1566
|
-
// this.network.reportPeer(peerIdStr, PeerAction.LowToleranceError, "BadBlockByRoot");
|
|
1567
|
-
// }
|
|
1568
|
-
this.logger.debug("ignored Banning unknown block", {
|
|
1569
|
-
slot: getBlockInputSyncCacheItemSlot(block),
|
|
1570
|
-
root: getBlockInputSyncCacheItemRootHex(block),
|
|
1571
|
-
peerIdStrings: Array.from(block.peerIdStrings)
|
|
1572
|
-
.map((id) => prettyPrintPeerIdStr(id))
|
|
1573
|
-
.join(","),
|
|
1574
|
-
});
|
|
1575
|
-
}
|
|
1576
|
-
// Prune knownBadBlocks
|
|
1577
|
-
pruneSetToMax(this.knownBadBlocks, MAX_KNOWN_BAD_BLOCKS);
|
|
1578
|
-
}
|
|
1579
1609
|
// Once a parent payload is invalid, every descendant waiting on that payload lineage becomes unrecoverable too.
|
|
1580
1610
|
removePendingPayloadAndDescendants(rootHex, headReason) {
|
|
1581
|
-
// Keep PayloadEnvelopeInput resident in the seen cache. importBlock() owns that object and
|
|
1582
|
-
// later validation/finalization logic decides when it can leave memory.
|
|
1583
1611
|
if (this.pendingPayloads.delete(rootHex)) {
|
|
1584
1612
|
this.metrics?.blockInputSync.removedPayloads.inc({ reason: headReason }, 1);
|
|
1585
1613
|
}
|
|
@@ -1600,9 +1628,50 @@ export class BlockInputSync {
|
|
|
1600
1628
|
});
|
|
1601
1629
|
}
|
|
1602
1630
|
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Same as `removeAndBanAllDescendants`, and downscores every peer that referenced or served a banned item, once per
|
|
1633
|
+
* peer. Only call for consensus-layer invalidity, never for an INVALID execution payload:
|
|
1634
|
+
* https://github.com/ethereum/consensus-specs/blob/master/specs/bellatrix/p2p-interface.md#the-reqresp-domain
|
|
1635
|
+
*/
|
|
1636
|
+
removeAndDownScoreAllDescendants(block, headReason) {
|
|
1637
|
+
const peersToReport = new Set();
|
|
1638
|
+
for (const bannedBlock of this.removeAndBanAllDescendants(block, headReason)) {
|
|
1639
|
+
for (const peerIdStr of bannedBlock.peerIdStrings) {
|
|
1640
|
+
peersToReport.add(peerIdStr);
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
for (const peerIdStr of peersToReport) {
|
|
1644
|
+
this.network.reportPeer(peerIdStr, PeerAction.LowToleranceError, headReason);
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
/**
|
|
1648
|
+
* Removes `block` and all its pending descendants and bans their roots in `knownBadBlocks`. Only call when the chain
|
|
1649
|
+
* is provably bad: a banned root is never searched for again. Returns the banned items.
|
|
1650
|
+
*/
|
|
1651
|
+
removeAndBanAllDescendants(block, headReason) {
|
|
1652
|
+
const bannedBlocks = [];
|
|
1653
|
+
for (const badBlock of this.removeAllDescendants(block, headReason, DroppedItemReason.invalidParent)) {
|
|
1654
|
+
const rootHex = getBlockInputSyncCacheItemRootHex(badBlock);
|
|
1655
|
+
// a gossip import may race a failing sync path, never ban a root fork choice has imported
|
|
1656
|
+
if (this.chain.forkChoice.hasBlockHex(rootHex)) {
|
|
1657
|
+
continue;
|
|
1658
|
+
}
|
|
1659
|
+
this.knownBadBlocks.add(rootHex);
|
|
1660
|
+
bannedBlocks.push(badBlock);
|
|
1661
|
+
this.logger.debug("Banning unknown block", {
|
|
1662
|
+
slot: getBlockInputSyncCacheItemSlot(badBlock),
|
|
1663
|
+
root: rootHex,
|
|
1664
|
+
reason: headReason,
|
|
1665
|
+
peerIdStrings: Array.from(badBlock.peerIdStrings)
|
|
1666
|
+
.map((id) => prettyPrintPeerIdStr(id))
|
|
1667
|
+
.join(","),
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
pruneSetToMax(this.knownBadBlocks, MAX_KNOWN_BAD_BLOCKS);
|
|
1671
|
+
return bannedBlocks;
|
|
1672
|
+
}
|
|
1603
1673
|
removeAllDescendants(block, headReason, descendantReason = DroppedItemReason.invalidParent) {
|
|
1604
1674
|
const rootHex = getBlockInputSyncCacheItemRootHex(block);
|
|
1605
|
-
const slot = getBlockInputSyncCacheItemSlot(block);
|
|
1606
1675
|
// Get all blocks that are a descendant of this one (index 0 is the head item itself)
|
|
1607
1676
|
const badPendingBlocks = [block, ...getAllDescendantBlocks(rootHex, this.pendingBlocks)];
|
|
1608
1677
|
for (const [i, block] of badPendingBlocks.entries()) {
|
|
@@ -1618,8 +1687,8 @@ export class BlockInputSync {
|
|
|
1618
1687
|
// Keep PayloadEnvelopeInput resident in the seen cache for consistency with the
|
|
1619
1688
|
// importBlock()-owned lifecycle.
|
|
1620
1689
|
this.logger.debug("Removing bad/unknown/incomplete BlockInputSyncCacheItem", {
|
|
1621
|
-
slot,
|
|
1622
|
-
|
|
1690
|
+
slot: getBlockInputSyncCacheItemSlot(block),
|
|
1691
|
+
root: rootHex,
|
|
1623
1692
|
});
|
|
1624
1693
|
}
|
|
1625
1694
|
return badPendingBlocks;
|
|
@@ -1666,8 +1735,7 @@ export class UnknownBlockPeerBalancer {
|
|
|
1666
1735
|
onRateLimited(peerId, rateLimitedUntilMs) {
|
|
1667
1736
|
this.rateLimitedUntilByPeer.set(peerId, rateLimitedUntilMs);
|
|
1668
1737
|
}
|
|
1669
|
-
getNextRateLimitRetryAt(pendingColumns, excludedPeers) {
|
|
1670
|
-
const now = Date.now();
|
|
1738
|
+
getNextRateLimitRetryAt(pendingColumns, excludedPeers, now = Date.now()) {
|
|
1671
1739
|
let retryAt = null;
|
|
1672
1740
|
for (const [peerId, rateLimitedUntil] of this.rateLimitedUntilByPeer.entries()) {
|
|
1673
1741
|
if (rateLimitedUntil <= now) {
|
|
@@ -1696,8 +1764,8 @@ export class UnknownBlockPeerBalancer {
|
|
|
1696
1764
|
* preferredPeers are the peers NetworkProcessor told us gossiped this root (from
|
|
1697
1765
|
* pendingBlock/cacheItem.peerIdStrings). They are preferred but not required.
|
|
1698
1766
|
*/
|
|
1699
|
-
bestPeerForPendingColumns(pendingColumns, excludedPeers, preferredPeers) {
|
|
1700
|
-
const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers);
|
|
1767
|
+
bestPeerForPendingColumns(pendingColumns, excludedPeers, preferredPeers, now = Date.now()) {
|
|
1768
|
+
const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers, now);
|
|
1701
1769
|
if (eligiblePeers.length === 0) {
|
|
1702
1770
|
return null;
|
|
1703
1771
|
}
|
|
@@ -1730,8 +1798,7 @@ export class UnknownBlockPeerBalancer {
|
|
|
1730
1798
|
}
|
|
1731
1799
|
return totalActiveRequests;
|
|
1732
1800
|
}
|
|
1733
|
-
filterPeers(pendingDataColumns, excludedPeers) {
|
|
1734
|
-
const now = Date.now();
|
|
1801
|
+
filterPeers(pendingDataColumns, excludedPeers, now) {
|
|
1735
1802
|
let maxColumnCount = 0;
|
|
1736
1803
|
const considerPeers = [];
|
|
1737
1804
|
for (const [peerId, syncMeta] of this.peersMeta.entries()) {
|