@lodestar/beacon-node 1.43.0-dev.e341cdc614 → 1.43.0-dev.e3c96e7a79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +17 -9
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +45 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -2
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +0 -1
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.js +1 -1
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +68 -6
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +4 -4
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +4 -1
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +16 -28
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +28 -14
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +88 -90
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts +5 -3
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +59 -26
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +4 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +9 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +2 -2
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +15 -20
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +89 -12
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +5 -3
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +50 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +79 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -6
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +29 -13
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +3 -14
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +0 -4
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +8 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/errors/index.d.ts +1 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +1 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +40 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/errors/proposerPreferences.js +14 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -0
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +11 -19
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +6 -1
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +7 -5
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +26 -4
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +45 -17
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +13 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +68 -25
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -0
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +1 -4
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +1 -4
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -0
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -0
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +22 -6
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +53 -17
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
- package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -0
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +24 -9
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +19 -9
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +4 -3
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +8 -0
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/validation/proposerPreferences.js +91 -0
- package/lib/chain/validation/proposerPreferences.js.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +21 -14
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +1 -0
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +6 -0
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +20 -0
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +18 -0
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +1 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +4 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +7 -1
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +1 -0
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.js +12 -1
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +13 -2
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +6 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +1 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +6 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +41 -19
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/index.js +5 -0
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +6 -5
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +6 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/constants.d.ts +3 -1
- package/lib/sync/constants.d.ts.map +1 -1
- package/lib/sync/constants.js +3 -4
- package/lib/sync/constants.js.map +1 -1
- package/lib/sync/range/batch.d.ts +28 -2
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +146 -44
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +12 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +53 -9
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +17 -6
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/types.d.ts +34 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +34 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +22 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +604 -53
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +46 -10
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +162 -24
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +16 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.js +0 -9
- package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +20 -5
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +17 -16
- package/src/api/impl/beacon/blocks/index.ts +22 -9
- package/src/api/impl/beacon/pool/index.ts +83 -1
- package/src/api/impl/beacon/state/utils.ts +2 -2
- package/src/api/impl/debug/index.ts +0 -1
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +82 -5
- package/src/chain/archiveStore/archiveStore.ts +5 -5
- package/src/chain/archiveStore/interface.ts +4 -4
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +4 -4
- package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
- package/src/chain/blocks/blockInput/blockInput.ts +4 -1
- package/src/chain/blocks/importBlock.ts +16 -48
- package/src/chain/blocks/importExecutionPayload.ts +109 -105
- package/src/chain/blocks/index.ts +73 -23
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +10 -2
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
- package/src/chain/blocks/types.ts +15 -25
- package/src/chain/blocks/utils/chainSegment.ts +114 -17
- package/src/chain/blocks/verifyBlock.ts +70 -9
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +134 -0
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
- package/src/chain/chain.ts +48 -26
- package/src/chain/emitter.ts +3 -14
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/executionPayloadBid.ts +6 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/errors/proposerPreferences.ts +47 -0
- package/src/chain/forkChoice/index.ts +8 -24
- package/src/chain/initState.ts +9 -1
- package/src/chain/interface.ts +11 -3
- package/src/chain/opPools/payloadAttestationPool.ts +29 -8
- package/src/chain/prepareNextSlot.ts +53 -18
- package/src/chain/produceBlock/produceBlockBody.ts +91 -21
- package/src/chain/regen/interface.ts +1 -0
- package/src/chain/regen/queued.ts +2 -7
- package/src/chain/regen/regen.ts +2 -7
- package/src/chain/seenCache/index.ts +1 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +71 -20
- package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
- package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/executionPayloadBid.ts +25 -8
- package/src/chain/validation/executionPayloadEnvelope.ts +20 -10
- package/src/chain/validation/payloadAttestationMessage.ts +5 -3
- package/src/chain/validation/proposerPreferences.ts +110 -0
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
- package/src/execution/engine/http.ts +21 -14
- package/src/execution/engine/interface.ts +1 -0
- package/src/execution/engine/mock.ts +8 -1
- package/src/execution/engine/types.ts +41 -0
- package/src/metrics/metrics/lodestar.ts +4 -0
- package/src/network/gossip/interface.ts +6 -0
- package/src/network/gossip/scoringParameters.ts +14 -1
- package/src/network/gossip/topic.ts +6 -0
- package/src/network/interface.ts +1 -0
- package/src/network/network.ts +12 -1
- package/src/network/processor/gossipHandlers.ts +56 -20
- package/src/network/processor/gossipQueues/index.ts +5 -0
- package/src/network/processor/index.ts +6 -5
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
- package/src/node/nodejs.ts +6 -4
- package/src/sync/constants.ts +4 -4
- package/src/sync/range/batch.ts +204 -49
- package/src/sync/range/chain.ts +69 -11
- package/src/sync/range/range.ts +18 -6
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +762 -57
- package/src/sync/utils/downloadByRange.ts +272 -39
- package/src/sync/utils/downloadByRoot.ts +24 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
- package/src/util/sszBytes.ts +25 -5
|
@@ -4,12 +4,14 @@ import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
|
4
4
|
import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
6
|
IBeaconStateView,
|
|
7
|
+
IBeaconStateViewBellatrix,
|
|
7
8
|
StateHashTreeRootSource,
|
|
8
9
|
computeEpochAtSlot,
|
|
9
10
|
computeTimeAtSlot,
|
|
10
11
|
isStatePostBellatrix,
|
|
12
|
+
isStatePostGloas,
|
|
11
13
|
} from "@lodestar/state-transition";
|
|
12
|
-
import {Slot} from "@lodestar/types";
|
|
14
|
+
import {Bytes32, Slot} from "@lodestar/types";
|
|
13
15
|
import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
|
|
14
16
|
import {GENESIS_SLOT, ZERO_HASH_HEX} from "../constants/constants.js";
|
|
15
17
|
import {BuilderStatus} from "../execution/builder/http.js";
|
|
@@ -81,6 +83,8 @@ export class PrepareNextSlotScheduler {
|
|
|
81
83
|
// calling updateHead() here before we produce a block to reduce reorg possibility
|
|
82
84
|
const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
|
|
83
85
|
const {slot: headSlot, blockRoot: headRoot} = headBlock;
|
|
86
|
+
// may be updated below if we predict a proposer-boost-reorg
|
|
87
|
+
let updatedHead = headBlock;
|
|
84
88
|
|
|
85
89
|
// PS: previously this was comparing slots, but that gave no leway on the skipped
|
|
86
90
|
// slots on epoch bounday. Making it more fluid.
|
|
@@ -123,7 +127,6 @@ export class PrepareNextSlotScheduler {
|
|
|
123
127
|
const proposerIndex = prepareState.getBeaconProposer(prepareSlot);
|
|
124
128
|
const feeRecipient = this.chain.beaconProposerCache.get(proposerIndex);
|
|
125
129
|
let updatedPrepareState = prepareState;
|
|
126
|
-
let updatedHeadRoot = headRoot;
|
|
127
130
|
|
|
128
131
|
if (feeRecipient) {
|
|
129
132
|
// If we are proposing next slot, we need to predict if we can proposer-boost-reorg or not
|
|
@@ -146,7 +149,7 @@ export class PrepareNextSlotScheduler {
|
|
|
146
149
|
{dontTransferCache: !isEpochTransition},
|
|
147
150
|
RegenCaller.predictProposerHead
|
|
148
151
|
);
|
|
149
|
-
|
|
152
|
+
updatedHead = proposerHead;
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
// Update the builder status, if enabled shoot an api call to check status
|
|
@@ -156,28 +159,54 @@ export class PrepareNextSlotScheduler {
|
|
|
156
159
|
this.logger.error("Builder disabled as the check status api failed", {prepareSlot}, e as Error);
|
|
157
160
|
});
|
|
158
161
|
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!isStatePostBellatrix(updatedPrepareState)) {
|
|
165
|
+
throw new Error("Expected Bellatrix state for payload attributes");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let parentBlockHash: Bytes32;
|
|
169
|
+
// Apply parent payload once here as it's reused by EL prep and SSE emit below
|
|
170
|
+
let stateAfterParentPayload: IBeaconStateViewBellatrix = updatedPrepareState;
|
|
171
|
+
if (isStatePostGloas(updatedPrepareState)) {
|
|
172
|
+
if (this.chain.forkChoice.shouldExtendPayload(updatedHead.blockRoot)) {
|
|
173
|
+
parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.blockHash;
|
|
174
|
+
// Skip applying parent payload unless we're proposing the next slot or have to emit payload_attributes events
|
|
175
|
+
if (feeRecipient !== undefined || this.chain.opts.emitPayloadAttributes === true) {
|
|
176
|
+
const parentExecutionRequests = await this.chain.getParentExecutionRequests(
|
|
177
|
+
updatedHead.slot,
|
|
178
|
+
updatedHead.blockRoot
|
|
179
|
+
);
|
|
180
|
+
stateAfterParentPayload = updatedPrepareState.withParentPayloadApplied(parentExecutionRequests);
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
parentBlockHash = updatedPrepareState.latestExecutionPayloadHeader.blockHash;
|
|
187
|
+
}
|
|
159
188
|
|
|
189
|
+
if (feeRecipient) {
|
|
160
190
|
const preparationTime =
|
|
161
191
|
computeTimeAtSlot(this.config, prepareSlot, this.chain.genesisTime) - Date.now() / 1000;
|
|
162
192
|
this.metrics?.blockPayload.payloadAdvancePrepTime.observe(preparationTime);
|
|
163
|
-
if (!isStatePostBellatrix(updatedPrepareState)) {
|
|
164
|
-
throw new Error("Expected Bellatrix state for payload preparation");
|
|
165
|
-
}
|
|
166
193
|
|
|
167
194
|
const safeBlockHash = getSafeExecutionBlockHash(this.chain.forkChoice);
|
|
168
195
|
const finalizedBlockHash =
|
|
169
196
|
this.chain.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
197
|
+
|
|
170
198
|
// awaiting here instead of throwing an async call because there is no other task
|
|
171
|
-
// left for scheduler and this gives nice
|
|
199
|
+
// left for scheduler and this gives nice semantics to catch and log errors in the
|
|
172
200
|
// try/catch wrapper here.
|
|
173
201
|
await prepareExecutionPayload(
|
|
174
202
|
this.chain,
|
|
175
203
|
this.logger,
|
|
176
204
|
fork as ForkPostBellatrix, // State is of execution type
|
|
177
|
-
fromHex(
|
|
205
|
+
fromHex(updatedHead.blockRoot),
|
|
206
|
+
parentBlockHash,
|
|
178
207
|
safeBlockHash,
|
|
179
208
|
finalizedBlockHash,
|
|
180
|
-
|
|
209
|
+
stateAfterParentPayload,
|
|
181
210
|
feeRecipient
|
|
182
211
|
);
|
|
183
212
|
this.logger.verbose("PrepareNextSlotScheduler prepared new payload", {
|
|
@@ -187,24 +216,30 @@ export class PrepareNextSlotScheduler {
|
|
|
187
216
|
});
|
|
188
217
|
}
|
|
189
218
|
|
|
190
|
-
if (
|
|
191
|
-
|
|
219
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
220
|
+
// Cutoff = slot of the parent of the block we'll actually build on (post-reorg).
|
|
221
|
+
// Steady state: cache holds just 2 entries — head (parent for next-slot production)
|
|
222
|
+
// and head.parent (proposer-boost-reorg fallback). Anything older is evicted.
|
|
223
|
+
const updatedHeadParent = this.chain.forkChoice.getBlockHexDefaultStatus(updatedHead.parentRoot);
|
|
224
|
+
if (updatedHeadParent) {
|
|
225
|
+
this.chain.seenPayloadEnvelopeInputCache.pruneBelowParent(updatedHeadParent);
|
|
226
|
+
}
|
|
192
227
|
}
|
|
193
228
|
|
|
194
229
|
this.computeStateHashTreeRoot(updatedPrepareState, isEpochTransition);
|
|
195
230
|
|
|
196
|
-
// If emitPayloadAttributes is true emit a SSE payloadAttributes event
|
|
231
|
+
// If emitPayloadAttributes is true emit a SSE payloadAttributes event for
|
|
232
|
+
// every slot. Without the flag, only emit the event if we are proposing in the next slot.
|
|
197
233
|
if (
|
|
198
|
-
this.chain.opts.emitPayloadAttributes === true &&
|
|
234
|
+
(feeRecipient || this.chain.opts.emitPayloadAttributes === true) &&
|
|
199
235
|
this.chain.emitter.listenerCount(routes.events.EventType.payloadAttributes)
|
|
200
236
|
) {
|
|
201
237
|
const data = getPayloadAttributesForSSE(fork as ForkPostBellatrix, this.chain, {
|
|
202
|
-
prepareState:
|
|
238
|
+
prepareState: stateAfterParentPayload,
|
|
203
239
|
prepareSlot,
|
|
204
|
-
parentBlockRoot: fromHex(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
feeRecipient: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
240
|
+
parentBlockRoot: fromHex(updatedHead.blockRoot),
|
|
241
|
+
parentBlockHash,
|
|
242
|
+
feeRecipient: feeRecipient ?? "0x0000000000000000000000000000000000000000",
|
|
208
243
|
});
|
|
209
244
|
this.chain.emitter.emit(routes.events.EventType.payloadAttributes, {data, version: fork});
|
|
210
245
|
}
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
IBeaconStateView,
|
|
20
20
|
type IBeaconStateViewBellatrix,
|
|
21
21
|
computeTimeAtSlot,
|
|
22
|
-
isParentBlockFull,
|
|
23
22
|
isStatePostBellatrix,
|
|
24
23
|
isStatePostCapella,
|
|
25
24
|
isStatePostGloas,
|
|
@@ -47,8 +46,9 @@ import {
|
|
|
47
46
|
electra,
|
|
48
47
|
fulu,
|
|
49
48
|
gloas,
|
|
49
|
+
ssz,
|
|
50
50
|
} from "@lodestar/types";
|
|
51
|
-
import {Logger, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
51
|
+
import {Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
52
52
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
53
53
|
import {numToQuantity} from "../../execution/engine/utils.js";
|
|
54
54
|
import {
|
|
@@ -111,6 +111,7 @@ export type ProduceFullGloas = {
|
|
|
111
111
|
executionRequests: electra.ExecutionRequests;
|
|
112
112
|
blobsBundle: BlobsBundle<ForkPostGloas>;
|
|
113
113
|
cells: fulu.Cell[][];
|
|
114
|
+
parentBlockRoot: Root;
|
|
114
115
|
};
|
|
115
116
|
export type ProduceFullFulu = {
|
|
116
117
|
type: BlockType.Full;
|
|
@@ -214,14 +215,28 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
214
215
|
});
|
|
215
216
|
|
|
216
217
|
// Get execution payload from EL
|
|
218
|
+
let parentBlockHash: Bytes32;
|
|
219
|
+
let parentExecutionRequests: electra.ExecutionRequests;
|
|
220
|
+
// Apply parent payload once here as it's reused by EL prep and voluntary exit filtering below
|
|
221
|
+
let stateAfterParentPayload: IBeaconStateViewBellatrix = currentState;
|
|
222
|
+
const isExtendingPayload = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot));
|
|
223
|
+
if (isExtendingPayload) {
|
|
224
|
+
parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
|
|
225
|
+
parentExecutionRequests = await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot);
|
|
226
|
+
stateAfterParentPayload = currentState.withParentPayloadApplied(parentExecutionRequests);
|
|
227
|
+
} else {
|
|
228
|
+
parentBlockHash = currentState.latestExecutionPayloadBid.parentBlockHash;
|
|
229
|
+
parentExecutionRequests = ssz.electra.ExecutionRequests.defaultValue();
|
|
230
|
+
}
|
|
217
231
|
const prepareRes = await prepareExecutionPayload(
|
|
218
232
|
this,
|
|
219
233
|
this.logger,
|
|
220
234
|
fork,
|
|
221
235
|
parentBlockRoot,
|
|
236
|
+
parentBlockHash,
|
|
222
237
|
safeBlockHash,
|
|
223
238
|
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
224
|
-
|
|
239
|
+
stateAfterParentPayload,
|
|
225
240
|
feeRecipient
|
|
226
241
|
);
|
|
227
242
|
|
|
@@ -255,8 +270,8 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
255
270
|
|
|
256
271
|
// Create self-build execution payload bid
|
|
257
272
|
const bid: gloas.ExecutionPayloadBid = {
|
|
258
|
-
parentBlockHash
|
|
259
|
-
parentBlockRoot
|
|
273
|
+
parentBlockHash,
|
|
274
|
+
parentBlockRoot,
|
|
260
275
|
blockHash: executionPayload.blockHash,
|
|
261
276
|
prevRandao: currentState.getRandaoMix(currentState.epoch),
|
|
262
277
|
feeRecipient: executionPayload.feeRecipient,
|
|
@@ -266,6 +281,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
266
281
|
value: 0,
|
|
267
282
|
executionPayment: 0,
|
|
268
283
|
blobKzgCommitments: blobsBundle.commitments,
|
|
284
|
+
executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
|
|
269
285
|
};
|
|
270
286
|
const signedBid: gloas.SignedExecutionPayloadBid = {
|
|
271
287
|
message: bid,
|
|
@@ -275,8 +291,19 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
275
291
|
const commonBlockBody = await commonBlockBodyPromise;
|
|
276
292
|
const gloasBody = Object.assign({}, commonBlockBody) as gloas.BeaconBlockBody;
|
|
277
293
|
gloasBody.signedExecutionPayloadBid = signedBid;
|
|
278
|
-
|
|
279
|
-
|
|
294
|
+
gloasBody.payloadAttestations = this.payloadAttestationPool.getPayloadAttestationsForBlock(
|
|
295
|
+
parentBlock.blockRoot,
|
|
296
|
+
blockSlot - 1
|
|
297
|
+
);
|
|
298
|
+
gloasBody.parentExecutionRequests = parentExecutionRequests;
|
|
299
|
+
// Drop voluntary exits that parent_execution_requests have invalidated (e.g. a withdrawal
|
|
300
|
+
// request initiating an exit on the same validator). Op pool selected against the unapplied
|
|
301
|
+
// state, so re-validate against the post-apply state to avoid producing an invalid block.
|
|
302
|
+
if (isExtendingPayload && commonBlockBody.voluntaryExits.length > 0) {
|
|
303
|
+
gloasBody.voluntaryExits = commonBlockBody.voluntaryExits.filter((signedVoluntaryExit) =>
|
|
304
|
+
stateAfterParentPayload.isValidVoluntaryExit(signedVoluntaryExit, false)
|
|
305
|
+
);
|
|
306
|
+
}
|
|
280
307
|
blockBody = gloasBody as AssembledBodyType<T>;
|
|
281
308
|
|
|
282
309
|
// Store execution payload data required to construct execution payload envelope later
|
|
@@ -285,6 +312,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
285
312
|
gloasResult.executionRequests = executionRequests;
|
|
286
313
|
gloasResult.blobsBundle = blobsBundle;
|
|
287
314
|
gloasResult.cells = cells;
|
|
315
|
+
gloasResult.parentBlockRoot = fromHex(parentBlock.blockRoot);
|
|
288
316
|
|
|
289
317
|
const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime);
|
|
290
318
|
this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
|
|
@@ -334,6 +362,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
334
362
|
this.logger,
|
|
335
363
|
fork,
|
|
336
364
|
parentBlockRoot,
|
|
365
|
+
currentState.latestExecutionPayloadHeader.blockHash,
|
|
337
366
|
safeBlockHash,
|
|
338
367
|
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
339
368
|
currentState,
|
|
@@ -442,6 +471,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
442
471
|
this.logger,
|
|
443
472
|
fork,
|
|
444
473
|
parentBlockRoot,
|
|
474
|
+
currentState.latestExecutionPayloadHeader.blockHash,
|
|
445
475
|
safeBlockHash,
|
|
446
476
|
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
447
477
|
currentState,
|
|
@@ -607,17 +637,21 @@ export async function prepareExecutionPayload(
|
|
|
607
637
|
logger: Logger,
|
|
608
638
|
fork: ForkPostBellatrix,
|
|
609
639
|
parentBlockRoot: Root,
|
|
640
|
+
parentBlockHash: Bytes32,
|
|
610
641
|
safeBlockHash: RootHex,
|
|
611
642
|
finalizedBlockHash: RootHex,
|
|
643
|
+
/**
|
|
644
|
+
* Post-gloas, when extending a full parent, callers must apply
|
|
645
|
+
* parent execution payload first (see `withParentPayloadApplied`).
|
|
646
|
+
*/
|
|
612
647
|
state: IBeaconStateViewBellatrix,
|
|
613
648
|
suggestedFeeRecipient: string
|
|
614
649
|
): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
|
|
615
|
-
const parentHash = state.latestBlockHash;
|
|
616
650
|
const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
|
|
617
651
|
const prevRandao = state.getRandaoMix(state.epoch);
|
|
618
652
|
|
|
619
653
|
const payloadIdCached = chain.executionEngine.payloadIdCache.get({
|
|
620
|
-
headBlockHash: toRootHex(
|
|
654
|
+
headBlockHash: toRootHex(parentBlockHash),
|
|
621
655
|
finalizedBlockHash,
|
|
622
656
|
timestamp: numToQuantity(timestamp),
|
|
623
657
|
prevRandao: toHex(prevRandao),
|
|
@@ -646,12 +680,13 @@ export async function prepareExecutionPayload(
|
|
|
646
680
|
prepareState: state,
|
|
647
681
|
prepareSlot: state.slot,
|
|
648
682
|
parentBlockRoot,
|
|
683
|
+
parentBlockHash,
|
|
649
684
|
feeRecipient: suggestedFeeRecipient,
|
|
650
685
|
});
|
|
651
686
|
|
|
652
687
|
payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
|
|
653
688
|
fork,
|
|
654
|
-
toRootHex(
|
|
689
|
+
toRootHex(parentBlockHash),
|
|
655
690
|
safeBlockHash,
|
|
656
691
|
finalizedBlockHash,
|
|
657
692
|
attributes
|
|
@@ -703,20 +738,34 @@ export function getPayloadAttributesForSSE(
|
|
|
703
738
|
prepareState,
|
|
704
739
|
prepareSlot,
|
|
705
740
|
parentBlockRoot,
|
|
741
|
+
parentBlockHash,
|
|
706
742
|
feeRecipient,
|
|
707
|
-
}: {
|
|
743
|
+
}: {
|
|
744
|
+
/**
|
|
745
|
+
* Post-gloas, when extending a full parent, callers must apply
|
|
746
|
+
* parent execution payload first (see `withParentPayloadApplied`).
|
|
747
|
+
*/
|
|
748
|
+
prepareState: IBeaconStateViewBellatrix;
|
|
749
|
+
prepareSlot: Slot;
|
|
750
|
+
parentBlockRoot: Root;
|
|
751
|
+
parentBlockHash: Bytes32;
|
|
752
|
+
feeRecipient: string;
|
|
753
|
+
}
|
|
708
754
|
): SSEPayloadAttributes {
|
|
709
|
-
const parentHash = prepareState.latestBlockHash;
|
|
710
755
|
const payloadAttributes = preparePayloadAttributes(fork, chain, {
|
|
711
756
|
prepareState,
|
|
712
757
|
prepareSlot,
|
|
713
758
|
parentBlockRoot,
|
|
759
|
+
parentBlockHash,
|
|
714
760
|
feeRecipient,
|
|
715
761
|
});
|
|
716
762
|
|
|
717
763
|
let parentBlockNumber: number;
|
|
718
764
|
if (isForkPostGloas(fork)) {
|
|
719
|
-
const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
|
|
765
|
+
const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
|
|
766
|
+
toRootHex(parentBlockRoot),
|
|
767
|
+
toRootHex(parentBlockHash)
|
|
768
|
+
);
|
|
720
769
|
if (parentBlock?.executionPayloadBlockHash == null) {
|
|
721
770
|
throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
|
|
722
771
|
}
|
|
@@ -730,7 +779,7 @@ export function getPayloadAttributesForSSE(
|
|
|
730
779
|
proposalSlot: prepareSlot,
|
|
731
780
|
parentBlockNumber,
|
|
732
781
|
parentBlockRoot,
|
|
733
|
-
parentBlockHash
|
|
782
|
+
parentBlockHash,
|
|
734
783
|
payloadAttributes,
|
|
735
784
|
};
|
|
736
785
|
return ssePayloadAttributes;
|
|
@@ -745,11 +794,17 @@ function preparePayloadAttributes(
|
|
|
745
794
|
prepareState,
|
|
746
795
|
prepareSlot,
|
|
747
796
|
parentBlockRoot,
|
|
797
|
+
parentBlockHash,
|
|
748
798
|
feeRecipient,
|
|
749
799
|
}: {
|
|
800
|
+
/**
|
|
801
|
+
* Post-gloas, when extending a full parent, callers must apply
|
|
802
|
+
* parent execution payload first (see `withParentPayloadApplied`).
|
|
803
|
+
*/
|
|
750
804
|
prepareState: IBeaconStateViewBellatrix;
|
|
751
805
|
prepareSlot: Slot;
|
|
752
806
|
parentBlockRoot: Root;
|
|
807
|
+
parentBlockHash: Bytes32;
|
|
753
808
|
feeRecipient: string;
|
|
754
809
|
}
|
|
755
810
|
): SSEPayloadAttributes["payloadAttributes"] {
|
|
@@ -766,13 +821,24 @@ function preparePayloadAttributes(
|
|
|
766
821
|
throw new Error("Expected Capella state for withdrawals");
|
|
767
822
|
}
|
|
768
823
|
|
|
769
|
-
if (isStatePostGloas(prepareState)
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
824
|
+
if (isStatePostGloas(prepareState)) {
|
|
825
|
+
const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
|
|
826
|
+
if (isExtendingPayload) {
|
|
827
|
+
// applyParentExecutionPayload sets latestBlockHash = parentBid.blockHash, so a mismatch
|
|
828
|
+
// here means the caller did not apply parent payload to prepareState
|
|
829
|
+
if (!byteArrayEquals(prepareState.latestBlockHash, prepareState.latestExecutionPayloadBid.blockHash)) {
|
|
830
|
+
throw new Error("Expected state with parent execution payload applied for withdrawals");
|
|
831
|
+
}
|
|
832
|
+
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
833
|
+
prepareState.getExpectedWithdrawals().expectedWithdrawals;
|
|
834
|
+
} else {
|
|
835
|
+
// When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
|
|
836
|
+
// already deducted from CL balances but never credited on the EL (the envelope
|
|
837
|
+
// was not delivered). The next payload must carry those same withdrawals to
|
|
838
|
+
// restore CL/EL consistency, otherwise validators permanently lose that balance.
|
|
839
|
+
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
840
|
+
prepareState.payloadExpectedWithdrawals;
|
|
841
|
+
}
|
|
776
842
|
} else {
|
|
777
843
|
// withdrawals logic is now fork aware as it changes on electra fork post capella
|
|
778
844
|
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
@@ -784,6 +850,10 @@ function preparePayloadAttributes(
|
|
|
784
850
|
(payloadAttributes as deneb.SSEPayloadAttributes["payloadAttributes"]).parentBeaconBlockRoot = parentBlockRoot;
|
|
785
851
|
}
|
|
786
852
|
|
|
853
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
854
|
+
(payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
|
|
855
|
+
}
|
|
856
|
+
|
|
787
857
|
return payloadAttributes;
|
|
788
858
|
}
|
|
789
859
|
|
|
@@ -21,6 +21,7 @@ export enum RegenCaller {
|
|
|
21
21
|
validateGossipAttestation = "validateGossipAttestation",
|
|
22
22
|
validateGossipVoluntaryExit = "validateGossipVoluntaryExit",
|
|
23
23
|
validateGossipExecutionPayloadBid = "validateGossipExecutionPayloadBid",
|
|
24
|
+
validateGossipProposerPreferences = "validateGossipProposerPreferences",
|
|
24
25
|
onForkChoiceFinalized = "onForkChoiceFinalized",
|
|
25
26
|
restApi = "restApi",
|
|
26
27
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {IBeaconStateView, computeEpochAtSlot} from "@lodestar/state-transition";
|
|
4
|
-
import {BeaconBlock, Epoch, RootHex, Slot,
|
|
4
|
+
import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
5
5
|
import {Logger, toRootHex} from "@lodestar/utils";
|
|
6
6
|
import {Metrics} from "../../metrics/index.js";
|
|
7
7
|
import {JobItemQueue} from "../../util/queue/index.js";
|
|
@@ -88,12 +88,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
88
88
|
*/
|
|
89
89
|
getPreStateSync(block: BeaconBlock): IBeaconStateView | null {
|
|
90
90
|
const parentRoot = toRootHex(block.parentRoot);
|
|
91
|
-
const parentBlock =
|
|
92
|
-
? this.forkChoice.getBlockHexAndBlockHash(
|
|
93
|
-
parentRoot,
|
|
94
|
-
toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
|
|
95
|
-
)
|
|
96
|
-
: this.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
91
|
+
const parentBlock = this.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
97
92
|
if (!parentBlock) {
|
|
98
93
|
throw new RegenError({
|
|
99
94
|
code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
computeEpochAtSlot,
|
|
10
10
|
computeStartSlotAtEpoch,
|
|
11
11
|
} from "@lodestar/state-transition";
|
|
12
|
-
import {BeaconBlock, RootHex, SignedBeaconBlock, Slot
|
|
12
|
+
import {BeaconBlock, RootHex, SignedBeaconBlock, Slot} from "@lodestar/types";
|
|
13
13
|
import {Logger, fromHex, toRootHex} from "@lodestar/utils";
|
|
14
14
|
import {IBeaconDb} from "../../db/index.js";
|
|
15
15
|
import {Metrics} from "../../metrics/index.js";
|
|
@@ -57,12 +57,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
57
57
|
regenCaller: RegenCaller
|
|
58
58
|
): Promise<IBeaconStateView> {
|
|
59
59
|
const parentRoot = toRootHex(block.parentRoot);
|
|
60
|
-
const parentBlock =
|
|
61
|
-
? this.modules.forkChoice.getBlockHexAndBlockHash(
|
|
62
|
-
parentRoot,
|
|
63
|
-
toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
|
|
64
|
-
)
|
|
65
|
-
: this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
60
|
+
const parentBlock = this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
66
61
|
if (!parentBlock) {
|
|
67
62
|
throw new RegenError({
|
|
68
63
|
code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
|
|
@@ -5,3 +5,4 @@ export {SeenContributionAndProof} from "./seenCommitteeContribution.js";
|
|
|
5
5
|
export {SeenExecutionPayloadBids} from "./seenExecutionPayloadBids.js";
|
|
6
6
|
export {SeenBlockInput} from "./seenGossipBlockInput.js";
|
|
7
7
|
export {PayloadEnvelopeInput, SeenPayloadEnvelopeInput} from "./seenPayloadEnvelopeInput.js";
|
|
8
|
+
export {SeenProposerPreferences} from "./seenProposerPreferences.js";
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
2
3
|
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
3
4
|
import {RootHex} from "@lodestar/types";
|
|
4
5
|
import {Logger} from "@lodestar/utils";
|
|
5
6
|
import {Metrics} from "../../metrics/metrics.js";
|
|
7
|
+
import {IClock} from "../../util/clock.js";
|
|
6
8
|
import {SerializedCache} from "../../util/serializedCache.js";
|
|
9
|
+
import {isDaOutOfRange} from "../blocks/blockInput/index.js";
|
|
7
10
|
import {CreateFromBlockProps, PayloadEnvelopeInput} from "../blocks/payloadEnvelopeInput/index.js";
|
|
8
11
|
import {ChainEvent, ChainEventEmitter} from "../emitter.js";
|
|
9
12
|
|
|
@@ -11,6 +14,9 @@ export type {PayloadEnvelopeInputState} from "../blocks/payloadEnvelopeInput/ind
|
|
|
11
14
|
export {PayloadEnvelopeInput} from "../blocks/payloadEnvelopeInput/index.js";
|
|
12
15
|
|
|
13
16
|
export type SeenPayloadEnvelopeInputModules = {
|
|
17
|
+
config: ChainForkConfig;
|
|
18
|
+
clock: IClock;
|
|
19
|
+
forkChoice: IForkChoice;
|
|
14
20
|
chainEvents: ChainEventEmitter;
|
|
15
21
|
signal: AbortSignal;
|
|
16
22
|
serializedCache: SerializedCache;
|
|
@@ -21,10 +27,20 @@ export type SeenPayloadEnvelopeInputModules = {
|
|
|
21
27
|
/**
|
|
22
28
|
* Cache for tracking PayloadEnvelopeInput instances, keyed by beacon block root.
|
|
23
29
|
*
|
|
24
|
-
* Created during block import when a block is processed.
|
|
25
|
-
*
|
|
30
|
+
* Created during block import when a block is processed. Two pruning paths:
|
|
31
|
+
* - `prepareNextSlot` calls `pruneBelow(headParentSlot)` every slot once the head we'll build
|
|
32
|
+
* on is known.
|
|
33
|
+
* - `onFinalized` calls `pruneBelow(finalizedSlot)` on every finalization for bulk cleanup.
|
|
34
|
+
*
|
|
35
|
+
* Steady state (linear chain, healthy progression): the cache holds ~2 entries — the head
|
|
36
|
+
* (parent for next-slot production) and its parent (proposer-boost-reorg fallback). It can
|
|
37
|
+
* transiently hold more during forks, range-sync bursts, or when `prepareNextSlot` skips
|
|
38
|
+
* ticks; subsequent ticks settle it back.
|
|
26
39
|
*/
|
|
27
40
|
export class SeenPayloadEnvelopeInput {
|
|
41
|
+
private readonly config: ChainForkConfig;
|
|
42
|
+
private readonly clock: IClock;
|
|
43
|
+
private readonly forkChoice: IForkChoice;
|
|
28
44
|
private readonly chainEvents: ChainEventEmitter;
|
|
29
45
|
private readonly signal: AbortSignal;
|
|
30
46
|
private readonly serializedCache: SerializedCache;
|
|
@@ -32,7 +48,19 @@ export class SeenPayloadEnvelopeInput {
|
|
|
32
48
|
private readonly logger?: Logger;
|
|
33
49
|
private payloadInputs = new Map<RootHex, PayloadEnvelopeInput>();
|
|
34
50
|
|
|
35
|
-
constructor({
|
|
51
|
+
constructor({
|
|
52
|
+
config,
|
|
53
|
+
clock,
|
|
54
|
+
forkChoice,
|
|
55
|
+
chainEvents,
|
|
56
|
+
signal,
|
|
57
|
+
serializedCache,
|
|
58
|
+
metrics,
|
|
59
|
+
logger,
|
|
60
|
+
}: SeenPayloadEnvelopeInputModules) {
|
|
61
|
+
this.config = config;
|
|
62
|
+
this.clock = clock;
|
|
63
|
+
this.forkChoice = forkChoice;
|
|
36
64
|
this.chainEvents = chainEvents;
|
|
37
65
|
this.signal = signal;
|
|
38
66
|
this.serializedCache = serializedCache;
|
|
@@ -51,14 +79,13 @@ export class SeenPayloadEnvelopeInput {
|
|
|
51
79
|
});
|
|
52
80
|
}
|
|
53
81
|
|
|
54
|
-
this.chainEvents.on(ChainEvent.forkChoiceFinalized, this.
|
|
82
|
+
this.chainEvents.on(ChainEvent.forkChoiceFinalized, this.pruneFinalized);
|
|
55
83
|
this.signal.addEventListener("abort", () => {
|
|
56
|
-
this.chainEvents.off(ChainEvent.forkChoiceFinalized, this.
|
|
84
|
+
this.chainEvents.off(ChainEvent.forkChoiceFinalized, this.pruneFinalized);
|
|
57
85
|
});
|
|
58
86
|
}
|
|
59
87
|
|
|
60
|
-
private
|
|
61
|
-
// Prune all entries with slot < finalized slot
|
|
88
|
+
private pruneFinalized = (checkpoint: CheckpointWithHex): void => {
|
|
62
89
|
const finalizedSlot = computeStartSlotAtEpoch(checkpoint.epoch);
|
|
63
90
|
let deletedCount = 0;
|
|
64
91
|
for (const [, input] of this.payloadInputs) {
|
|
@@ -67,16 +94,32 @@ export class SeenPayloadEnvelopeInput {
|
|
|
67
94
|
deletedCount++;
|
|
68
95
|
}
|
|
69
96
|
}
|
|
70
|
-
|
|
97
|
+
|
|
98
|
+
this.logger?.debug("SeenPayloadEnvelopeInput.pruneFinalized deleted entries", {
|
|
99
|
+
finalizedSlot,
|
|
100
|
+
finalizedRoot: checkpoint.rootHex,
|
|
101
|
+
deletedCount,
|
|
102
|
+
});
|
|
71
103
|
};
|
|
72
104
|
|
|
73
|
-
add(props: CreateFromBlockProps): PayloadEnvelopeInput {
|
|
74
|
-
|
|
75
|
-
|
|
105
|
+
add(props: Omit<CreateFromBlockProps, "daOutOfRange">): PayloadEnvelopeInput {
|
|
106
|
+
const existing = this.payloadInputs.get(props.blockRootHex);
|
|
107
|
+
if (existing !== undefined) {
|
|
108
|
+
this.logger?.verbose("SeenPayloadEnvelopeInput.add reused existing entry", {
|
|
109
|
+
slot: existing.slot,
|
|
110
|
+
root: props.blockRootHex,
|
|
111
|
+
});
|
|
112
|
+
return existing;
|
|
76
113
|
}
|
|
77
|
-
const
|
|
114
|
+
const daOutOfRange = isDaOutOfRange(this.config, props.forkName, props.block.message.slot, this.clock.currentEpoch);
|
|
115
|
+
const input = PayloadEnvelopeInput.createFromBlock({...props, daOutOfRange});
|
|
78
116
|
this.payloadInputs.set(props.blockRootHex, input);
|
|
79
117
|
this.metrics?.seenCache.payloadEnvelopeInput.created.inc();
|
|
118
|
+
this.logger?.verbose("SeenPayloadEnvelopeInput.add created new entry", {
|
|
119
|
+
slot: input.slot,
|
|
120
|
+
root: props.blockRootHex,
|
|
121
|
+
daOutOfRange,
|
|
122
|
+
});
|
|
80
123
|
return input;
|
|
81
124
|
}
|
|
82
125
|
|
|
@@ -88,17 +131,25 @@ export class SeenPayloadEnvelopeInput {
|
|
|
88
131
|
return this.payloadInputs.get(blockRootHex)?.hasPayloadEnvelope() ?? false;
|
|
89
132
|
}
|
|
90
133
|
|
|
91
|
-
prune(blockRootHex: RootHex): void {
|
|
92
|
-
const payloadInput = this.payloadInputs.get(blockRootHex);
|
|
93
|
-
if (payloadInput) {
|
|
94
|
-
this.evictPayloadInput(payloadInput);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
134
|
size(): number {
|
|
99
135
|
return this.payloadInputs.size;
|
|
100
136
|
}
|
|
101
137
|
|
|
138
|
+
pruneBelowParent(parentBlock: ProtoBlock): void {
|
|
139
|
+
for (const block of this.forkChoice.getAllAncestorBlocks(parentBlock.blockRoot, parentBlock.payloadStatus)) {
|
|
140
|
+
if (block.slot < parentBlock.slot) {
|
|
141
|
+
const input = this.payloadInputs.get(block.blockRoot);
|
|
142
|
+
if (input) {
|
|
143
|
+
this.evictPayloadInput(input);
|
|
144
|
+
this.logger?.verbose("SeenPayloadEnvelopeInput.pruneBelowParent deleted", {
|
|
145
|
+
slot: block.slot,
|
|
146
|
+
root: block.blockRoot,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
102
153
|
private evictPayloadInput(payloadInput: PayloadEnvelopeInput): void {
|
|
103
154
|
this.serializedCache.delete(payloadInput.getSerializedCacheKeys());
|
|
104
155
|
this.payloadInputs.delete(payloadInput.blockRootHex);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {RootHex, Slot, ValidatorIndex} from "@lodestar/types";
|
|
2
|
+
import {MapDef} from "@lodestar/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tracks signed proposer preferences we've already seen per (dependent_root, proposal_slot, validator_index).
|
|
6
|
+
*/
|
|
7
|
+
export class SeenProposerPreferences {
|
|
8
|
+
private readonly validatorByDependentRootBySlot = new MapDef<Slot, Map<RootHex, ValidatorIndex>>(
|
|
9
|
+
() => new Map<RootHex, ValidatorIndex>()
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
isKnown(dependentRoot: RootHex, proposalSlot: Slot, validatorIndex: ValidatorIndex): boolean {
|
|
13
|
+
return this.validatorByDependentRootBySlot.get(proposalSlot)?.get(dependentRoot) === validatorIndex;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
add(dependentRoot: RootHex, proposalSlot: Slot, validatorIndex: ValidatorIndex): void {
|
|
17
|
+
this.validatorByDependentRootBySlot.getOrDefault(proposalSlot).set(dependentRoot, validatorIndex);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Entries are only load-bearing while `proposal_slot > current_slot`. Once the slot has
|
|
22
|
+
* passed the `[IGNORE] proposal_slot > current_slot` gossip rule takes over, so drop them
|
|
23
|
+
* on each slot tick.
|
|
24
|
+
*/
|
|
25
|
+
prune(currentSlot: Slot): void {
|
|
26
|
+
for (const slot of this.validatorByDependentRootBySlot.keys()) {
|
|
27
|
+
if (slot < currentSlot) {
|
|
28
|
+
this.validatorByDependentRootBySlot.delete(slot);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -226,7 +226,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
226
226
|
}
|
|
227
227
|
sszTimer?.();
|
|
228
228
|
const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
|
|
229
|
-
|
|
229
|
+
// preload validators and balances for faster state transition
|
|
230
|
+
const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes, {
|
|
231
|
+
preloadValidatorsAndBalances: true,
|
|
232
|
+
});
|
|
230
233
|
// hashTreeRoot() calls the commit() inside
|
|
231
234
|
// there is no modification inside the state, it's just that we want to compute and cache all roots
|
|
232
235
|
const stateRoot = toRootHex(newCachedState.hashTreeRoot());
|