@lodestar/beacon-node 1.23.0-dev.77006ea0ce → 1.23.0-dev.794e5ef488
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.js +18 -19
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/blocks/utils.js +1 -1
- package/lib/api/impl/beacon/blocks/utils.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +13 -23
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.js +33 -3
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -6
- package/lib/api/impl/beacon/state/utils.js +24 -36
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/config/constants.js +0 -1
- package/lib/api/impl/config/constants.js.map +1 -1
- package/lib/api/impl/debug/index.js +30 -0
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/errors.d.ts +8 -0
- package/lib/api/impl/errors.js +7 -0
- package/lib/api/impl/errors.js.map +1 -1
- package/lib/api/impl/events/index.js +1 -2
- package/lib/api/impl/events/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.js +3 -3
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/node/index.js +2 -4
- package/lib/api/impl/node/index.js.map +1 -1
- package/lib/api/impl/node/utils.js +1 -0
- package/lib/api/impl/node/utils.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts +31 -0
- package/lib/api/impl/validator/index.js +159 -92
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/impl/validator/utils.d.ts +3 -2
- package/lib/api/impl/validator/utils.js +15 -7
- package/lib/api/impl/validator/utils.js.map +1 -1
- package/lib/api/rest/activeSockets.js +1 -1
- package/lib/api/rest/activeSockets.js.map +1 -1
- package/lib/api/rest/base.d.ts +1 -0
- package/lib/api/rest/base.js +31 -4
- package/lib/api/rest/base.js.map +1 -1
- package/lib/api/rest/index.js +1 -0
- package/lib/api/rest/index.js.map +1 -1
- package/lib/api/rest/swaggerUI.js +1 -4
- package/lib/api/rest/swaggerUI.js.map +1 -1
- package/lib/chain/archiver/archiver.d.ts +40 -0
- package/lib/chain/archiver/archiver.js +117 -0
- package/lib/chain/archiver/archiver.js.map +1 -0
- package/lib/chain/archiver/index.d.ts +2 -54
- package/lib/chain/archiver/index.js +2 -104
- package/lib/chain/archiver/index.js.map +1 -1
- package/lib/chain/archiver/interface.d.ts +39 -0
- package/lib/chain/archiver/interface.js +8 -0
- package/lib/chain/archiver/interface.js.map +1 -0
- package/lib/chain/archiver/{archiveStates.d.ts → strategies/frequencyStateArchiveStrategy.d.ts} +16 -14
- package/lib/chain/archiver/{archiveStates.js → strategies/frequencyStateArchiveStrategy.js} +8 -6
- package/lib/chain/archiver/strategies/frequencyStateArchiveStrategy.js.map +1 -0
- package/lib/chain/balancesCache.js +1 -1
- package/lib/chain/balancesCache.js.map +1 -1
- package/lib/chain/blocks/importBlock.js +2 -1
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/index.js +3 -5
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.js +2 -2
- package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +5 -13
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/bls/multithread/index.js +4 -4
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +1 -1
- package/lib/chain/bls/multithread/jobItem.js +3 -13
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/multithread/poolSize.js +1 -1
- package/lib/chain/bls/multithread/poolSize.js.map +1 -1
- package/lib/chain/bls/multithread/worker.js +1 -1
- package/lib/chain/bls/multithread/worker.js.map +1 -1
- package/lib/chain/chain.d.ts +4 -2
- package/lib/chain/chain.js +34 -37
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +1 -1
- package/lib/chain/emitter.js +1 -1
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts +4 -0
- package/lib/chain/forkChoice/index.js +5 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/genesis/genesis.js +2 -6
- package/lib/chain/genesis/genesis.js.map +1 -1
- package/lib/chain/historicalState/getHistoricalState.d.ts +2 -1
- package/lib/chain/historicalState/getHistoricalState.js +3 -0
- package/lib/chain/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/historicalState/worker.js +1 -1
- package/lib/chain/historicalState/worker.js.map +1 -1
- package/lib/chain/initState.d.ts +1 -1
- package/lib/chain/initState.js +1 -1
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -2
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/lightClient/index.js +3 -5
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +32 -36
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/attestationPool.js +3 -5
- package/lib/chain/opPools/attestationPool.js.map +1 -1
- package/lib/chain/opPools/opPool.js +2 -4
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js +3 -5
- package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +2 -4
- package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
- package/lib/chain/options.d.ts +3 -1
- package/lib/chain/options.js +5 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +2 -1
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +18 -17
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/produceBlock/validateBlobsAndKzgCommitments.d.ts +1 -1
- package/lib/chain/produceBlock/validateBlobsAndKzgCommitments.js +1 -1
- package/lib/chain/produceBlock/validateBlobsAndKzgCommitments.js.map +1 -1
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.js +1 -1
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/rewards/attestationsRewards.d.ts +1 -1
- package/lib/chain/rewards/attestationsRewards.js +3 -2
- package/lib/chain/rewards/attestationsRewards.js.map +1 -1
- package/lib/chain/rewards/blockRewards.js +1 -3
- package/lib/chain/rewards/blockRewards.js.map +1 -1
- package/lib/chain/rewards/syncCommitteeRewards.js +1 -3
- package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +21 -25
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/shufflingCache.js +11 -11
- package/lib/chain/shufflingCache.js.map +1 -1
- package/lib/chain/stateCache/datastore/file.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +7 -2
- package/lib/chain/stateCache/fifoBlockStateCache.js +7 -2
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +4 -3
- package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -3
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.d.ts +1 -1
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts +3 -17
- package/lib/chain/validation/attestation.js +28 -53
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts +1 -1
- package/lib/chain/validation/blsToExecutionChange.d.ts +1 -1
- package/lib/chain/validation/lightClientFinalityUpdate.js +1 -1
- package/lib/chain/validation/lightClientFinalityUpdate.js.map +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.d.ts +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts +1 -1
- package/lib/db/buckets.js +3 -5
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/repositories/backfilledRanges.d.ts +1 -1
- package/lib/db/repositories/backfilledRanges.js +1 -2
- package/lib/db/repositories/backfilledRanges.js.map +1 -1
- package/lib/db/repositories/blockArchive.js +1 -1
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.js +1 -1
- package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
- package/lib/db/repositories/checkpointState.js +1 -1
- package/lib/db/repositories/checkpointState.js.map +1 -1
- package/lib/db/repositories/depositDataRoot.d.ts +1 -1
- package/lib/db/repositories/depositDataRoot.js +2 -3
- package/lib/db/repositories/depositDataRoot.js.map +1 -1
- package/lib/db/repositories/eth1Data.d.ts +1 -1
- package/lib/db/repositories/eth1Data.js +1 -2
- package/lib/db/repositories/eth1Data.js.map +1 -1
- package/lib/db/repositories/stateArchive.js +1 -1
- package/lib/db/repositories/stateArchive.js.map +1 -1
- package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts +1 -1
- package/lib/db/single/preGenesisStateLastProcessedBlock.js +1 -1
- package/lib/db/single/preGenesisStateLastProcessedBlock.js.map +1 -1
- package/lib/eth1/eth1DataCache.js +1 -1
- package/lib/eth1/eth1DataCache.js.map +1 -1
- package/lib/eth1/eth1DepositDataTracker.js +9 -13
- package/lib/eth1/eth1DepositDataTracker.js.map +1 -1
- package/lib/eth1/eth1DepositsCache.js +2 -2
- package/lib/eth1/eth1DepositsCache.js.map +1 -1
- package/lib/eth1/eth1MergeBlockTracker.js +40 -50
- package/lib/eth1/eth1MergeBlockTracker.js.map +1 -1
- package/lib/eth1/index.js +4 -8
- package/lib/eth1/index.js.map +1 -1
- package/lib/eth1/provider/eth1Provider.js.map +1 -1
- package/lib/eth1/provider/jsonRpcHttpClient.d.ts +1 -1
- package/lib/eth1/provider/jsonRpcHttpClient.js +6 -12
- package/lib/eth1/provider/jsonRpcHttpClient.js.map +1 -1
- package/lib/eth1/provider/jwt.js +0 -1
- package/lib/eth1/provider/jwt.js.map +1 -1
- package/lib/eth1/provider/utils.js +1 -1
- package/lib/eth1/provider/utils.js.map +1 -1
- package/lib/eth1/utils/deposits.js +1 -1
- package/lib/eth1/utils/deposits.js.map +1 -1
- package/lib/eth1/utils/eth1Vote.js +3 -5
- package/lib/eth1/utils/eth1Vote.js.map +1 -1
- package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js +1 -3
- package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js.map +1 -1
- package/lib/execution/builder/http.d.ts +17 -2
- package/lib/execution/builder/http.js +32 -7
- package/lib/execution/builder/http.js.map +1 -1
- package/lib/execution/builder/index.js +1 -0
- package/lib/execution/builder/index.js.map +1 -1
- package/lib/execution/builder/interface.d.ts +3 -2
- package/lib/execution/engine/http.d.ts +2 -2
- package/lib/execution/engine/http.js +4 -8
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/index.js +1 -0
- package/lib/execution/engine/index.js.map +1 -1
- package/lib/execution/engine/mock.js +8 -11
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +16 -24
- package/lib/execution/engine/types.js +31 -52
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/execution/engine/utils.js +1 -1
- package/lib/execution/engine/utils.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +6 -1
- package/lib/metrics/metrics/beacon.js +13 -3
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +0 -1
- package/lib/metrics/metrics/lodestar.js +0 -6
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/metrics/validatorMonitor.js +37 -49
- package/lib/metrics/validatorMonitor.js.map +1 -1
- package/lib/monitoring/properties.js +2 -4
- package/lib/monitoring/properties.js.map +1 -1
- package/lib/monitoring/service.js +3 -5
- package/lib/monitoring/service.js.map +1 -1
- package/lib/monitoring/system.js +0 -1
- package/lib/monitoring/system.js.map +1 -1
- package/lib/network/core/metrics.js +0 -2
- package/lib/network/core/metrics.js.map +1 -1
- package/lib/network/core/networkCore.js +7 -1
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorker.js +0 -1
- package/lib/network/core/networkCoreWorker.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
- package/lib/network/discv5/index.d.ts +1 -1
- package/lib/network/discv5/index.js +1 -1
- package/lib/network/discv5/index.js.map +1 -1
- package/lib/network/discv5/utils.js +1 -0
- package/lib/network/discv5/utils.js.map +1 -1
- package/lib/network/discv5/worker.js +0 -1
- package/lib/network/discv5/worker.js.map +1 -1
- package/lib/network/events.js +1 -1
- package/lib/network/events.js.map +1 -1
- package/lib/network/forks.js +0 -1
- package/lib/network/forks.js.map +1 -1
- package/lib/network/gossip/encoding.js +1 -3
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/gossip/gossipsub.js +6 -7
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +8 -6
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/metrics.js +0 -1
- package/lib/network/gossip/metrics.js.map +1 -1
- package/lib/network/gossip/scoringParameters.js +0 -1
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.js +3 -4
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +1 -5
- package/lib/network/network.d.ts +2 -2
- package/lib/network/network.js.map +1 -1
- package/lib/network/options.js +0 -2
- package/lib/network/options.js.map +1 -1
- package/lib/network/peers/datastore.js +1 -2
- package/lib/network/peers/datastore.js.map +1 -1
- package/lib/network/peers/discover.js +8 -13
- package/lib/network/peers/discover.js.map +1 -1
- package/lib/network/peers/peerManager.js +10 -7
- package/lib/network/peers/peerManager.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts +0 -2
- package/lib/network/processor/gossipHandlers.js +15 -62
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts +1 -1
- package/lib/network/processor/gossipQueues/index.js +7 -22
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/gossipQueues/indexed.js +1 -3
- package/lib/network/processor/gossipQueues/indexed.js.map +1 -1
- package/lib/network/processor/gossipQueues/linear.js +5 -7
- package/lib/network/processor/gossipQueues/linear.js.map +1 -1
- package/lib/network/processor/gossipQueues/types.d.ts +1 -2
- package/lib/network/processor/gossipQueues/types.js +0 -6
- package/lib/network/processor/gossipQueues/types.js.map +1 -1
- package/lib/network/processor/index.js +4 -2
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.d.ts +2 -2
- package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.js +5 -5
- package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.js.map +1 -1
- package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/lightClientBootstrap.js +1 -3
- package/lib/network/reqresp/handlers/lightClientBootstrap.js.map +1 -1
- package/lib/network/reqresp/handlers/lightClientFinalityUpdate.js +6 -8
- package/lib/network/reqresp/handlers/lightClientFinalityUpdate.js.map +1 -1
- package/lib/network/reqresp/handlers/lightClientOptimisticUpdate.js +6 -8
- package/lib/network/reqresp/handlers/lightClientOptimisticUpdate.js.map +1 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js +1 -3
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js.map +1 -1
- package/lib/network/reqresp/protocols.js +0 -1
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/rateLimit.js +1 -1
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/reqresp/score.js +0 -1
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/reqresp/types.js +3 -7
- package/lib/network/reqresp/types.js.map +1 -1
- package/lib/network/reqresp/utils/collect.d.ts +1 -1
- package/lib/network/reqresp/utils/collectSequentialBlocksInRange.d.ts +1 -2
- package/lib/network/reqresp/utils/collectSequentialBlocksInRange.js.map +1 -1
- package/lib/network/util.js +1 -1
- package/lib/network/util.js.map +1 -1
- package/lib/node/nodejs.js +1 -1
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.js +16 -26
- package/lib/node/notifier.js.map +1 -1
- package/lib/node/options.d.ts +2 -2
- package/lib/node/options.js +2 -2
- package/lib/node/options.js.map +1 -1
- package/lib/sync/backfill/backfill.d.ts +2 -2
- package/lib/sync/backfill/backfill.js +4 -2
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts +1 -2
- package/lib/sync/backfill/verify.js.map +1 -1
- package/lib/sync/range/range.d.ts +1 -1
- package/lib/sync/range/range.js +3 -7
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/range/utils/batches.js +1 -3
- package/lib/sync/range/utils/batches.js.map +1 -1
- package/lib/sync/sync.js +26 -25
- package/lib/sync/sync.js.map +1 -1
- package/lib/sync/unknownBlock.js +2 -6
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/remoteSyncType.js +25 -36
- package/lib/sync/utils/remoteSyncType.js.map +1 -1
- package/lib/util/asyncIterableToEvents.js +0 -2
- package/lib/util/asyncIterableToEvents.js.map +1 -1
- package/lib/util/binarySearch.js +1 -1
- package/lib/util/binarySearch.js.map +1 -1
- package/lib/util/bitArray.js +1 -2
- package/lib/util/bitArray.js.map +1 -1
- package/lib/util/kzg.js +3 -4
- package/lib/util/kzg.js.map +1 -1
- package/lib/util/map.js +0 -1
- package/lib/util/map.js.map +1 -1
- package/lib/util/profile.js +1 -1
- package/lib/util/profile.js.map +1 -1
- package/lib/util/queue/errors.d.ts +0 -1
- package/lib/util/queue/errors.js +0 -3
- package/lib/util/queue/errors.js.map +1 -1
- package/lib/util/queue/fnQueue.js +1 -1
- package/lib/util/queue/fnQueue.js.map +1 -1
- package/lib/util/queue/itemQueue.js +1 -1
- package/lib/util/queue/itemQueue.js.map +1 -1
- package/package.json +19 -18
- package/lib/chain/archiver/archiveStates.js.map +0 -1
- package/lib/network/processor/gossipQueues/indexedAvgTime.d.ts +0 -31
- package/lib/network/processor/gossipQueues/indexedAvgTime.js +0 -115
- package/lib/network/processor/gossipQueues/indexedAvgTime.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { PubkeyIndexMap } from "@chainsafe/pubkey-index-map";
|
|
1
2
|
import { routes } from "@lodestar/api";
|
|
2
|
-
import { computeStartSlotAtEpoch, calculateCommitteeAssignments, proposerShufflingDecisionRoot, attesterShufflingDecisionRoot, getBlockRootAtSlot, computeEpochAtSlot, getCurrentSlot, beaconBlockToBlinded, } from "@lodestar/state-transition";
|
|
3
|
+
import { computeStartSlotAtEpoch, calculateCommitteeAssignments, proposerShufflingDecisionRoot, attesterShufflingDecisionRoot, getBlockRootAtSlot, computeEpochAtSlot, getCurrentSlot, beaconBlockToBlinded, createCachedBeaconState, loadState, } from "@lodestar/state-transition";
|
|
3
4
|
import { GENESIS_SLOT, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT, SYNC_COMMITTEE_SUBNET_SIZE, isForkBlobs, isForkExecution, ForkSeq, isForkPostElectra, } from "@lodestar/params";
|
|
4
5
|
import { MAX_BUILDER_BOOST_FACTOR } from "@lodestar/validator";
|
|
5
|
-
import { ssz, ProducedBlockSource, isBlindedBeaconBlock, isBlockContents, } from "@lodestar/types";
|
|
6
|
+
import { ssz, ProducedBlockSource, isBlindedBeaconBlock, isBlockContents, getValidatorStatus, } from "@lodestar/types";
|
|
6
7
|
import { ExecutionStatus, DataAvailabilityStatus } from "@lodestar/fork-choice";
|
|
7
|
-
import { fromHex, toHex, resolveOrRacePromises, prettyWeiToEth, toRootHex } from "@lodestar/utils";
|
|
8
|
+
import { fromHex, toHex, resolveOrRacePromises, prettyWeiToEth, toRootHex, TimeoutError, formatWeiToEth, } from "@lodestar/utils";
|
|
8
9
|
import { AttestationError, AttestationErrorCode, GossipAction, SyncCommitteeError, SyncCommitteeErrorCode, } from "../../../chain/errors/index.js";
|
|
9
10
|
import { validateApiAggregateAndProof } from "../../../chain/validation/index.js";
|
|
10
11
|
import { ZERO_HASH } from "../../../constants/index.js";
|
|
@@ -14,10 +15,11 @@ import { getDefaultGraffiti, toGraffitiBuffer } from "../../../util/graffiti.js"
|
|
|
14
15
|
import { ApiError, NodeIsSyncing, OnlySupportedByDVT } from "../errors.js";
|
|
15
16
|
import { validateSyncCommitteeGossipContributionAndProof } from "../../../chain/validation/syncCommitteeContributionAndProof.js";
|
|
16
17
|
import { RegenCaller } from "../../../chain/regen/index.js";
|
|
17
|
-
import {
|
|
18
|
+
import { getStateResponseWithRegen } from "../beacon/state/utils.js";
|
|
18
19
|
import { validateGossipFnRetryUnknownRoot } from "../../../network/processor/gossipHandlers.js";
|
|
19
20
|
import { SCHEDULER_LOOKAHEAD_FACTOR } from "../../../chain/prepareNextSlot.js";
|
|
20
21
|
import { ChainEvent } from "../../../chain/index.js";
|
|
22
|
+
import { NoBidReceived } from "../../../execution/builder/http.js";
|
|
21
23
|
import { getLodestarClientVersion } from "../../../util/metadata.js";
|
|
22
24
|
import { computeSubnetForCommitteesAtSlot, getPubkeysForIndices, selectBlockProductionSource } from "./utils.js";
|
|
23
25
|
/**
|
|
@@ -35,7 +37,7 @@ import { computeSubnetForCommitteesAtSlot, getPubkeysForIndices, selectBlockProd
|
|
|
35
37
|
*/
|
|
36
38
|
export const SYNC_TOLERANCE_EPOCHS = 1;
|
|
37
39
|
/**
|
|
38
|
-
* Cutoff time to wait for execution and builder block production apis to resolve
|
|
40
|
+
* Cutoff time to wait from start of the slot for execution and builder block production apis to resolve
|
|
39
41
|
* Post this time, race execution and builder to pick whatever resolves first
|
|
40
42
|
*
|
|
41
43
|
* Empirically the builder block resolves in ~1.5+ seconds, and execution should resolve <1 sec.
|
|
@@ -45,6 +47,31 @@ export const SYNC_TOLERANCE_EPOCHS = 1;
|
|
|
45
47
|
const BLOCK_PRODUCTION_RACE_CUTOFF_MS = 2_000;
|
|
46
48
|
/** Overall timeout for execution and block production apis */
|
|
47
49
|
const BLOCK_PRODUCTION_RACE_TIMEOUT_MS = 12_000;
|
|
50
|
+
/**
|
|
51
|
+
* Engine block selection reasons tracked in metrics
|
|
52
|
+
*/
|
|
53
|
+
export var EngineBlockSelectionReason;
|
|
54
|
+
(function (EngineBlockSelectionReason) {
|
|
55
|
+
EngineBlockSelectionReason["BuilderDisabled"] = "builder_disabled";
|
|
56
|
+
EngineBlockSelectionReason["BuilderError"] = "builder_error";
|
|
57
|
+
EngineBlockSelectionReason["BuilderTimeout"] = "builder_timeout";
|
|
58
|
+
EngineBlockSelectionReason["BuilderPending"] = "builder_pending";
|
|
59
|
+
EngineBlockSelectionReason["BuilderNoBid"] = "builder_no_bid";
|
|
60
|
+
EngineBlockSelectionReason["BuilderCensorship"] = "builder_censorship";
|
|
61
|
+
EngineBlockSelectionReason["BlockValue"] = "block_value";
|
|
62
|
+
EngineBlockSelectionReason["EnginePreferred"] = "engine_preferred";
|
|
63
|
+
})(EngineBlockSelectionReason || (EngineBlockSelectionReason = {}));
|
|
64
|
+
/**
|
|
65
|
+
* Builder block selection reasons tracked in metrics
|
|
66
|
+
*/
|
|
67
|
+
export var BuilderBlockSelectionReason;
|
|
68
|
+
(function (BuilderBlockSelectionReason) {
|
|
69
|
+
BuilderBlockSelectionReason["EngineDisabled"] = "engine_disabled";
|
|
70
|
+
BuilderBlockSelectionReason["EngineError"] = "engine_error";
|
|
71
|
+
BuilderBlockSelectionReason["EnginePending"] = "engine_pending";
|
|
72
|
+
BuilderBlockSelectionReason["BlockValue"] = "block_value";
|
|
73
|
+
BuilderBlockSelectionReason["BuilderPreferred"] = "builder_preferred";
|
|
74
|
+
})(BuilderBlockSelectionReason || (BuilderBlockSelectionReason = {}));
|
|
48
75
|
/**
|
|
49
76
|
* Server implementation for handling validator duties.
|
|
50
77
|
* See `@lodestar/validator/src/api` for the client implementation).
|
|
@@ -90,7 +117,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
90
117
|
if (msToSlot > MAX_API_CLOCK_DISPARITY_MS) {
|
|
91
118
|
throw Error(`Requested slot ${slot} is in the future`);
|
|
92
119
|
}
|
|
93
|
-
|
|
120
|
+
if (msToSlot > 0) {
|
|
94
121
|
await chain.clock.waitForSlot(slot);
|
|
95
122
|
}
|
|
96
123
|
// else, clock already in slot or slot is in the past
|
|
@@ -129,20 +156,18 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
129
156
|
blockTotalValue: prettyWeiToEth(totalValue),
|
|
130
157
|
};
|
|
131
158
|
}
|
|
132
|
-
|
|
159
|
+
if (source === ProducedBlockSource.builder) {
|
|
133
160
|
return {
|
|
134
161
|
builderExecutionPayloadValue: prettyWeiToEth(executionValue),
|
|
135
162
|
builderConsensusBlockValue: prettyWeiToEth(consensusValue),
|
|
136
163
|
builderBlockTotalValue: prettyWeiToEth(totalValue),
|
|
137
164
|
};
|
|
138
165
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
};
|
|
145
|
-
}
|
|
166
|
+
return {
|
|
167
|
+
engineExecutionPayloadValue: prettyWeiToEth(executionValue),
|
|
168
|
+
engineConsensusBlockValue: prettyWeiToEth(consensusValue),
|
|
169
|
+
engineBlockTotalValue: prettyWeiToEth(totalValue),
|
|
170
|
+
};
|
|
146
171
|
}
|
|
147
172
|
/**
|
|
148
173
|
* This function is called 1s before next epoch, usually at that time PrepareNextSlotScheduler finishes
|
|
@@ -204,9 +229,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
204
229
|
if (currentSlot - headSlot > SYNC_TOLERANCE_EPOCHS * SLOTS_PER_EPOCH) {
|
|
205
230
|
throw new NodeIsSyncing(`headSlot ${headSlot} currentSlot ${currentSlot}`);
|
|
206
231
|
}
|
|
207
|
-
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
232
|
+
return;
|
|
210
233
|
}
|
|
211
234
|
case SyncState.Synced:
|
|
212
235
|
return;
|
|
@@ -269,10 +292,6 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
269
292
|
if (skipHeadChecksAndUpdate !== true) {
|
|
270
293
|
notWhileSyncing();
|
|
271
294
|
await waitForSlot(slot); // Must never request for a future slot > currentSlot
|
|
272
|
-
// Process the queued attestations in the forkchoice for correct head estimation
|
|
273
|
-
// forkChoice.updateTime() might have already been called by the onSlot clock
|
|
274
|
-
// handler, in which case this should just return.
|
|
275
|
-
chain.forkChoice.updateTime(slot);
|
|
276
295
|
parentBlockRoot = fromHex(chain.getProposerHead(slot).blockRoot);
|
|
277
296
|
}
|
|
278
297
|
else {
|
|
@@ -291,6 +310,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
291
310
|
});
|
|
292
311
|
metrics?.blockProductionSuccess.inc({ source });
|
|
293
312
|
metrics?.blockProductionNumAggregated.observe({ source }, block.body.attestations.length);
|
|
313
|
+
metrics?.blockProductionExecutionPayloadValue.observe({ source }, Number(formatWeiToEth(executionPayloadValue)));
|
|
294
314
|
logger.verbose("Produced blinded block", {
|
|
295
315
|
slot,
|
|
296
316
|
executionPayloadValue,
|
|
@@ -314,10 +334,6 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
314
334
|
if (skipHeadChecksAndUpdate !== true) {
|
|
315
335
|
notWhileSyncing();
|
|
316
336
|
await waitForSlot(slot); // Must never request for a future slot > currentSlot
|
|
317
|
-
// Process the queued attestations in the forkchoice for correct head estimation
|
|
318
|
-
// forkChoice.updateTime() might have already been called by the onSlot clock
|
|
319
|
-
// handler, in which case this should just return.
|
|
320
|
-
chain.forkChoice.updateTime(slot);
|
|
321
337
|
parentBlockRoot = fromHex(chain.getProposerHead(slot).blockRoot);
|
|
322
338
|
}
|
|
323
339
|
else {
|
|
@@ -344,6 +360,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
344
360
|
}
|
|
345
361
|
metrics?.blockProductionSuccess.inc({ source });
|
|
346
362
|
metrics?.blockProductionNumAggregated.observe({ source }, block.body.attestations.length);
|
|
363
|
+
metrics?.blockProductionExecutionPayloadValue.observe({ source }, Number(formatWeiToEth(executionPayloadValue)));
|
|
347
364
|
logger.verbose("Produced execution block", {
|
|
348
365
|
slot,
|
|
349
366
|
executionPayloadValue,
|
|
@@ -367,9 +384,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
367
384
|
shouldOverrideBuilder,
|
|
368
385
|
};
|
|
369
386
|
}
|
|
370
|
-
|
|
371
|
-
return { data: block, version, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder };
|
|
372
|
-
}
|
|
387
|
+
return { data: block, version, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder };
|
|
373
388
|
}
|
|
374
389
|
finally {
|
|
375
390
|
if (timer)
|
|
@@ -381,10 +396,6 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
381
396
|
_skipRandaoVerification, builderBoostFactor, { feeRecipient, builderSelection, strictFeeRecipientCheck } = {}) {
|
|
382
397
|
notWhileSyncing();
|
|
383
398
|
await waitForSlot(slot); // Must never request for a future slot > currentSlot
|
|
384
|
-
// Process the queued attestations in the forkchoice for correct head estimation
|
|
385
|
-
// forkChoice.updateTime() might have already been called by the onSlot clock
|
|
386
|
-
// handler, in which case this should just return.
|
|
387
|
-
chain.forkChoice.updateTime(slot);
|
|
388
399
|
const parentBlockRoot = fromHex(chain.getProposerHead(slot).blockRoot);
|
|
389
400
|
notOnOutOfRangeData(parentBlockRoot);
|
|
390
401
|
const fork = config.getForkName(slot);
|
|
@@ -429,9 +440,11 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
429
440
|
graffiti: toGraffitiBuffer(graffiti ?? getDefaultGraffiti(getLodestarClientVersion(opts), chain.executionEngine.clientVersion, opts)),
|
|
430
441
|
});
|
|
431
442
|
logger.debug("Produced common block body", loggerContext);
|
|
443
|
+
// Calculate cutoff time based on start of the slot
|
|
444
|
+
const cutoffMs = Math.max(0, BLOCK_PRODUCTION_RACE_CUTOFF_MS - Math.round(chain.clock.secFromSlot(slot) * 1000));
|
|
432
445
|
logger.verbose("Block production race (builder vs execution) starting", {
|
|
433
446
|
...loggerContext,
|
|
434
|
-
cutoffMs
|
|
447
|
+
cutoffMs,
|
|
435
448
|
timeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS,
|
|
436
449
|
});
|
|
437
450
|
// use abort controller to stop waiting for both block sources
|
|
@@ -470,7 +483,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
470
483
|
})
|
|
471
484
|
: Promise.reject(new Error("Engine disabled"));
|
|
472
485
|
const [builder, engine] = await resolveOrRacePromises([builderPromise, enginePromise], {
|
|
473
|
-
resolveTimeoutMs:
|
|
486
|
+
resolveTimeoutMs: cutoffMs,
|
|
474
487
|
raceTimeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS,
|
|
475
488
|
signal: controller.signal,
|
|
476
489
|
});
|
|
@@ -484,10 +497,18 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
484
497
|
}, engine.reason);
|
|
485
498
|
}
|
|
486
499
|
if (builder.status === "rejected" && isBuilderEnabled) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
500
|
+
if (builder.reason instanceof NoBidReceived) {
|
|
501
|
+
logger.info("Builder did not provide a bid", {
|
|
502
|
+
...loggerContext,
|
|
503
|
+
durationMs: builder.durationMs,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
logger.warn("Builder failed to produce the block", {
|
|
508
|
+
...loggerContext,
|
|
509
|
+
durationMs: builder.durationMs,
|
|
510
|
+
}, builder.reason);
|
|
511
|
+
}
|
|
491
512
|
}
|
|
492
513
|
if (builder.status === "rejected" && engine.status === "rejected") {
|
|
493
514
|
throw Error(`${isBuilderEnabled && isEngineEnabled ? "Builder and engine both" : isBuilderEnabled ? "Builder" : "Engine"} failed to produce the block`);
|
|
@@ -500,6 +521,10 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
500
521
|
shouldOverrideBuilder: engine.value.shouldOverrideBuilder,
|
|
501
522
|
...getBlockValueLogInfo(engine.value),
|
|
502
523
|
});
|
|
524
|
+
metrics?.blockProductionSelectionResults.inc({
|
|
525
|
+
source: ProducedBlockSource.engine,
|
|
526
|
+
reason: EngineBlockSelectionReason.BuilderCensorship,
|
|
527
|
+
});
|
|
503
528
|
return { ...engine.value, executionPayloadBlinded: false, executionPayloadSource: ProducedBlockSource.engine };
|
|
504
529
|
}
|
|
505
530
|
if (builder.status === "fulfilled" && engine.status !== "fulfilled") {
|
|
@@ -508,6 +533,14 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
508
533
|
durationMs: builder.durationMs,
|
|
509
534
|
...getBlockValueLogInfo(builder.value),
|
|
510
535
|
});
|
|
536
|
+
metrics?.blockProductionSelectionResults.inc({
|
|
537
|
+
source: ProducedBlockSource.builder,
|
|
538
|
+
reason: isEngineEnabled === false
|
|
539
|
+
? BuilderBlockSelectionReason.EngineDisabled
|
|
540
|
+
: engine.status === "pending"
|
|
541
|
+
? BuilderBlockSelectionReason.EnginePending
|
|
542
|
+
: BuilderBlockSelectionReason.EngineError,
|
|
543
|
+
});
|
|
511
544
|
return { ...builder.value, executionPayloadBlinded: true, executionPayloadSource: ProducedBlockSource.builder };
|
|
512
545
|
}
|
|
513
546
|
if (engine.status === "fulfilled" && builder.status !== "fulfilled") {
|
|
@@ -516,15 +549,29 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
516
549
|
durationMs: engine.durationMs,
|
|
517
550
|
...getBlockValueLogInfo(engine.value),
|
|
518
551
|
});
|
|
552
|
+
metrics?.blockProductionSelectionResults.inc({
|
|
553
|
+
source: ProducedBlockSource.engine,
|
|
554
|
+
reason: isBuilderEnabled === false
|
|
555
|
+
? EngineBlockSelectionReason.BuilderDisabled
|
|
556
|
+
: builder.status === "pending"
|
|
557
|
+
? EngineBlockSelectionReason.BuilderPending
|
|
558
|
+
: builder.reason instanceof NoBidReceived
|
|
559
|
+
? EngineBlockSelectionReason.BuilderNoBid
|
|
560
|
+
: builder.reason instanceof TimeoutError
|
|
561
|
+
? EngineBlockSelectionReason.BuilderTimeout
|
|
562
|
+
: EngineBlockSelectionReason.BuilderError,
|
|
563
|
+
});
|
|
519
564
|
return { ...engine.value, executionPayloadBlinded: false, executionPayloadSource: ProducedBlockSource.engine };
|
|
520
565
|
}
|
|
521
566
|
if (engine.status === "fulfilled" && builder.status === "fulfilled") {
|
|
522
|
-
const
|
|
567
|
+
const result = selectBlockProductionSource({
|
|
523
568
|
builderBlockValue: builder.value.executionPayloadValue + builder.value.consensusBlockValue,
|
|
524
569
|
engineBlockValue: engine.value.executionPayloadValue + engine.value.consensusBlockValue,
|
|
525
570
|
builderBoostFactor,
|
|
526
571
|
builderSelection,
|
|
527
572
|
});
|
|
573
|
+
const executionPayloadSource = result.source;
|
|
574
|
+
metrics?.blockProductionSelectionResults.inc(result);
|
|
528
575
|
logger.info(`Selected ${executionPayloadSource} block`, {
|
|
529
576
|
...loggerContext,
|
|
530
577
|
engineDurationMs: engine.durationMs,
|
|
@@ -539,13 +586,11 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
539
586
|
executionPayloadSource,
|
|
540
587
|
};
|
|
541
588
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
};
|
|
548
|
-
}
|
|
589
|
+
return {
|
|
590
|
+
...builder.value,
|
|
591
|
+
executionPayloadBlinded: true,
|
|
592
|
+
executionPayloadSource,
|
|
593
|
+
};
|
|
549
594
|
}
|
|
550
595
|
throw Error("Unreachable error occurred during the builder and execution block production");
|
|
551
596
|
}
|
|
@@ -560,27 +605,21 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
560
605
|
if (meta.executionPayloadBlinded) {
|
|
561
606
|
return { data, meta };
|
|
562
607
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
else {
|
|
573
|
-
const blindedBlock = beaconBlockToBlinded(config, data);
|
|
574
|
-
return {
|
|
575
|
-
data: blindedBlock,
|
|
576
|
-
meta: { ...meta, executionPayloadBlinded: true },
|
|
577
|
-
};
|
|
578
|
-
}
|
|
608
|
+
if (isBlockContents(data)) {
|
|
609
|
+
const { block } = data;
|
|
610
|
+
const blindedBlock = beaconBlockToBlinded(config, block);
|
|
611
|
+
return {
|
|
612
|
+
data: blindedBlock,
|
|
613
|
+
meta: { ...meta, executionPayloadBlinded: true },
|
|
614
|
+
};
|
|
579
615
|
}
|
|
616
|
+
const blindedBlock = beaconBlockToBlinded(config, data);
|
|
617
|
+
return {
|
|
618
|
+
data: blindedBlock,
|
|
619
|
+
meta: { ...meta, executionPayloadBlinded: true },
|
|
620
|
+
};
|
|
580
621
|
}
|
|
581
|
-
|
|
582
|
-
return { data, meta };
|
|
583
|
-
}
|
|
622
|
+
return { data, meta };
|
|
584
623
|
},
|
|
585
624
|
async produceBlindedBlock({ slot, randaoReveal, graffiti }) {
|
|
586
625
|
const { data, version } = await produceEngineOrBuilderBlock(slot, randaoReveal, graffiti);
|
|
@@ -592,13 +631,11 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
592
631
|
const blindedBlock = beaconBlockToBlinded(config, block);
|
|
593
632
|
return { data: blindedBlock, meta: { version } };
|
|
594
633
|
}
|
|
595
|
-
|
|
634
|
+
if (isBlindedBeaconBlock(data)) {
|
|
596
635
|
return { data, meta: { version } };
|
|
597
636
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
return { data: blindedBlock, meta: { version } };
|
|
601
|
-
}
|
|
637
|
+
const blindedBlock = beaconBlockToBlinded(config, data);
|
|
638
|
+
return { data: blindedBlock, meta: { version } };
|
|
602
639
|
},
|
|
603
640
|
async produceAttestationData({ committeeIndex, slot }) {
|
|
604
641
|
notWhileSyncing();
|
|
@@ -674,14 +711,15 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
674
711
|
},
|
|
675
712
|
async getProposerDuties({ epoch }) {
|
|
676
713
|
notWhileSyncing();
|
|
677
|
-
// Early check that epoch is
|
|
714
|
+
// Early check that epoch is no more than current_epoch + 1, or allow for pre-genesis
|
|
678
715
|
const currentEpoch = currentEpochWithDisparity();
|
|
679
716
|
const nextEpoch = currentEpoch + 1;
|
|
680
|
-
if (currentEpoch >= 0 && epoch
|
|
681
|
-
throw
|
|
717
|
+
if (currentEpoch >= 0 && epoch > nextEpoch) {
|
|
718
|
+
throw new ApiError(400, `Requested epoch ${epoch} must not be more than one epoch in the future`);
|
|
682
719
|
}
|
|
683
720
|
const head = chain.forkChoice.getHead();
|
|
684
721
|
let state = undefined;
|
|
722
|
+
const startSlot = computeStartSlotAtEpoch(epoch);
|
|
685
723
|
const slotMs = config.SECONDS_PER_SLOT * 1000;
|
|
686
724
|
const prepareNextSlotLookAheadMs = slotMs / SCHEDULER_LOOKAHEAD_FACTOR;
|
|
687
725
|
const toNextEpochMs = msToNextEpoch();
|
|
@@ -699,28 +737,59 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
699
737
|
}
|
|
700
738
|
}
|
|
701
739
|
if (!state) {
|
|
702
|
-
|
|
740
|
+
if (epoch >= currentEpoch - 1) {
|
|
741
|
+
// Cached beacon state stores proposers for previous, current and next epoch. The
|
|
742
|
+
// requested epoch is within that range, we can use the head state at current epoch
|
|
743
|
+
state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.getDuties);
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
const res = await getStateResponseWithRegen(chain, startSlot);
|
|
747
|
+
const stateViewDU = res.state instanceof Uint8Array
|
|
748
|
+
? loadState(config, chain.getHeadState(), res.state).state
|
|
749
|
+
: res.state.clone();
|
|
750
|
+
state = createCachedBeaconState(stateViewDU, {
|
|
751
|
+
config: chain.config,
|
|
752
|
+
// Not required to compute proposers
|
|
753
|
+
pubkey2index: new PubkeyIndexMap(),
|
|
754
|
+
index2pubkey: [],
|
|
755
|
+
}, { skipSyncPubkeys: true, skipSyncCommitteeCache: true });
|
|
756
|
+
if (state.epochCtx.epoch !== epoch) {
|
|
757
|
+
throw Error(`Loaded state epoch ${state.epochCtx.epoch} does not match requested epoch ${epoch}`);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
703
760
|
}
|
|
704
761
|
const stateEpoch = state.epochCtx.epoch;
|
|
705
762
|
let indexes = [];
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
763
|
+
switch (epoch) {
|
|
764
|
+
case stateEpoch:
|
|
765
|
+
indexes = state.epochCtx.getBeaconProposers();
|
|
766
|
+
break;
|
|
767
|
+
case stateEpoch + 1:
|
|
768
|
+
// make sure shuffling is calculated and ready for next call to calculate nextProposers
|
|
769
|
+
await chain.shufflingCache.get(state.epochCtx.nextEpoch, state.epochCtx.nextDecisionRoot);
|
|
770
|
+
// Requesting duties for next epoch is allowed since they can be predicted with high probabilities.
|
|
771
|
+
// @see `epochCtx.getBeaconProposersNextEpoch` JSDocs for rationale.
|
|
772
|
+
indexes = state.epochCtx.getBeaconProposersNextEpoch();
|
|
773
|
+
break;
|
|
774
|
+
case stateEpoch - 1: {
|
|
775
|
+
const indexesPrevEpoch = state.epochCtx.getBeaconProposersPrevEpoch();
|
|
776
|
+
if (indexesPrevEpoch === null) {
|
|
777
|
+
// Should not happen as previous proposer duties should be initialized for head state
|
|
778
|
+
// and if we load state from `Uint8Array` it will always be the state of requested epoch
|
|
779
|
+
throw Error(`Proposer duties for previous epoch ${epoch} not yet initialized`);
|
|
780
|
+
}
|
|
781
|
+
indexes = indexesPrevEpoch;
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
default:
|
|
785
|
+
// Should never happen, epoch is checked to be in bounds above
|
|
786
|
+
throw Error(`Proposer duties for epoch ${epoch} not supported, current epoch ${stateEpoch}`);
|
|
717
787
|
}
|
|
718
788
|
// NOTE: this is the fastest way of getting compressed pubkeys.
|
|
719
789
|
// See benchmark -> packages/lodestar/test/perf/api/impl/validator/attester.test.ts
|
|
720
790
|
// After dropping the flat caches attached to the CachedBeaconState it's no longer available.
|
|
721
791
|
// TODO: Add a flag to just send 0x00 as pubkeys since the Lodestar validator does not need them.
|
|
722
792
|
const pubkeys = getPubkeysForIndices(state.validators, indexes);
|
|
723
|
-
const startSlot = computeStartSlotAtEpoch(epoch);
|
|
724
793
|
const duties = [];
|
|
725
794
|
for (let i = 0; i < SLOTS_PER_EPOCH; i++) {
|
|
726
795
|
duties.push({ slot: startSlot + i, validatorIndex: indexes[i], pubkey: pubkeys[i] });
|
|
@@ -873,7 +942,6 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
873
942
|
await Promise.all(signedAggregateAndProofs.map(async (signedAggregateAndProof, i) => {
|
|
874
943
|
try {
|
|
875
944
|
// TODO: Validate in batch
|
|
876
|
-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
877
945
|
const validateFn = () => validateApiAggregateAndProof(fork, chain, signedAggregateAndProof);
|
|
878
946
|
const { slot, beaconBlockRoot } = signedAggregateAndProof.message.aggregate.data;
|
|
879
947
|
// when a validator is configured with multiple beacon node urls, this attestation may come from another beacon node
|
|
@@ -903,7 +971,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
903
971
|
if (errors.length > 1) {
|
|
904
972
|
throw Error("Multiple errors on publishAggregateAndProofs\n" + errors.map((e) => e.message).join("\n"));
|
|
905
973
|
}
|
|
906
|
-
|
|
974
|
+
if (errors.length === 1) {
|
|
907
975
|
throw errors[0];
|
|
908
976
|
}
|
|
909
977
|
},
|
|
@@ -945,7 +1013,7 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
945
1013
|
if (errors.length > 1) {
|
|
946
1014
|
throw Error("Multiple errors on publishContributionAndProofs\n" + errors.map((e) => e.message).join("\n"));
|
|
947
1015
|
}
|
|
948
|
-
|
|
1016
|
+
if (errors.length === 1) {
|
|
949
1017
|
throw errors[0];
|
|
950
1018
|
}
|
|
951
1019
|
},
|
|
@@ -1036,12 +1104,11 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
1036
1104
|
const filteredRegistrations = registrations.filter((registration) => {
|
|
1037
1105
|
const { pubkey } = registration.message;
|
|
1038
1106
|
const validatorIndex = headState.epochCtx.pubkey2index.get(pubkey);
|
|
1039
|
-
if (validatorIndex ===
|
|
1107
|
+
if (validatorIndex === null)
|
|
1040
1108
|
return false;
|
|
1041
1109
|
const validator = headState.validators.getReadonly(validatorIndex);
|
|
1042
1110
|
const status = getValidatorStatus(validator, currentEpoch);
|
|
1043
|
-
return (status === "
|
|
1044
|
-
status === "active_exiting" ||
|
|
1111
|
+
return (status === "active_exiting" ||
|
|
1045
1112
|
status === "active_ongoing" ||
|
|
1046
1113
|
status === "active_slashed" ||
|
|
1047
1114
|
status === "pending_initialized" ||
|