@lodestar/beacon-node 1.42.0-dev.5f2fffc2ce → 1.42.0-dev.687ecdc8cd
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 +36 -17
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +1 -1
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/index.js +27 -32
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +4 -4
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js +7 -10
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +4 -6
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/proof/index.d.ts.map +1 -1
- package/lib/api/impl/proof/index.js +2 -6
- package/lib/api/impl/proof/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +27 -27
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/impl/validator/utils.d.ts +2 -2
- package/lib/api/impl/validator/utils.d.ts.map +1 -1
- package/lib/api/impl/validator/utils.js +3 -3
- package/lib/api/impl/validator/utils.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +3 -7
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +8 -26
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +1 -3
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +1 -0
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/balancesCache.d.ts +2 -2
- package/lib/chain/balancesCache.d.ts.map +1 -1
- package/lib/chain/balancesCache.js +4 -4
- package/lib/chain/balancesCache.js.map +1 -1
- package/lib/chain/blocks/blockInput/types.d.ts +4 -3
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/types.js +1 -0
- package/lib/chain/blocks/blockInput/types.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts +3 -3
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +39 -23
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +48 -0
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -0
- package/lib/chain/blocks/importExecutionPayload.js +167 -0
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -0
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +3 -2
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.js +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +80 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +248 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +29 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js +11 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +15 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +46 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -0
- package/lib/chain/blocks/types.d.ts +28 -15
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/types.js.map +1 -1
- package/lib/chain/blocks/utils/checkpoint.d.ts +2 -2
- package/lib/chain/blocks/utils/checkpoint.d.ts.map +1 -1
- package/lib/chain/blocks/utils/checkpoint.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +2 -2
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +4 -4
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +5 -5
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -4
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +3 -3
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +3 -3
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +12 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +40 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -0
- package/lib/chain/chain.d.ts +19 -14
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +75 -42
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +2 -2
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/errors/blockError.d.ts +4 -4
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +12 -2
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +3 -1
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts +4 -4
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +27 -33
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/initState.d.ts +2 -2
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +1 -1
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +17 -15
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/lightClient/index.d.ts +2 -2
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +4 -4
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts +6 -6
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +10 -13
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/opPool.d.ts +3 -3
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +7 -7
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +2 -2
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +2 -2
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/options.d.ts +1 -0
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -0
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts +2 -2
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +3 -3
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +4 -4
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +8 -4
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -5
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +13 -17
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +15 -13
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +2 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +14 -14
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +6 -5
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +6 -6
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -1
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -1
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +38 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +76 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -0
- package/lib/chain/serializeState.d.ts +2 -2
- package/lib/chain/serializeState.d.ts.map +1 -1
- package/lib/chain/serializeState.js +1 -1
- package/lib/chain/serializeState.js.map +1 -1
- package/lib/chain/shufflingCache.d.ts +2 -2
- package/lib/chain/shufflingCache.d.ts.map +1 -1
- package/lib/chain/shufflingCache.js +3 -4
- package/lib/chain/shufflingCache.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +6 -6
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +11 -11
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +12 -16
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +14 -14
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +3 -3
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/blobSidecar.js +1 -1
- package/lib/chain/validation/blobSidecar.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +3 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/blsToExecutionChange.js +2 -2
- package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +1 -1
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +4 -4
- 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 +29 -19
- package/lib/chain/validation/executionPayloadEnvelope.js.map +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/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +1 -2
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.js +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.js +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
- package/lib/chain/validation/syncCommittee.d.ts +4 -4
- package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/syncCommittee.js +13 -12
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +3 -3
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +5 -4
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +13 -8
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +2 -2
- package/lib/metrics/metrics/lodestar.d.ts +40 -4
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +93 -15
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +15 -0
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/interface.d.ts +4 -2
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +5 -0
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts +4 -2
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +11 -5
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
- package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
- package/lib/network/processor/extractSlotRootFns.js +15 -5
- package/lib/network/processor/extractSlotRootFns.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +39 -9
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +12 -7
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +99 -78
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +10 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +8 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +69 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +6 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +28 -0
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -0
- package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/index.js +11 -1
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/protocols.d.ts +2 -0
- package/lib/network/reqresp/protocols.d.ts.map +1 -1
- package/lib/network/reqresp/protocols.js +10 -0
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
- package/lib/network/reqresp/rateLimit.js +8 -0
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +2 -0
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/reqresp/types.d.ts +8 -2
- package/lib/network/reqresp/types.d.ts.map +1 -1
- package/lib/network/reqresp/types.js +7 -1
- package/lib/network/reqresp/types.js.map +1 -1
- package/lib/node/nodejs.d.ts +2 -2
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +1 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.d.ts.map +1 -1
- package/lib/node/notifier.js +3 -3
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/backfill/backfill.d.ts +3 -3
- package/lib/sync/backfill/backfill.d.ts.map +1 -1
- package/lib/sync/backfill/backfill.js +3 -3
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/constants.d.ts +1 -1
- package/lib/sync/constants.js +1 -1
- package/lib/sync/unknownBlock.d.ts +3 -9
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +8 -41
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/sszBytes.d.ts +4 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +69 -12
- package/lib/util/sszBytes.js.map +1 -1
- package/lib/util/types.d.ts +2 -0
- package/lib/util/types.d.ts.map +1 -1
- package/lib/util/types.js +1 -0
- package/lib/util/types.js.map +1 -1
- package/package.json +16 -16
- package/src/api/impl/beacon/blocks/index.ts +37 -18
- package/src/api/impl/beacon/pool/index.ts +1 -1
- package/src/api/impl/beacon/state/index.ts +29 -41
- package/src/api/impl/beacon/state/utils.ts +11 -25
- package/src/api/impl/lodestar/index.ts +4 -8
- package/src/api/impl/proof/index.ts +2 -9
- package/src/api/impl/validator/index.ts +29 -41
- package/src/api/impl/validator/utils.ts +4 -7
- package/src/chain/archiveStore/archiveStore.ts +1 -0
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -39
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +2 -1
- package/src/chain/archiveStore/historicalState/types.ts +2 -0
- package/src/chain/archiveStore/historicalState/worker.ts +1 -4
- package/src/chain/archiveStore/interface.ts +1 -0
- package/src/chain/balancesCache.ts +5 -11
- package/src/chain/blocks/blockInput/types.ts +4 -3
- package/src/chain/blocks/importBlock.ts +59 -27
- package/src/chain/blocks/importExecutionPayload.ts +247 -0
- package/src/chain/blocks/index.ts +3 -2
- package/src/chain/blocks/payloadEnvelopeInput/index.ts +2 -0
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +336 -0
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +33 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +61 -0
- package/src/chain/blocks/types.ts +34 -15
- package/src/chain/blocks/utils/checkpoint.ts +2 -2
- package/src/chain/blocks/verifyBlock.ts +5 -10
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -14
- package/src/chain/blocks/verifyBlocksSignatures.ts +3 -3
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -8
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +55 -0
- package/src/chain/chain.ts +112 -70
- package/src/chain/emitter.ts +2 -2
- package/src/chain/errors/blockError.ts +4 -4
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
- package/src/chain/forkChoice/index.ts +33 -52
- package/src/chain/initState.ts +7 -2
- package/src/chain/interface.ts +18 -16
- package/src/chain/lightClient/index.ts +9 -22
- package/src/chain/opPools/aggregatedAttestationPool.ts +15 -21
- package/src/chain/opPools/opPool.ts +13 -14
- package/src/chain/opPools/utils.ts +4 -4
- package/src/chain/options.ts +2 -0
- package/src/chain/prepareNextSlot.ts +6 -8
- package/src/chain/produceBlock/computeNewStateRoot.ts +11 -10
- package/src/chain/produceBlock/produceBlockBody.ts +23 -50
- package/src/chain/regen/interface.ts +15 -17
- package/src/chain/regen/queued.ts +16 -20
- package/src/chain/regen/regen.ts +16 -17
- package/src/chain/seenCache/index.ts +1 -1
- package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +106 -0
- package/src/chain/serializeState.ts +3 -3
- package/src/chain/shufflingCache.ts +5 -7
- package/src/chain/stateCache/fifoBlockStateCache.ts +7 -7
- package/src/chain/stateCache/persistentCheckpointsCache.ts +27 -42
- package/src/chain/stateCache/types.ts +14 -18
- package/src/chain/validation/attesterSlashing.ts +3 -3
- package/src/chain/validation/blobSidecar.ts +1 -1
- package/src/chain/validation/block.ts +2 -4
- package/src/chain/validation/blsToExecutionChange.ts +2 -2
- package/src/chain/validation/dataColumnSidecar.ts +1 -1
- package/src/chain/validation/executionPayloadBid.ts +3 -7
- package/src/chain/validation/executionPayloadEnvelope.ts +36 -29
- package/src/chain/validation/lightClientFinalityUpdate.ts +1 -1
- package/src/chain/validation/lightClientOptimisticUpdate.ts +1 -1
- package/src/chain/validation/payloadAttestationMessage.ts +2 -4
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -7
- package/src/chain/validation/signatureSets/syncCommittee.ts +2 -7
- package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -2
- package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -7
- package/src/chain/validation/syncCommittee.ts +21 -20
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -10
- package/src/chain/validation/voluntaryExit.ts +3 -8
- package/src/chain/validatorMonitor.ts +23 -12
- package/src/execution/engine/interface.ts +2 -2
- package/src/metrics/metrics/lodestar.ts +100 -19
- package/src/network/gossip/encoding.ts +16 -0
- package/src/network/interface.ts +15 -2
- package/src/network/libp2p/index.ts +5 -0
- package/src/network/network.ts +34 -6
- package/src/network/processor/extractSlotRootFns.ts +19 -6
- package/src/network/processor/gossipHandlers.ts +45 -8
- package/src/network/processor/index.ts +110 -89
- package/src/network/reqresp/ReqRespBeaconNode.ts +14 -1
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +94 -0
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +43 -0
- package/src/network/reqresp/handlers/index.ts +12 -0
- package/src/network/reqresp/protocols.ts +12 -0
- package/src/network/reqresp/rateLimit.ts +18 -0
- package/src/network/reqresp/score.ts +2 -0
- package/src/network/reqresp/types.ts +13 -0
- package/src/node/nodejs.ts +3 -5
- package/src/node/notifier.ts +4 -10
- package/src/sync/backfill/backfill.ts +4 -4
- package/src/sync/constants.ts +1 -1
- package/src/sync/unknownBlock.ts +10 -50
- package/src/util/sszBytes.ts +90 -10
- package/src/util/types.ts +6 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +0 -15
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +0 -1
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +0 -28
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +0 -1
- package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +0 -34
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {ForkName} from "@lodestar/params";
|
|
1
|
+
import {ForkName, isForkPostGloas} from "@lodestar/params";
|
|
2
2
|
import {SlotOptionalRoot, SlotRootHex} from "@lodestar/types";
|
|
3
3
|
import {
|
|
4
|
+
getBeaconBlockRootFromDataColumnSidecarSerialized,
|
|
5
|
+
getBeaconBlockRootFromExecutionPayloadEnvelopeSerialized,
|
|
4
6
|
getBlockRootFromBeaconAttestationSerialized,
|
|
5
7
|
getBlockRootFromSignedAggregateAndProofSerialized,
|
|
6
8
|
getSlotFromBeaconAttestationSerialized,
|
|
7
9
|
getSlotFromBlobSidecarSerialized,
|
|
8
10
|
getSlotFromDataColumnSidecarSerialized,
|
|
11
|
+
getSlotFromExecutionPayloadEnvelopeSerialized,
|
|
9
12
|
getSlotFromSignedAggregateAndProofSerialized,
|
|
10
13
|
getSlotFromSignedBeaconBlockSerialized,
|
|
11
14
|
} from "../../util/sszBytes.js";
|
|
@@ -14,7 +17,7 @@ import {ExtractSlotRootFns} from "./types.js";
|
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* Extract the slot and block root of a gossip message form serialized data.
|
|
17
|
-
*
|
|
20
|
+
* Not applicable for all topics.
|
|
18
21
|
*/
|
|
19
22
|
export function createExtractBlockSlotRootFns(): ExtractSlotRootFns {
|
|
20
23
|
return {
|
|
@@ -52,13 +55,23 @@ export function createExtractBlockSlotRootFns(): ExtractSlotRootFns {
|
|
|
52
55
|
}
|
|
53
56
|
return {slot};
|
|
54
57
|
},
|
|
55
|
-
[GossipType.data_column_sidecar]: (data: Uint8Array): SlotOptionalRoot | null => {
|
|
56
|
-
const slot = getSlotFromDataColumnSidecarSerialized(data);
|
|
57
|
-
|
|
58
|
+
[GossipType.data_column_sidecar]: (data: Uint8Array, fork: ForkName): SlotOptionalRoot | null => {
|
|
59
|
+
const slot = getSlotFromDataColumnSidecarSerialized(data, fork);
|
|
58
60
|
if (slot === null) {
|
|
59
61
|
return null;
|
|
60
62
|
}
|
|
61
|
-
|
|
63
|
+
|
|
64
|
+
const root = isForkPostGloas(fork) ? getBeaconBlockRootFromDataColumnSidecarSerialized(data) : null;
|
|
65
|
+
return root !== null ? {slot, root} : {slot};
|
|
66
|
+
},
|
|
67
|
+
[GossipType.execution_payload]: (data: Uint8Array): SlotRootHex | null => {
|
|
68
|
+
const slot = getSlotFromExecutionPayloadEnvelopeSerialized(data);
|
|
69
|
+
const root = getBeaconBlockRootFromExecutionPayloadEnvelopeSerialized(data);
|
|
70
|
+
|
|
71
|
+
if (slot === null || root === null) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return {slot, root};
|
|
62
75
|
},
|
|
63
76
|
};
|
|
64
77
|
}
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
IBlockInput,
|
|
31
31
|
isBlockInputColumns,
|
|
32
32
|
} from "../../chain/blocks/blockInput/index.js";
|
|
33
|
+
import {PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/index.js";
|
|
33
34
|
import {BlobSidecarValidation} from "../../chain/blocks/types.js";
|
|
34
35
|
import {ChainEvent} from "../../chain/emitter.js";
|
|
35
36
|
import {
|
|
@@ -42,6 +43,8 @@ import {
|
|
|
42
43
|
BlockGossipError,
|
|
43
44
|
DataColumnSidecarErrorCode,
|
|
44
45
|
DataColumnSidecarGossipError,
|
|
46
|
+
ExecutionPayloadEnvelopeError,
|
|
47
|
+
ExecutionPayloadEnvelopeErrorCode,
|
|
45
48
|
GossipAction,
|
|
46
49
|
GossipActionError,
|
|
47
50
|
SyncCommitteeError,
|
|
@@ -616,6 +619,13 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
616
619
|
});
|
|
617
620
|
});
|
|
618
621
|
}
|
|
622
|
+
|
|
623
|
+
// TODO GLOAS: In Gloas, also add column to PayloadEnvelopeInput and notify the payload processor:
|
|
624
|
+
// const payloadInput = chain.seenPayloadEnvelopeInput.get(blockRootHex);
|
|
625
|
+
// if (payloadInput) {
|
|
626
|
+
// payloadInput.addColumn({columnSidecar, source: BlockInputSource.gossip, seenTimestampSec, peerIdStr});
|
|
627
|
+
// chain.processExecutionPayload(payloadInput, {validSignature: true});
|
|
628
|
+
// }
|
|
619
629
|
},
|
|
620
630
|
|
|
621
631
|
[GossipType.beacon_aggregate_and_proof]: async ({
|
|
@@ -767,9 +777,9 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
767
777
|
const {serializedData} = gossipData;
|
|
768
778
|
const syncCommittee = sszDeserialize(topic, serializedData);
|
|
769
779
|
const {subnet} = topic;
|
|
770
|
-
let
|
|
780
|
+
let indicesInSubcommittee: number[] = [0];
|
|
771
781
|
try {
|
|
772
|
-
|
|
782
|
+
indicesInSubcommittee = (await validateGossipSyncCommittee(chain, syncCommittee, subnet)).indicesInSubcommittee;
|
|
773
783
|
} catch (e) {
|
|
774
784
|
if (e instanceof SyncCommitteeError && e.action === GossipAction.REJECT) {
|
|
775
785
|
chain.persistInvalidSszValue(ssz.altair.SyncCommitteeMessage, syncCommittee, "gossip_reject");
|
|
@@ -777,11 +787,12 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
777
787
|
throw e;
|
|
778
788
|
}
|
|
779
789
|
|
|
780
|
-
// Handler
|
|
781
|
-
|
|
790
|
+
// Handler — add for ALL positions this validator holds in the subcommittee
|
|
782
791
|
try {
|
|
783
|
-
const
|
|
784
|
-
|
|
792
|
+
for (const indexInSubcommittee of indicesInSubcommittee) {
|
|
793
|
+
const insertOutcome = chain.syncCommitteeMessagePool.add(subnet, syncCommittee, indexInSubcommittee);
|
|
794
|
+
metrics?.opPool.syncCommitteeMessagePoolInsertOutcome.inc({insertOutcome});
|
|
795
|
+
}
|
|
785
796
|
} catch (e) {
|
|
786
797
|
logger.debug("Error adding to syncCommittee pool", {subnet}, e as Error);
|
|
787
798
|
}
|
|
@@ -826,17 +837,43 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
826
837
|
[GossipType.execution_payload]: async ({
|
|
827
838
|
gossipData,
|
|
828
839
|
topic,
|
|
840
|
+
peerIdStr,
|
|
829
841
|
seenTimestampSec,
|
|
830
842
|
}: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
|
|
831
843
|
const {serializedData} = gossipData;
|
|
832
844
|
const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
|
|
845
|
+
// TODO GLOAS: handle BLOCK_ROOT_UNKNOWN error to trigger sync
|
|
833
846
|
await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
|
|
834
847
|
|
|
835
848
|
const slot = executionPayloadEnvelope.message.slot;
|
|
836
849
|
const delaySec = seenTimestampSec - computeTimeAtSlot(config, slot, chain.genesisTime);
|
|
837
850
|
metrics?.gossipExecutionPayloadEnvelope.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
|
|
851
|
+
chain.validatorMonitor?.registerExecutionPayloadEnvelope(OpSource.gossip, delaySec, executionPayloadEnvelope);
|
|
852
|
+
|
|
853
|
+
const blockRootHex = toRootHex(executionPayloadEnvelope.message.beaconBlockRoot);
|
|
854
|
+
const payloadInput = chain.seenPayloadEnvelopeInputCache.get(blockRootHex);
|
|
855
|
+
|
|
856
|
+
if (!payloadInput) {
|
|
857
|
+
// This shouldn't happen because beacon block should have been imported and thus payload input should have been created.
|
|
858
|
+
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
859
|
+
code: ExecutionPayloadEnvelopeErrorCode.PAYLOAD_ENVELOPE_INPUT_MISSING,
|
|
860
|
+
blockRoot: blockRootHex,
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
chain.serializedCache.set(executionPayloadEnvelope, serializedData);
|
|
865
|
+
|
|
866
|
+
payloadInput.addPayloadEnvelope({
|
|
867
|
+
envelope: executionPayloadEnvelope,
|
|
868
|
+
source: PayloadEnvelopeInputSource.gossip,
|
|
869
|
+
seenTimestampSec,
|
|
870
|
+
peerIdStr,
|
|
871
|
+
});
|
|
838
872
|
|
|
839
|
-
// TODO GLOAS:
|
|
873
|
+
// TODO GLOAS: Emit execution_payload_gossip event for gossip receipt.
|
|
874
|
+
chain.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
|
|
875
|
+
chain.logger.debug("Error processing execution payload from gossip", {slot, root: blockRootHex}, e as Error);
|
|
876
|
+
});
|
|
840
877
|
},
|
|
841
878
|
[GossipType.payload_attestation_message]: async ({
|
|
842
879
|
gossipData,
|
|
@@ -1007,7 +1044,7 @@ export async function validateGossipFnRetryUnknownRoot<T>(
|
|
|
1007
1044
|
if (unknownBlockRootRetries === 0) {
|
|
1008
1045
|
// Trigger unknown block root search here
|
|
1009
1046
|
const rootHex = toRootHex(blockRoot);
|
|
1010
|
-
network.
|
|
1047
|
+
network.searchUnknownBlock({slot, root: rootHex}, BlockInputSource.gossip);
|
|
1011
1048
|
}
|
|
1012
1049
|
|
|
1013
1050
|
if (unknownBlockRootRetries++ < MAX_UNKNOWN_BLOCK_ROOT_RETRIES) {
|
|
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {ForkSeq} from "@lodestar/params";
|
|
3
3
|
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
4
4
|
import {RootHex, Slot, SlotRootHex} from "@lodestar/types";
|
|
5
|
-
import {Logger, MapDef, mapValues,
|
|
5
|
+
import {Logger, MapDef, mapValues, sleep} from "@lodestar/utils";
|
|
6
6
|
import {BlockInputSource} from "../../chain/blocks/blockInput/types.js";
|
|
7
7
|
import {ChainEvent} from "../../chain/emitter.js";
|
|
8
8
|
import {GossipErrorCode} from "../../chain/errors/gossipValidation.js";
|
|
@@ -87,27 +87,27 @@ const executeGossipWorkOrder = Object.keys(executeGossipWorkOrderObj) as (keyof
|
|
|
87
87
|
// TODO: Arbitrary constant, check metrics
|
|
88
88
|
const MAX_JOBS_SUBMITTED_PER_TICK = 128;
|
|
89
89
|
|
|
90
|
-
// How many
|
|
90
|
+
// How many gossip messages we keep before new ones get dropped.
|
|
91
91
|
const MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS = 16_384;
|
|
92
92
|
|
|
93
|
-
// We don't want to process too many
|
|
94
|
-
// As seen on mainnet,
|
|
93
|
+
// We don't want to process too many gossip messages in a single tick
|
|
94
|
+
// As seen on mainnet, gossip messages concurrency metric ranges from 1000 to 2000
|
|
95
95
|
// so make this constant a little bit conservative
|
|
96
|
-
const
|
|
96
|
+
const MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK = 1024;
|
|
97
97
|
|
|
98
98
|
// Same motivation to JobItemQueue, we don't want to block the event loop
|
|
99
|
-
const
|
|
99
|
+
const AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS = 50;
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
* Reprocess reject reason for metrics
|
|
103
103
|
*/
|
|
104
104
|
export enum ReprocessRejectReason {
|
|
105
105
|
/**
|
|
106
|
-
* There are too many
|
|
106
|
+
* There are too many gossip messages that have unknown block root.
|
|
107
107
|
*/
|
|
108
108
|
reached_limit = "reached_limit",
|
|
109
109
|
/**
|
|
110
|
-
* The awaiting
|
|
110
|
+
* The awaiting gossip message is pruned per clock slot.
|
|
111
111
|
*/
|
|
112
112
|
expired = "expired",
|
|
113
113
|
}
|
|
@@ -137,7 +137,7 @@ export enum CannotAcceptWorkReason {
|
|
|
137
137
|
*
|
|
138
138
|
* ### PendingGossipsubMessage beacon_attestation example
|
|
139
139
|
*
|
|
140
|
-
* For
|
|
140
|
+
* For gossip messages, processing the message includes the steps:
|
|
141
141
|
* 1. Pre shuffling sync validation
|
|
142
142
|
* 2. Retrieve shuffling: async + goes into the regen queue and can be expensive
|
|
143
143
|
* 3. Pre sig validation sync validation
|
|
@@ -156,11 +156,10 @@ export class NetworkProcessor {
|
|
|
156
156
|
private readonly gossipQueues: ReturnType<typeof createGossipQueues>;
|
|
157
157
|
private readonly gossipTopicConcurrency: {[K in GossipType]: number};
|
|
158
158
|
private readonly extractBlockSlotRootFns = createExtractBlockSlotRootFns();
|
|
159
|
-
// we may not receive the block for Attestation and SignedAggregateAndProof messages, in that case PendingGossipsubMessage needs
|
|
159
|
+
// we may not receive the block for messages like Attestation and SignedAggregateAndProof messages, in that case PendingGossipsubMessage needs
|
|
160
160
|
// to be stored in this Map and reprocessed once the block comes
|
|
161
|
-
private readonly
|
|
162
|
-
private
|
|
163
|
-
private unknownRootsBySlot = new MapDef<Slot, Set<RootHex>>(() => new Set());
|
|
161
|
+
private readonly awaitingMessagesByBlockRoot: MapDef<RootHex, Set<PendingGossipsubMessage>>;
|
|
162
|
+
private unknownBlocksBySlot = new MapDef<Slot, Set<RootHex>>(() => new Set());
|
|
164
163
|
|
|
165
164
|
constructor(
|
|
166
165
|
modules: NetworkProcessorModules,
|
|
@@ -184,9 +183,7 @@ export class NetworkProcessor {
|
|
|
184
183
|
this.chain.emitter.on(routes.events.EventType.block, this.onBlockProcessed.bind(this));
|
|
185
184
|
this.chain.clock.on(ClockEvent.slot, this.onClockSlot.bind(this));
|
|
186
185
|
|
|
187
|
-
this.
|
|
188
|
-
() => new MapDef<RootHex, Set<PendingGossipsubMessage>>(() => new Set())
|
|
189
|
-
);
|
|
186
|
+
this.awaitingMessagesByBlockRoot = new MapDef<RootHex, Set<PendingGossipsubMessage>>(() => new Set());
|
|
190
187
|
|
|
191
188
|
// TODO: Implement queues and priorization for ReqResp incoming requests
|
|
192
189
|
// Listens to NetworkEvent.reqRespIncomingRequest event
|
|
@@ -198,7 +195,7 @@ export class NetworkProcessor {
|
|
|
198
195
|
metrics.gossipValidationQueue.keySize.set({topic}, this.gossipQueues[topic].keySize);
|
|
199
196
|
metrics.gossipValidationQueue.concurrency.set({topic}, this.gossipTopicConcurrency[topic]);
|
|
200
197
|
}
|
|
201
|
-
metrics.
|
|
198
|
+
metrics.awaitingBlockGossipMessages.countPerSlot.set(this.unknownBlockGossipsubMessagesCount);
|
|
202
199
|
// specific metric for beacon_attestation topic
|
|
203
200
|
metrics.gossipValidationQueue.keyAge.reset();
|
|
204
201
|
for (const ageMs of this.gossipQueues.beacon_attestation.getDataAgeMs()) {
|
|
@@ -233,64 +230,77 @@ export class NetworkProcessor {
|
|
|
233
230
|
return queue.getAll();
|
|
234
231
|
}
|
|
235
232
|
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Search block via `ChainEvent.unknownBlockRoot` event
|
|
235
|
+
* Note that slot is not necessarily the same to the block's slot but it can be used for a good prune strategy.
|
|
236
|
+
* In the rare case, if 2 messages on 2 slots search for the same root (for example beacon_attestation) we may emit the same root twice but BlockInputSync should handle it well.
|
|
237
|
+
*/
|
|
238
|
+
searchUnknownBlock({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
|
|
239
|
+
if (
|
|
240
|
+
this.chain.seenBlock(root) ||
|
|
241
|
+
this.awaitingMessagesByBlockRoot.has(root) ||
|
|
242
|
+
this.unknownBlocksBySlot.getOrDefault(slot).has(root)
|
|
243
|
+
) {
|
|
238
244
|
return;
|
|
239
245
|
}
|
|
240
246
|
// Search for the unknown block
|
|
241
|
-
this.
|
|
247
|
+
this.unknownBlocksBySlot.getOrDefault(slot).add(root);
|
|
242
248
|
this.chain.emitter.emit(ChainEvent.unknownBlockRoot, {rootHex: root, peer, source});
|
|
243
249
|
}
|
|
244
250
|
|
|
245
251
|
private onPendingGossipsubMessage(message: PendingGossipsubMessage): void {
|
|
246
252
|
const topicType = message.topic.type;
|
|
247
253
|
const extractBlockSlotRootFn = this.extractBlockSlotRootFns[topicType];
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
//
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const {fork} = message.topic.boundary;
|
|
258
|
-
let earliestPermissableSlot = clockSlot - DEFAULT_EARLIEST_PERMISSIBLE_SLOT_DISTANCE;
|
|
259
|
-
if (ForkSeq[fork] >= ForkSeq.deneb && topicType === GossipType.beacon_attestation) {
|
|
260
|
-
// post deneb, the attestations could be in current or previous epoch
|
|
261
|
-
earliestPermissableSlot = computeStartSlotAtEpoch(this.chain.clock.currentEpoch - 1);
|
|
262
|
-
}
|
|
263
|
-
if (slot < earliestPermissableSlot) {
|
|
264
|
-
// TODO: Should report the dropped job to gossip? It will be eventually pruned from the mcache
|
|
265
|
-
this.metrics?.networkProcessor.gossipValidationError.inc({
|
|
266
|
-
topic: topicType,
|
|
267
|
-
error: GossipErrorCode.PAST_SLOT,
|
|
268
|
-
});
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
message.msgSlot = slot;
|
|
272
|
-
// check if we processed a block with this root
|
|
273
|
-
// no need to check if root is a descendant of the current finalized block, it will be checked once we validate the message if needed
|
|
274
|
-
if (root && !this.chain.forkChoice.hasBlockHexUnsafe(root)) {
|
|
275
|
-
this.searchUnknownSlotRoot({slot, root}, BlockInputSource.gossip, message.propagationSource.toString());
|
|
276
|
-
|
|
277
|
-
if (this.unknownBlockGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
|
|
278
|
-
// TODO: Should report the dropped job to gossip? It will be eventually pruned from the mcache
|
|
279
|
-
this.metrics?.reprocessGossipAttestations.reject.inc({reason: ReprocessRejectReason.reached_limit});
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
254
|
+
const slotRoot = extractBlockSlotRootFn
|
|
255
|
+
? extractBlockSlotRootFn(message.msg.data, message.topic.boundary.fork)
|
|
256
|
+
: null;
|
|
257
|
+
if (slotRoot === null) {
|
|
258
|
+
// some messages don't have slot and root
|
|
259
|
+
// if the msg.data is invalid, message will be rejected when deserializing data in later phase (gossipValidatorFn)
|
|
260
|
+
this.pushPendingGossipsubMessageToQueue(message);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
282
263
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
264
|
+
// common check for all topics
|
|
265
|
+
// DOS protection: avoid processing messages that are too old
|
|
266
|
+
const {slot, root} = slotRoot;
|
|
267
|
+
const clockSlot = this.chain.clock.currentSlot;
|
|
268
|
+
const {fork} = message.topic.boundary;
|
|
269
|
+
let earliestPermissableSlot = clockSlot - DEFAULT_EARLIEST_PERMISSIBLE_SLOT_DISTANCE;
|
|
270
|
+
if (ForkSeq[fork] >= ForkSeq.deneb && topicType === GossipType.beacon_attestation) {
|
|
271
|
+
// post deneb, the attestations could be in current or previous epoch
|
|
272
|
+
earliestPermissableSlot = computeStartSlotAtEpoch(this.chain.clock.currentEpoch - 1);
|
|
273
|
+
}
|
|
274
|
+
if (slot < earliestPermissableSlot) {
|
|
275
|
+
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
276
|
+
this.metrics?.networkProcessor.gossipValidationError.inc({
|
|
277
|
+
topic: topicType,
|
|
278
|
+
error: GossipErrorCode.PAST_SLOT,
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
message.msgSlot = slot;
|
|
284
|
+
|
|
285
|
+
// no need to check if root is a descendant of the current finalized block, it will be checked once we validate the message if needed
|
|
286
|
+
if (root && !this.chain.forkChoice.hasBlockHexUnsafe(root)) {
|
|
287
|
+
this.searchUnknownBlock({slot, root}, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
288
|
+
|
|
289
|
+
if (this.unknownBlockGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
|
|
290
|
+
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
291
|
+
this.metrics?.awaitingBlockGossipMessages.reject.inc({
|
|
292
|
+
reason: ReprocessRejectReason.reached_limit,
|
|
293
|
+
topic: topicType,
|
|
294
|
+
});
|
|
295
|
+
return;
|
|
290
296
|
}
|
|
297
|
+
|
|
298
|
+
this.metrics?.awaitingBlockGossipMessages.queue.inc({topic: topicType});
|
|
299
|
+
const awaitingGossipsubMessages = this.awaitingMessagesByBlockRoot.getOrDefault(root);
|
|
300
|
+
awaitingGossipsubMessages.add(message);
|
|
301
|
+
return;
|
|
291
302
|
}
|
|
292
303
|
|
|
293
|
-
// bypass the check for other messages
|
|
294
304
|
this.pushPendingGossipsubMessageToQueue(message);
|
|
295
305
|
}
|
|
296
306
|
|
|
@@ -298,7 +308,7 @@ export class NetworkProcessor {
|
|
|
298
308
|
const topicType = message.topic.type;
|
|
299
309
|
const droppedCount = this.gossipQueues[topicType].add(message);
|
|
300
310
|
if (droppedCount) {
|
|
301
|
-
//
|
|
311
|
+
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
302
312
|
this.metrics?.gossipValidationQueue.droppedJobs.inc({topic: message.topic.type}, droppedCount);
|
|
303
313
|
}
|
|
304
314
|
|
|
@@ -306,58 +316,61 @@ export class NetworkProcessor {
|
|
|
306
316
|
this.executeWork();
|
|
307
317
|
}
|
|
308
318
|
|
|
309
|
-
private async onBlockProcessed({
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}: {
|
|
313
|
-
slot: Slot;
|
|
314
|
-
block: string;
|
|
315
|
-
executionOptimistic: boolean;
|
|
316
|
-
}): Promise<void> {
|
|
317
|
-
const byRootGossipsubMessages = this.awaitingGossipsubMessagesByRootBySlot.getOrDefault(slot);
|
|
318
|
-
const waitingGossipsubMessages = byRootGossipsubMessages.getOrDefault(rootHex);
|
|
319
|
-
if (waitingGossipsubMessages.size === 0) {
|
|
319
|
+
private async onBlockProcessed({block: rootHex}: {block: string; executionOptimistic: boolean}): Promise<void> {
|
|
320
|
+
const waitingGossipsubMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
|
|
321
|
+
if (!waitingGossipsubMessages || waitingGossipsubMessages.size === 0) {
|
|
320
322
|
return;
|
|
321
323
|
}
|
|
322
324
|
|
|
323
|
-
this.metrics?.reprocessGossipAttestations.resolve.inc(waitingGossipsubMessages.size);
|
|
324
325
|
const nowSec = Date.now() / 1000;
|
|
325
326
|
let count = 0;
|
|
326
327
|
// TODO: we can group attestations to process in batches but since we have the SeenAttestationDatas
|
|
327
328
|
// cache, it may not be necessary at this time
|
|
328
329
|
for (const message of waitingGossipsubMessages) {
|
|
329
|
-
|
|
330
|
+
const topicType = message.topic.type;
|
|
331
|
+
this.metrics?.awaitingBlockGossipMessages.waitSecBeforeResolve.set(
|
|
332
|
+
{topic: topicType},
|
|
333
|
+
nowSec - message.seenTimestampSec
|
|
334
|
+
);
|
|
335
|
+
this.metrics?.awaitingBlockGossipMessages.resolve.inc({topic: topicType});
|
|
330
336
|
this.pushPendingGossipsubMessageToQueue(message);
|
|
331
337
|
count++;
|
|
332
338
|
// don't want to block the event loop, worse case it'd wait for 16_084 / 1024 * 50ms = 800ms which is not a big deal
|
|
333
|
-
if (count ===
|
|
339
|
+
if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
|
|
334
340
|
count = 0;
|
|
335
|
-
await sleep(
|
|
341
|
+
await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
|
|
336
342
|
}
|
|
337
343
|
}
|
|
338
344
|
|
|
339
|
-
|
|
345
|
+
this.awaitingMessagesByBlockRoot.delete(rootHex);
|
|
340
346
|
}
|
|
341
347
|
|
|
342
348
|
private onClockSlot(clockSlot: Slot): void {
|
|
343
349
|
const nowSec = Date.now() / 1000;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
350
|
+
const minSlot = clockSlot - MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE;
|
|
351
|
+
|
|
352
|
+
for (const [slot, roots] of this.unknownBlocksBySlot) {
|
|
353
|
+
if (slot > minSlot) continue;
|
|
354
|
+
for (const rootHex of roots) {
|
|
355
|
+
const gossipMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
|
|
356
|
+
if (gossipMessages !== undefined) {
|
|
347
357
|
for (const message of gossipMessages) {
|
|
348
|
-
|
|
349
|
-
this.metrics?.
|
|
350
|
-
|
|
358
|
+
const topicType = message.topic.type;
|
|
359
|
+
this.metrics?.awaitingBlockGossipMessages.reject.inc({
|
|
360
|
+
topic: topicType,
|
|
361
|
+
reason: ReprocessRejectReason.expired,
|
|
362
|
+
});
|
|
363
|
+
this.metrics?.awaitingBlockGossipMessages.waitSecBeforeReject.set(
|
|
364
|
+
{topic: topicType, reason: ReprocessRejectReason.expired},
|
|
351
365
|
nowSec - message.seenTimestampSec
|
|
352
366
|
);
|
|
353
|
-
//
|
|
367
|
+
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
354
368
|
}
|
|
369
|
+
this.awaitingMessagesByBlockRoot.delete(rootHex);
|
|
355
370
|
}
|
|
356
|
-
this.awaitingGossipsubMessagesByRootBySlot.delete(slot);
|
|
357
371
|
}
|
|
372
|
+
this.unknownBlocksBySlot.delete(slot);
|
|
358
373
|
}
|
|
359
|
-
pruneSetToMax(this.unknownRootsBySlot, MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE);
|
|
360
|
-
this.unknownBlockGossipsubMessagesCount = 0;
|
|
361
374
|
}
|
|
362
375
|
|
|
363
376
|
private executeWork(): void {
|
|
@@ -496,4 +509,12 @@ export class NetworkProcessor {
|
|
|
496
509
|
|
|
497
510
|
return null;
|
|
498
511
|
}
|
|
512
|
+
|
|
513
|
+
private get unknownBlockGossipsubMessagesCount(): number {
|
|
514
|
+
let count = 0;
|
|
515
|
+
for (const messages of this.awaitingMessagesByBlockRoot.values()) {
|
|
516
|
+
count += messages.size;
|
|
517
|
+
}
|
|
518
|
+
return count;
|
|
519
|
+
}
|
|
499
520
|
}
|
|
@@ -58,7 +58,7 @@ export type ReqRespBeaconNodeOpts = ReqRespOpts & {disableLightClientServer?: bo
|
|
|
58
58
|
* Implementation of Ethereum Consensus p2p Req/Resp domain.
|
|
59
59
|
* For the spec that this code is based on, see:
|
|
60
60
|
* https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-reqresp-domain
|
|
61
|
-
* https://github.com/ethereum/consensus-specs/blob/
|
|
61
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.6.1/specs/altair/light-client/p2p-interface.md#the-reqresp-domain
|
|
62
62
|
*/
|
|
63
63
|
export class ReqRespBeaconNode extends ReqResp {
|
|
64
64
|
private readonly metadataController: MetadataController;
|
|
@@ -297,6 +297,19 @@ export class ReqRespBeaconNode extends ReqResp {
|
|
|
297
297
|
);
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
301
|
+
protocolsAtFork.push(
|
|
302
|
+
[
|
|
303
|
+
protocols.ExecutionPayloadEnvelopesByRoot(fork, this.config),
|
|
304
|
+
this.getHandler(ReqRespMethod.ExecutionPayloadEnvelopesByRoot),
|
|
305
|
+
],
|
|
306
|
+
[
|
|
307
|
+
protocols.ExecutionPayloadEnvelopesByRange(fork, this.config),
|
|
308
|
+
this.getHandler(ReqRespMethod.ExecutionPayloadEnvelopesByRange),
|
|
309
|
+
]
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
300
313
|
return protocolsAtFork;
|
|
301
314
|
}
|
|
302
315
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {ChainConfig} from "@lodestar/config";
|
|
2
|
+
import {PayloadStatus} from "@lodestar/fork-choice";
|
|
3
|
+
import {GENESIS_SLOT} from "@lodestar/params";
|
|
4
|
+
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
5
|
+
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
6
|
+
import {gloas} from "@lodestar/types";
|
|
7
|
+
import {IBeaconChain} from "../../../chain/index.js";
|
|
8
|
+
import {IBeaconDb} from "../../../db/index.js";
|
|
9
|
+
|
|
10
|
+
export async function* onExecutionPayloadEnvelopesByRange(
|
|
11
|
+
request: gloas.ExecutionPayloadEnvelopesByRangeRequest,
|
|
12
|
+
chain: IBeaconChain,
|
|
13
|
+
db: IBeaconDb
|
|
14
|
+
): AsyncIterable<ResponseOutgoing> {
|
|
15
|
+
const {startSlot, count} = validateExecutionPayloadEnvelopesByRangeRequest(chain.config, request);
|
|
16
|
+
const endSlot = startSlot + count;
|
|
17
|
+
|
|
18
|
+
if (startSlot < chain.earliestAvailableSlot) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const finalized = db.executionPayloadEnvelopeArchive;
|
|
23
|
+
const finalizedSlot = chain.forkChoice.getFinalizedCheckpointSlot();
|
|
24
|
+
|
|
25
|
+
// Finalized range of envelopes
|
|
26
|
+
if (startSlot <= finalizedSlot) {
|
|
27
|
+
for await (const {key, value: envelopeBytes} of finalized.binaryEntriesStream({
|
|
28
|
+
gte: startSlot,
|
|
29
|
+
lt: endSlot,
|
|
30
|
+
})) {
|
|
31
|
+
const slot = finalized.decodeKey(key);
|
|
32
|
+
yield {
|
|
33
|
+
data: envelopeBytes,
|
|
34
|
+
boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(slot)),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Non-finalized range of envelopes
|
|
40
|
+
if (endSlot > finalizedSlot) {
|
|
41
|
+
const headBlock = chain.forkChoice.getHead();
|
|
42
|
+
const headRoot = headBlock.blockRoot;
|
|
43
|
+
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
|
|
44
|
+
|
|
45
|
+
// Iterate head chain with ascending block numbers
|
|
46
|
+
for (let i = headChain.length - 1; i >= 0; i--) {
|
|
47
|
+
const block = headChain[i];
|
|
48
|
+
|
|
49
|
+
if (block.slot >= startSlot && block.slot < endSlot) {
|
|
50
|
+
// Skip EMPTY blocks
|
|
51
|
+
if (block.payloadStatus !== PayloadStatus.FULL) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const envelopeBytes = await chain.getSerializedExecutionPayloadEnvelope(block.slot, block.blockRoot);
|
|
56
|
+
if (!envelopeBytes) {
|
|
57
|
+
throw new ResponseError(
|
|
58
|
+
RespStatus.SERVER_ERROR,
|
|
59
|
+
`No envelope for root ${block.blockRoot} slot ${block.slot}, startSlot=${startSlot} endSlot=${endSlot} finalizedSlot=${finalizedSlot}`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
yield {
|
|
64
|
+
data: envelopeBytes,
|
|
65
|
+
boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(block.slot)),
|
|
66
|
+
};
|
|
67
|
+
} else if (block.slot >= endSlot) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function validateExecutionPayloadEnvelopesByRangeRequest(
|
|
75
|
+
config: ChainConfig,
|
|
76
|
+
request: gloas.ExecutionPayloadEnvelopesByRangeRequest
|
|
77
|
+
): gloas.ExecutionPayloadEnvelopesByRangeRequest {
|
|
78
|
+
const {startSlot} = request;
|
|
79
|
+
let {count} = request;
|
|
80
|
+
|
|
81
|
+
if (count < 1) {
|
|
82
|
+
throw new ResponseError(RespStatus.INVALID_REQUEST, "count < 1");
|
|
83
|
+
}
|
|
84
|
+
// TODO: validate against MIN_EPOCHS_FOR_BLOCK_REQUESTS
|
|
85
|
+
if (startSlot < GENESIS_SLOT) {
|
|
86
|
+
throw new ResponseError(RespStatus.INVALID_REQUEST, "startSlot < genesis");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (count > config.MAX_REQUEST_BLOCKS_DENEB) {
|
|
90
|
+
count = config.MAX_REQUEST_BLOCKS_DENEB;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {startSlot, count};
|
|
94
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {ResponseOutgoing} from "@lodestar/reqresp";
|
|
2
|
+
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
3
|
+
import {toRootHex} from "@lodestar/utils";
|
|
4
|
+
import {IBeaconChain} from "../../../chain/index.js";
|
|
5
|
+
import {IBeaconDb} from "../../../db/index.js";
|
|
6
|
+
import {ExecutionPayloadEnvelopesByRootRequest} from "../../../util/types.js";
|
|
7
|
+
|
|
8
|
+
export async function* onExecutionPayloadEnvelopesByRoot(
|
|
9
|
+
requestBody: ExecutionPayloadEnvelopesByRootRequest,
|
|
10
|
+
chain: IBeaconChain,
|
|
11
|
+
db: IBeaconDb
|
|
12
|
+
): AsyncIterable<ResponseOutgoing> {
|
|
13
|
+
// Spec: [max(GLOAS_FORK_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch]
|
|
14
|
+
const currentEpoch = chain.clock.currentEpoch;
|
|
15
|
+
const minimumRequestEpoch = Math.max(
|
|
16
|
+
currentEpoch - chain.config.MIN_EPOCHS_FOR_BLOCK_REQUESTS,
|
|
17
|
+
chain.config.GLOAS_FORK_EPOCH
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
for (const root of requestBody) {
|
|
21
|
+
const rootHex = toRootHex(root);
|
|
22
|
+
const block = chain.forkChoice.getBlockHexDefaultStatus(rootHex);
|
|
23
|
+
// If the block is not in fork choice, it may be finalized. Attempt to find its slot in block archive
|
|
24
|
+
const slot = block ? block.slot : await db.blockArchive.getSlotByRoot(root);
|
|
25
|
+
|
|
26
|
+
if (slot === null) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const requestedEpoch = computeEpochAtSlot(slot);
|
|
31
|
+
if (requestedEpoch < minimumRequestEpoch) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const envelopeBytes = await chain.getSerializedExecutionPayloadEnvelope(slot, rootHex);
|
|
36
|
+
if (envelopeBytes) {
|
|
37
|
+
yield {
|
|
38
|
+
data: envelopeBytes,
|
|
39
|
+
boundary: chain.config.getForkBoundaryAtEpoch(requestedEpoch),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|