@lodestar/beacon-node 1.40.0-dev.9e8478fc70 → 1.40.0-dev.ba49cac4ae
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 +15 -9
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +24 -0
- 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.map +1 -1
- package/lib/api/rest/base.d.ts.map +1 -1
- package/lib/api/rest/base.js +2 -2
- package/lib/api/rest/base.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +2 -0
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +7 -3
- package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +2 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +28 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +38 -3
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.js +1 -1
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -1
- package/lib/chain/blocks/verifyBlock.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 +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -2
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +8 -0
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +3 -1
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +5 -3
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +2 -2
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -2
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +4 -2
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +2 -2
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +9 -6
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -3
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +39 -34
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/attestationError.d.ts +14 -1
- package/lib/chain/errors/attestationError.d.ts.map +1 -1
- package/lib/chain/errors/attestationError.js +8 -0
- package/lib/chain/errors/attestationError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +48 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -0
- package/lib/chain/errors/executionPayloadBid.js +15 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +48 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.js +16 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -0
- package/lib/chain/errors/index.d.ts +3 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +3 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/errors/payloadAttestation.d.ts +34 -0
- package/lib/chain/errors/payloadAttestation.d.ts.map +1 -0
- package/lib/chain/errors/payloadAttestation.js +13 -0
- package/lib/chain/errors/payloadAttestation.js.map +1 -0
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +18 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +2 -2
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +7 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +1 -2
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.d.ts +21 -0
- package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -0
- package/lib/chain/opPools/executionPayloadBidPool.js +57 -0
- package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -0
- package/lib/chain/opPools/index.d.ts +2 -0
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js +2 -0
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts +24 -0
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -0
- package/lib/chain/opPools/payloadAttestationPool.js +109 -0
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -0
- package/lib/chain/options.d.ts +0 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +0 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +2 -1
- 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 +1 -1
- 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 +2 -0
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +4 -1
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +3 -1
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +3 -1
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenAttesters.d.ts +5 -0
- package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
- package/lib/chain/seenCache/seenAttesters.js +5 -0
- package/lib/chain/seenCache/seenAttesters.js.map +1 -1
- package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts +12 -0
- package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts.map +1 -0
- package/lib/chain/seenCache/seenExecutionPayloadBids.js +30 -0
- package/lib/chain/seenCache/seenExecutionPayloadBids.js.map +1 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +15 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +28 -0
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +1 -0
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +3 -3
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/stateCache/index.d.ts +0 -2
- package/lib/chain/stateCache/index.d.ts.map +1 -1
- package/lib/chain/stateCache/index.js +0 -2
- package/lib/chain/stateCache/index.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +2 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +3 -0
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +35 -14
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts +2 -2
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +27 -8
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
- package/lib/chain/validation/blobSidecar.js +4 -4
- 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 +6 -6
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +4 -4
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +5 -0
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -0
- package/lib/chain/validation/executionPayloadBid.js +104 -0
- package/lib/chain/validation/executionPayloadBid.js.map +1 -0
- package/lib/chain/validation/executionPayloadEnvelope.d.ts +5 -0
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/validation/executionPayloadEnvelope.js +89 -0
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -0
- package/lib/chain/validation/payloadAttestationMessage.d.ts +9 -0
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -0
- package/lib/chain/validation/payloadAttestationMessage.js +72 -0
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -0
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
- package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
- package/lib/chain/validation/signatureSets/aggregateAndProof.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 +3 -3
- package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
- package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
- package/lib/chain/validation/signatureSets/selectionProof.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 +3 -3
- package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
- 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 +3 -3
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
- package/lib/chain/validation/syncCommittee.js +1 -1
- 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 +3 -5
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +1 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +7 -4
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/db/repositories/checkpointState.js +0 -1
- package/lib/db/repositories/checkpointState.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +20 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +40 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/core/networkCore.d.ts +3 -0
- package/lib/network/core/networkCore.d.ts.map +1 -1
- package/lib/network/core/networkCore.js +9 -0
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorker.js +3 -0
- package/lib/network/core/networkCoreWorker.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -0
- package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js +9 -0
- package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
- package/lib/network/core/types.d.ts +3 -0
- package/lib/network/core/types.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts +34 -0
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +123 -0
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +20 -2
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +3 -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 +38 -2
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +77 -1
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +20 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/network.d.ts +3 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +9 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/options.d.ts +6 -0
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js.map +1 -1
- package/lib/network/peers/peerManager.d.ts.map +1 -1
- package/lib/network/peers/peerManager.js +9 -0
- package/lib/network/peers/peerManager.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +35 -1
- 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 +16 -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 +3 -0
- package/lib/network/processor/index.js.map +1 -1
- package/lib/sync/backfill/backfill.d.ts.map +1 -1
- package/lib/sync/backfill/backfill.js +3 -4
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts +1 -2
- package/lib/sync/backfill/verify.d.ts.map +1 -1
- package/lib/sync/backfill/verify.js +2 -2
- package/lib/sync/backfill/verify.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +2 -2
- 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 +1 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/package.json +16 -16
- package/src/api/impl/beacon/blocks/index.ts +31 -19
- package/src/api/impl/lodestar/index.ts +29 -0
- package/src/api/impl/validator/index.ts +2 -1
- package/src/api/rest/base.ts +4 -4
- package/src/chain/ColumnReconstructionTracker.ts +8 -4
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +2 -1
- package/src/chain/blocks/blockInput/blockInput.ts +47 -4
- package/src/chain/blocks/importBlock.ts +1 -1
- package/src/chain/blocks/verifyBlock.ts +0 -1
- package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -2
- package/src/chain/blocks/writeBlockInputToDb.ts +9 -0
- package/src/chain/bls/multithread/index.ts +7 -4
- package/src/chain/bls/multithread/jobItem.ts +7 -3
- package/src/chain/bls/singleThread.ts +5 -3
- package/src/chain/bls/utils.ts +15 -7
- package/src/chain/chain.ts +47 -36
- package/src/chain/errors/attestationError.ts +11 -1
- package/src/chain/errors/executionPayloadBid.ts +35 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +34 -0
- package/src/chain/errors/index.ts +3 -0
- package/src/chain/errors/payloadAttestation.ts +25 -0
- package/src/chain/forkChoice/index.ts +19 -0
- package/src/chain/initState.ts +2 -2
- package/src/chain/interface.ts +16 -1
- package/src/chain/lightClient/index.ts +1 -2
- package/src/chain/opPools/executionPayloadBidPool.ts +77 -0
- package/src/chain/opPools/index.ts +2 -0
- package/src/chain/opPools/payloadAttestationPool.ts +157 -0
- package/src/chain/options.ts +0 -2
- package/src/chain/regen/interface.ts +2 -1
- package/src/chain/regen/queued.ts +1 -2
- package/src/chain/regen/regen.ts +6 -1
- package/src/chain/seenCache/index.ts +3 -1
- package/src/chain/seenCache/seenAttesters.ts +5 -0
- package/src/chain/seenCache/seenExecutionPayloadBids.ts +35 -0
- package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +34 -0
- package/src/chain/seenCache/seenGossipBlockInput.ts +3 -3
- package/src/chain/stateCache/index.ts +0 -2
- package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
- package/src/chain/validation/aggregateAndProof.ts +36 -14
- package/src/chain/validation/attestation.ts +33 -16
- package/src/chain/validation/attesterSlashing.ts +1 -6
- package/src/chain/validation/blobSidecar.ts +3 -8
- package/src/chain/validation/block.ts +6 -6
- package/src/chain/validation/dataColumnSidecar.ts +3 -8
- package/src/chain/validation/executionPayloadBid.ts +141 -0
- package/src/chain/validation/executionPayloadEnvelope.ts +122 -0
- package/src/chain/validation/payloadAttestationMessage.ts +109 -0
- package/src/chain/validation/proposerSlashing.ts +1 -6
- package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
- package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
- package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
- package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
- package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
- package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
- package/src/chain/validation/syncCommittee.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
- package/src/chain/validation/voluntaryExit.ts +1 -1
- package/src/chain/validatorMonitor.ts +10 -5
- package/src/db/repositories/checkpointState.ts +1 -1
- package/src/metrics/metrics/lodestar.ts +40 -0
- package/src/network/core/networkCore.ts +12 -0
- package/src/network/core/networkCoreWorker.ts +3 -0
- package/src/network/core/networkCoreWorkerHandler.ts +9 -0
- package/src/network/core/types.ts +6 -0
- package/src/network/gossip/gossipsub.ts +147 -1
- package/src/network/gossip/interface.ts +17 -0
- package/src/network/gossip/scoringParameters.ts +44 -2
- package/src/network/gossip/topic.ts +21 -0
- package/src/network/network.ts +12 -0
- package/src/network/options.ts +6 -0
- package/src/network/peers/peerManager.ts +11 -0
- package/src/network/processor/gossipHandlers.ts +49 -1
- package/src/network/processor/gossipQueues/index.ts +16 -0
- package/src/network/processor/index.ts +3 -0
- package/src/sync/backfill/backfill.ts +3 -4
- package/src/sync/backfill/verify.ts +2 -3
- package/src/sync/utils/downloadByRange.ts +2 -2
- package/src/sync/utils/downloadByRoot.ts +1 -2
- package/lib/chain/stateCache/blockStateCacheImpl.d.ts +0 -54
- package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +0 -1
- package/lib/chain/stateCache/blockStateCacheImpl.js +0 -130
- package/lib/chain/stateCache/blockStateCacheImpl.js.map +0 -1
- package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +0 -60
- package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +0 -1
- package/lib/chain/stateCache/inMemoryCheckpointsCache.js +0 -156
- package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +0 -1
- package/lib/util/bytes.d.ts +0 -3
- package/lib/util/bytes.d.ts.map +0 -1
- package/lib/util/bytes.js +0 -11
- package/lib/util/bytes.js.map +0 -1
- package/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
- package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
- package/src/util/bytes.ts +0 -11
|
@@ -46,12 +46,11 @@ import {
|
|
|
46
46
|
ssz,
|
|
47
47
|
sszTypesFor,
|
|
48
48
|
} from "@lodestar/types";
|
|
49
|
-
import {Logger, MapDef, pruneSetToMax, toRootHex} from "@lodestar/utils";
|
|
49
|
+
import {Logger, MapDef, byteArrayEquals, pruneSetToMax, toRootHex} from "@lodestar/utils";
|
|
50
50
|
import {ZERO_HASH} from "../../constants/index.js";
|
|
51
51
|
import {IBeaconDb} from "../../db/index.js";
|
|
52
52
|
import {NUM_WITNESS, NUM_WITNESS_ELECTRA} from "../../db/repositories/lightclientSyncCommitteeWitness.js";
|
|
53
53
|
import {Metrics} from "../../metrics/index.js";
|
|
54
|
-
import {byteArrayEquals} from "../../util/bytes.js";
|
|
55
54
|
import {IClock} from "../../util/clock.js";
|
|
56
55
|
import {ChainEventEmitter} from "../emitter.js";
|
|
57
56
|
import {LightClientServerError, LightClientServerErrorCode} from "../errors/lightClientError.js";
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {Slot, gloas} from "@lodestar/types";
|
|
2
|
+
import {MapDef, toRootHex} from "@lodestar/utils";
|
|
3
|
+
import {InsertOutcome} from "./types.js";
|
|
4
|
+
import {pruneBySlot} from "./utils.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* TODO GLOAS: Revisit this value and add rational for choosing it
|
|
8
|
+
*/
|
|
9
|
+
const SLOTS_RETAINED = 2;
|
|
10
|
+
|
|
11
|
+
type BlockRootHex = string;
|
|
12
|
+
type BlockHashHex = string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Store the best execution payload bid per slot / (parent block root, parent block hash).
|
|
16
|
+
*/
|
|
17
|
+
export class ExecutionPayloadBidPool {
|
|
18
|
+
private readonly bidByParentHashByParentRootBySlot = new MapDef<
|
|
19
|
+
Slot,
|
|
20
|
+
MapDef<BlockRootHex, Map<BlockHashHex, gloas.ExecutionPayloadBid>>
|
|
21
|
+
>(() => new MapDef<BlockRootHex, Map<BlockHashHex, gloas.ExecutionPayloadBid>>(() => new Map()));
|
|
22
|
+
private lowestPermissibleSlot = 0;
|
|
23
|
+
|
|
24
|
+
get size(): number {
|
|
25
|
+
let count = 0;
|
|
26
|
+
for (const byParentRoot of this.bidByParentHashByParentRootBySlot.values()) {
|
|
27
|
+
for (const byParentHash of byParentRoot.values()) {
|
|
28
|
+
count += byParentHash.size;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return count;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
add(bid: gloas.ExecutionPayloadBid): InsertOutcome {
|
|
35
|
+
const {slot, parentBlockRoot, parentBlockHash, value} = bid;
|
|
36
|
+
const lowestPermissibleSlot = this.lowestPermissibleSlot;
|
|
37
|
+
|
|
38
|
+
if (slot < lowestPermissibleSlot) {
|
|
39
|
+
return InsertOutcome.Old;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const parentRootHex = toRootHex(parentBlockRoot);
|
|
43
|
+
const parentHashHex = toRootHex(parentBlockHash);
|
|
44
|
+
const bidByParentHash = this.bidByParentHashByParentRootBySlot.getOrDefault(slot).getOrDefault(parentRootHex);
|
|
45
|
+
const existing = bidByParentHash.get(parentHashHex);
|
|
46
|
+
|
|
47
|
+
if (existing) {
|
|
48
|
+
const existingValue = existing.value;
|
|
49
|
+
const newValue = value;
|
|
50
|
+
if (newValue > existingValue) {
|
|
51
|
+
bidByParentHash.set(parentHashHex, bid);
|
|
52
|
+
return InsertOutcome.NewData;
|
|
53
|
+
}
|
|
54
|
+
return newValue === existingValue ? InsertOutcome.AlreadyKnown : InsertOutcome.NotBetterThan;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
bidByParentHash.set(parentHashHex, bid);
|
|
58
|
+
return InsertOutcome.NewData;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Return the highest-value bid matching slot, parent block root, and parent block hash.
|
|
63
|
+
* Used for gossip validation and block production.
|
|
64
|
+
*/
|
|
65
|
+
getBestBid(
|
|
66
|
+
parentBlockRoot: BlockRootHex,
|
|
67
|
+
parentBlockHash: BlockHashHex,
|
|
68
|
+
slot: Slot
|
|
69
|
+
): gloas.ExecutionPayloadBid | null {
|
|
70
|
+
const bidByParentHash = this.bidByParentHashByParentRootBySlot.get(slot)?.get(parentBlockRoot);
|
|
71
|
+
return bidByParentHash?.get(parentBlockHash) ?? null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
prune(clockSlot: Slot): void {
|
|
75
|
+
this.lowestPermissibleSlot = pruneBySlot(this.bidByParentHashByParentRootBySlot, clockSlot, SLOTS_RETAINED);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export {AggregatedAttestationPool} from "./aggregatedAttestationPool.js";
|
|
2
2
|
export {AttestationPool} from "./attestationPool.js";
|
|
3
|
+
export {ExecutionPayloadBidPool} from "./executionPayloadBidPool.js";
|
|
3
4
|
export {OpPool} from "./opPool.js";
|
|
5
|
+
export {PayloadAttestationPool} from "./payloadAttestationPool.js";
|
|
4
6
|
export {SyncCommitteeMessagePool} from "./syncCommitteeMessagePool.js";
|
|
5
7
|
export {SyncContributionAndProofPool} from "./syncContributionAndProofPool.js";
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
2
|
+
import {BitArray} from "@chainsafe/ssz";
|
|
3
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
4
|
+
import {MAX_COMMITTEES_PER_SLOT, PTC_SIZE} from "@lodestar/params";
|
|
5
|
+
import {RootHex, Slot, gloas} from "@lodestar/types";
|
|
6
|
+
import {MapDef, toRootHex} from "@lodestar/utils";
|
|
7
|
+
import {Metrics} from "../../metrics/metrics.js";
|
|
8
|
+
import {IClock} from "../../util/clock.js";
|
|
9
|
+
import {InsertOutcome, OpPoolError, OpPoolErrorCode} from "./types.js";
|
|
10
|
+
import {pruneBySlot, signatureFromBytesNoCheck} from "./utils.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* TODO GLOAS: Revisit this value and add rational for choosing it
|
|
14
|
+
*/
|
|
15
|
+
const SLOTS_RETAINED = 2;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The maximum number of distinct `PayloadAttestationData` that will be stored in each slot.
|
|
19
|
+
*
|
|
20
|
+
* This is a DoS protection measure.
|
|
21
|
+
*/
|
|
22
|
+
// TODO GLOAS: Revisit this value. Educated guess would be MAX_ATTESTATIONS_PER_SLOT in AttestationPool divided by MAX_COMMITTEES_PER_SLOT
|
|
23
|
+
const MAX_PAYLOAD_ATTESTATIONS_PER_SLOT = 16_384 / MAX_COMMITTEES_PER_SLOT;
|
|
24
|
+
|
|
25
|
+
type DataRootHex = string;
|
|
26
|
+
type BlockRootHex = string;
|
|
27
|
+
|
|
28
|
+
type AggregateFast = {
|
|
29
|
+
aggregationBits: BitArray;
|
|
30
|
+
data: gloas.PayloadAttestationData;
|
|
31
|
+
signature: Signature;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export class PayloadAttestationPool {
|
|
35
|
+
private readonly aggregateByDataRootByBlockRootBySlot = new MapDef<
|
|
36
|
+
Slot,
|
|
37
|
+
Map<BlockRootHex, Map<DataRootHex, AggregateFast>>
|
|
38
|
+
>(() => new Map<BlockRootHex, Map<DataRootHex, AggregateFast>>());
|
|
39
|
+
private lowestPermissibleSlot = 0;
|
|
40
|
+
|
|
41
|
+
constructor(
|
|
42
|
+
private readonly config: ChainForkConfig,
|
|
43
|
+
private readonly clock: IClock,
|
|
44
|
+
private readonly metrics: Metrics | null = null
|
|
45
|
+
) {}
|
|
46
|
+
|
|
47
|
+
get size(): number {
|
|
48
|
+
let count = 0;
|
|
49
|
+
for (const aggregateByDataRootByBlockRoot of this.aggregateByDataRootByBlockRootBySlot.values()) {
|
|
50
|
+
for (const aggregateByDataRoot of aggregateByDataRootByBlockRoot.values()) {
|
|
51
|
+
count += aggregateByDataRoot.size;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return count;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
add(
|
|
58
|
+
message: gloas.PayloadAttestationMessage,
|
|
59
|
+
payloadAttDataRootHex: RootHex,
|
|
60
|
+
validatorCommitteeIndex: number
|
|
61
|
+
): InsertOutcome {
|
|
62
|
+
const slot = message.data.slot;
|
|
63
|
+
const lowestPermissibleSlot = this.lowestPermissibleSlot;
|
|
64
|
+
|
|
65
|
+
if (slot < lowestPermissibleSlot) {
|
|
66
|
+
return InsertOutcome.Old;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (slot < this.clock.slotWithPastTolerance(this.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000)) {
|
|
70
|
+
return InsertOutcome.Late;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.getOrDefault(slot);
|
|
74
|
+
let aggregateByDataRoot = aggregateByDataRootByBlockRoot.get(toRootHex(message.data.beaconBlockRoot));
|
|
75
|
+
|
|
76
|
+
if (!aggregateByDataRoot) {
|
|
77
|
+
aggregateByDataRoot = new Map<DataRootHex, AggregateFast>();
|
|
78
|
+
aggregateByDataRootByBlockRoot.set(toRootHex(message.data.beaconBlockRoot), aggregateByDataRoot);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (aggregateByDataRoot.size >= MAX_PAYLOAD_ATTESTATIONS_PER_SLOT) {
|
|
82
|
+
throw new OpPoolError({code: OpPoolErrorCode.REACHED_MAX_PER_SLOT});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const aggregate = aggregateByDataRoot.get(payloadAttDataRootHex);
|
|
86
|
+
if (aggregate) {
|
|
87
|
+
// Aggregate msg into aggregate
|
|
88
|
+
return aggregateMessageInto(message, validatorCommitteeIndex, aggregate);
|
|
89
|
+
}
|
|
90
|
+
// Create a new aggregate with data
|
|
91
|
+
aggregateByDataRoot.set(payloadAttDataRootHex, messageToAggregate(message, validatorCommitteeIndex));
|
|
92
|
+
|
|
93
|
+
return InsertOutcome.NewData;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get payload attestations to be included in a block.
|
|
98
|
+
* Pick the top `maxAttestation` number of attestations with the most votes
|
|
99
|
+
*/
|
|
100
|
+
getPayloadAttestationsForBlock(
|
|
101
|
+
beaconBlockRoot: BlockRootHex,
|
|
102
|
+
slot: Slot,
|
|
103
|
+
maxAttestation: number
|
|
104
|
+
): gloas.PayloadAttestation[] {
|
|
105
|
+
const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.get(slot);
|
|
106
|
+
|
|
107
|
+
if (!aggregateByDataRootByBlockRoot) {
|
|
108
|
+
this.metrics?.opPool.payloadAttestationPool.getPayloadAttestationsCacheMisses.inc();
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const aggregateByDataRoot = aggregateByDataRootByBlockRoot.get(beaconBlockRoot);
|
|
113
|
+
|
|
114
|
+
if (!aggregateByDataRoot) {
|
|
115
|
+
this.metrics?.opPool.payloadAttestationPool.getPayloadAttestationsCacheMisses.inc();
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return Array.from(aggregateByDataRoot.values())
|
|
120
|
+
.slice()
|
|
121
|
+
.sort((a, b) => b.aggregationBits.getTrueBitIndexes().length - a.aggregationBits.getTrueBitIndexes().length)
|
|
122
|
+
.slice(0, maxAttestation)
|
|
123
|
+
.map(fastToPayloadAttestation);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
prune(clockSlot: Slot): void {
|
|
127
|
+
pruneBySlot(this.aggregateByDataRootByBlockRootBySlot, clockSlot, SLOTS_RETAINED);
|
|
128
|
+
this.lowestPermissibleSlot = clockSlot;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function messageToAggregate(message: gloas.PayloadAttestationMessage, validatorCommitteeIndex: number): AggregateFast {
|
|
133
|
+
return {
|
|
134
|
+
aggregationBits: BitArray.fromSingleBit(PTC_SIZE, validatorCommitteeIndex),
|
|
135
|
+
data: message.data,
|
|
136
|
+
signature: signatureFromBytesNoCheck(message.signature),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function aggregateMessageInto(
|
|
141
|
+
message: gloas.PayloadAttestationMessage,
|
|
142
|
+
validatorCommitteeIndex: number,
|
|
143
|
+
aggregate: AggregateFast
|
|
144
|
+
): InsertOutcome {
|
|
145
|
+
if (aggregate.aggregationBits.get(validatorCommitteeIndex) === true) {
|
|
146
|
+
return InsertOutcome.AlreadyKnown;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
aggregate.aggregationBits.set(validatorCommitteeIndex, true);
|
|
150
|
+
aggregate.signature = aggregateSignatures([aggregate.signature, signatureFromBytesNoCheck(message.signature)]);
|
|
151
|
+
|
|
152
|
+
return InsertOutcome.Aggregated;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function fastToPayloadAttestation(aggFast: AggregateFast): gloas.PayloadAttestation {
|
|
156
|
+
return {...aggFast, signature: aggFast.signature.toBytes()};
|
|
157
|
+
}
|
package/src/chain/options.ts
CHANGED
|
@@ -45,7 +45,6 @@ export type IChainOptions = BlockProcessOpts &
|
|
|
45
45
|
broadcastValidationStrictness?: string;
|
|
46
46
|
minSameMessageSignatureSetsToBatch: number;
|
|
47
47
|
archiveDateEpochs?: number;
|
|
48
|
-
nHistoricalStates?: boolean;
|
|
49
48
|
nHistoricalStatesFileDataStore?: boolean;
|
|
50
49
|
};
|
|
51
50
|
|
|
@@ -119,7 +118,6 @@ export const defaultChainOptions: IChainOptions = {
|
|
|
119
118
|
// batching too much may block the I/O thread so if useWorker=false, suggest this value to be 32
|
|
120
119
|
// since this batch attestation work is designed to work with useWorker=true, make this the lowest value
|
|
121
120
|
minSameMessageSignatureSetsToBatch: 2,
|
|
122
|
-
nHistoricalStates: true,
|
|
123
121
|
// as of Feb 2025, this option turned out to be very useful:
|
|
124
122
|
// - it allows to share a persisted checkpoint state to other nodes
|
|
125
123
|
// - users can prune the persisted checkpoint state files manually to save disc space
|
|
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
|
|
4
4
|
import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
5
|
-
import {CheckpointHex} from "../stateCache/
|
|
5
|
+
import {CheckpointHex} from "../stateCache/types.js";
|
|
6
6
|
|
|
7
7
|
export enum RegenCaller {
|
|
8
8
|
getDuties = "getDuties",
|
|
@@ -18,6 +18,7 @@ export enum RegenCaller {
|
|
|
18
18
|
validateGossipAggregateAndProof = "validateGossipAggregateAndProof",
|
|
19
19
|
validateGossipAttestation = "validateGossipAttestation",
|
|
20
20
|
validateGossipVoluntaryExit = "validateGossipVoluntaryExit",
|
|
21
|
+
validateGossipExecutionPayloadBid = "validateGossipExecutionPayloadBid",
|
|
21
22
|
onForkChoiceFinalized = "onForkChoiceFinalized",
|
|
22
23
|
restApi = "restApi",
|
|
23
24
|
}
|
|
@@ -5,8 +5,7 @@ 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";
|
|
8
|
-
import {CheckpointHex} from "../stateCache/
|
|
9
|
-
import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
|
|
8
|
+
import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
|
|
10
9
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
11
10
|
import {
|
|
12
11
|
IStateRegenerator,
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {Metrics} from "../../metrics/index.js";
|
|
|
18
18
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
19
19
|
import {getCheckpointFromState} from "../blocks/utils/checkpoint.js";
|
|
20
20
|
import {ChainEvent, ChainEventEmitter} from "../emitter.js";
|
|
21
|
+
import {SeenBlockInput} from "../seenCache/seenGossipBlockInput.js";
|
|
21
22
|
import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
|
|
22
23
|
import {ValidatorMonitor} from "../validatorMonitor.js";
|
|
23
24
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
@@ -28,6 +29,7 @@ export type RegenModules = {
|
|
|
28
29
|
forkChoice: IForkChoice;
|
|
29
30
|
blockStateCache: BlockStateCache;
|
|
30
31
|
checkpointStateCache: CheckpointStateCache;
|
|
32
|
+
seenBlockInputCache: SeenBlockInput;
|
|
31
33
|
config: ChainForkConfig;
|
|
32
34
|
emitter: ChainEventEmitter;
|
|
33
35
|
logger: Logger;
|
|
@@ -191,7 +193,10 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
191
193
|
const protoBlocksAsc = blocksToReplay.reverse();
|
|
192
194
|
for (const [i, protoBlock] of protoBlocksAsc.entries()) {
|
|
193
195
|
replaySlots[i] = protoBlock.slot;
|
|
194
|
-
|
|
196
|
+
const blockInput = this.modules.seenBlockInputCache.get(protoBlock.blockRoot);
|
|
197
|
+
blockPromises[i] = blockInput?.hasBlock()
|
|
198
|
+
? Promise.resolve(blockInput.getBlock())
|
|
199
|
+
: this.modules.db.block.get(fromHex(protoBlock.blockRoot));
|
|
195
200
|
}
|
|
196
201
|
|
|
197
202
|
const logCtx = {stateRoot, caller, replaySlots: replaySlots.join(",")};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export {SeenAggregators, SeenAttesters} from "./seenAttesters.js";
|
|
1
|
+
export {SeenAggregators, SeenAttesters, SeenPayloadAttesters} from "./seenAttesters.js";
|
|
2
2
|
export {SeenBlockProposers} from "./seenBlockProposers.js";
|
|
3
3
|
export {SeenSyncCommitteeMessages} from "./seenCommittee.js";
|
|
4
4
|
export {SeenContributionAndProof} from "./seenCommitteeContribution.js";
|
|
5
|
+
export {SeenExecutionPayloadBids} from "./seenExecutionPayloadBids.js";
|
|
6
|
+
export {SeenExecutionPayloadEnvelopes} from "./seenExecutionPayloadEnvelope.js";
|
|
5
7
|
export {SeenBlockInput} from "./seenGossipBlockInput.js";
|
|
@@ -56,3 +56,8 @@ export class SeenAttesters {
|
|
|
56
56
|
* Keeps a cache to filter aggregated attestations from the same aggregators in the same epoch
|
|
57
57
|
*/
|
|
58
58
|
export class SeenAggregators extends SeenAttesters {}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Keeps a cache to filter payload attestations from the same attesters in the same epoch
|
|
62
|
+
*/
|
|
63
|
+
export class SeenPayloadAttesters extends SeenAttesters {}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {BuilderIndex, Slot} from "@lodestar/types";
|
|
2
|
+
import {MapDef} from "@lodestar/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* TODO GLOAS: Revisit this value and add rational for choosing it
|
|
6
|
+
*/
|
|
7
|
+
const SLOTS_RETAINED = 2;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tracks execution payload bids we've already seen per (slot, builder).
|
|
11
|
+
*/
|
|
12
|
+
export class SeenExecutionPayloadBids {
|
|
13
|
+
private readonly builderIndexesBySlot = new MapDef<Slot, Set<BuilderIndex>>(() => new Set<BuilderIndex>());
|
|
14
|
+
private lowestPermissibleSlot: Slot = 0;
|
|
15
|
+
|
|
16
|
+
isKnown(slot: Slot, builderIndex: BuilderIndex): boolean {
|
|
17
|
+
return this.builderIndexesBySlot.get(slot)?.has(builderIndex) === true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
add(slot: Slot, builderIndex: BuilderIndex): void {
|
|
21
|
+
if (slot < this.lowestPermissibleSlot) {
|
|
22
|
+
throw Error(`slot ${slot} < lowestPermissibleSlot ${this.lowestPermissibleSlot}`);
|
|
23
|
+
}
|
|
24
|
+
this.builderIndexesBySlot.getOrDefault(slot).add(builderIndex);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
prune(currentSlot: Slot): void {
|
|
28
|
+
this.lowestPermissibleSlot = Math.max(currentSlot - SLOTS_RETAINED, 0);
|
|
29
|
+
for (const slot of this.builderIndexesBySlot.keys()) {
|
|
30
|
+
if (slot < this.lowestPermissibleSlot) {
|
|
31
|
+
this.builderIndexesBySlot.delete(slot);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {RootHex, Slot} from "@lodestar/types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cache to prevent processing multiple execution payload envelopes for the same block root.
|
|
5
|
+
* Only one builder qualifies to submit an execution payload for a given slot.
|
|
6
|
+
* We only keep track of envelopes of unfinalized slots.
|
|
7
|
+
* [IGNORE] The node has not seen another valid `SignedExecutionPayloadEnvelope` for this block root.
|
|
8
|
+
*/
|
|
9
|
+
export class SeenExecutionPayloadEnvelopes {
|
|
10
|
+
private readonly slotByBlockRoot = new Map<RootHex, Slot>();
|
|
11
|
+
private finalizedSlot: Slot = 0;
|
|
12
|
+
|
|
13
|
+
isKnown(blockRoot: RootHex): boolean {
|
|
14
|
+
return this.slotByBlockRoot.has(blockRoot);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
add(blockRoot: RootHex, slot: Slot): void {
|
|
18
|
+
if (slot < this.finalizedSlot) {
|
|
19
|
+
throw Error(`slot ${slot} < finalizedSlot ${this.finalizedSlot}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.slotByBlockRoot.set(blockRoot, slot);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
prune(finalizedSlot: Slot): void {
|
|
26
|
+
this.finalizedSlot = finalizedSlot;
|
|
27
|
+
|
|
28
|
+
for (const [blockRoot, slot] of this.slotByBlockRoot.entries()) {
|
|
29
|
+
if (slot < finalizedSlot) {
|
|
30
|
+
this.slotByBlockRoot.delete(blockRoot);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -3,7 +3,7 @@ import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
|
3
3
|
import {ForkName, ForkPostFulu, ForkPreGloas, isForkPostDeneb, isForkPostFulu, isForkPostGloas} from "@lodestar/params";
|
|
4
4
|
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
5
5
|
import {BLSSignature, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
6
|
-
import {LodestarError, Logger, pruneSetToMax} from "@lodestar/utils";
|
|
6
|
+
import {LodestarError, Logger, byteArrayEquals, pruneSetToMax} from "@lodestar/utils";
|
|
7
7
|
import {Metrics} from "../../metrics/metrics.js";
|
|
8
8
|
import {IClock} from "../../util/clock.js";
|
|
9
9
|
import {CustodyConfig} from "../../util/dataColumns.js";
|
|
@@ -344,7 +344,7 @@ export class SeenBlockInput {
|
|
|
344
344
|
return false;
|
|
345
345
|
}
|
|
346
346
|
// Only consider verified if the signature matches
|
|
347
|
-
return
|
|
347
|
+
return byteArrayEquals(cachedSignature, signature);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
/**
|
|
@@ -379,7 +379,7 @@ export class SeenBlockInput {
|
|
|
379
379
|
let itemsToDelete = this.blockInputs.size - MAX_BLOCK_INPUT_CACHE_SIZE;
|
|
380
380
|
|
|
381
381
|
if (itemsToDelete > 0) {
|
|
382
|
-
const sorted = [...this.blockInputs.entries()].sort((a, b) =>
|
|
382
|
+
const sorted = [...this.blockInputs.entries()].sort((a, b) => a[1].slot - b[1].slot);
|
|
383
383
|
for (const [rootHex] of sorted) {
|
|
384
384
|
this.blockInputs.delete(rootHex);
|
|
385
385
|
itemsToDelete--;
|
|
@@ -31,7 +31,7 @@ type PersistentCheckpointStateCacheModules = {
|
|
|
31
31
|
signal?: AbortSignal;
|
|
32
32
|
datastore: CPStateDatastore;
|
|
33
33
|
blockStateCache: BlockStateCache;
|
|
34
|
-
bufferPool?: BufferPool
|
|
34
|
+
bufferPool?: BufferPool;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
/** checkpoint serialized as a string */
|
|
@@ -119,7 +119,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
119
119
|
private readonly maxEpochsOnDisk: number;
|
|
120
120
|
private readonly datastore: CPStateDatastore;
|
|
121
121
|
private readonly blockStateCache: BlockStateCache;
|
|
122
|
-
private readonly bufferPool?: BufferPool
|
|
122
|
+
private readonly bufferPool?: BufferPool;
|
|
123
123
|
|
|
124
124
|
constructor(
|
|
125
125
|
{
|
|
@@ -851,6 +851,10 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
|
|
|
851
851
|
};
|
|
852
852
|
}
|
|
853
853
|
|
|
854
|
+
export function toCheckpointKey(cp: CheckpointHex): string {
|
|
855
|
+
return `${cp.rootHex}:${cp.epoch}`;
|
|
856
|
+
}
|
|
857
|
+
|
|
854
858
|
function toCacheKey(cp: CheckpointHex | phase0.Checkpoint): CacheKey {
|
|
855
859
|
if (isCheckpointHex(cp)) {
|
|
856
860
|
return `${cp.rootHex}_${cp.epoch}`;
|
|
@@ -71,11 +71,34 @@ async function validateAggregateAndProof(
|
|
|
71
71
|
const attData = aggregate.data;
|
|
72
72
|
const attSlot = attData.slot;
|
|
73
73
|
|
|
74
|
-
let
|
|
75
|
-
if (ForkSeq[fork] >= ForkSeq.
|
|
76
|
-
|
|
74
|
+
let committeeIndex: number | null;
|
|
75
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
76
|
+
// [REJECT] `aggregate.data.index < 2`.
|
|
77
|
+
if (attData.index >= 2) {
|
|
78
|
+
throw new AttestationError(GossipAction.REJECT, {
|
|
79
|
+
code: AttestationErrorCode.INVALID_PAYLOAD_STATUS_VALUE,
|
|
80
|
+
attDataIndex: attData.index,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// [REJECT] `aggregate.data.index == 0` if `block.slot == aggregate.data.slot`.
|
|
84
|
+
const block = chain.forkChoice.getBlock(attData.beaconBlockRoot);
|
|
85
|
+
|
|
86
|
+
// If block is unknown, we don't handle it here. It will throw error later on at `verifyHeadBlockAndTargetRoot()`
|
|
87
|
+
if (block !== null && block.slot === attData.slot && attData.index !== 0) {
|
|
88
|
+
throw new AttestationError(GossipAction.REJECT, {
|
|
89
|
+
code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate)
|
|
94
|
+
committeeIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
|
|
95
|
+
if (committeeIndex === null) {
|
|
96
|
+
throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NOT_EXACTLY_ONE_COMMITTEE_BIT_SET});
|
|
97
|
+
}
|
|
98
|
+
} else if (ForkSeq[fork] >= ForkSeq.electra) {
|
|
99
|
+
committeeIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
|
|
77
100
|
// [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate)
|
|
78
|
-
if (
|
|
101
|
+
if (committeeIndex === null) {
|
|
79
102
|
throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NOT_EXACTLY_ONE_COMMITTEE_BIT_SET});
|
|
80
103
|
}
|
|
81
104
|
// [REJECT] aggregate.data.index == 0
|
|
@@ -83,11 +106,11 @@ async function validateAggregateAndProof(
|
|
|
83
106
|
throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NON_ZERO_ATTESTATION_DATA_INDEX});
|
|
84
107
|
}
|
|
85
108
|
} else {
|
|
86
|
-
|
|
109
|
+
committeeIndex = attData.index;
|
|
87
110
|
}
|
|
88
111
|
|
|
89
112
|
const seenAttDataKey = serializedData ? getSeenAttDataKeyFromSignedAggregateAndProof(fork, serializedData) : null;
|
|
90
|
-
const cachedAttData = seenAttDataKey ? chain.seenAttestationDatas.get(attSlot,
|
|
113
|
+
const cachedAttData = seenAttDataKey ? chain.seenAttestationDatas.get(attSlot, committeeIndex, seenAttDataKey) : null;
|
|
91
114
|
|
|
92
115
|
const attEpoch = computeEpochAtSlot(attSlot);
|
|
93
116
|
const attTarget = attData.target;
|
|
@@ -136,7 +159,7 @@ async function validateAggregateAndProof(
|
|
|
136
159
|
: toRootHex(ssz.phase0.AttestationData.hashTreeRoot(attData));
|
|
137
160
|
if (
|
|
138
161
|
!skipValidationKnownAttesters &&
|
|
139
|
-
chain.seenAggregatedAttestations.isKnown(targetEpoch,
|
|
162
|
+
chain.seenAggregatedAttestations.isKnown(targetEpoch, committeeIndex, attDataRootHex, aggregationBits)
|
|
140
163
|
) {
|
|
141
164
|
throw new AttestationError(GossipAction.IGNORE, {
|
|
142
165
|
code: AttestationErrorCode.ATTESTERS_ALREADY_KNOWN,
|
|
@@ -177,7 +200,7 @@ async function validateAggregateAndProof(
|
|
|
177
200
|
// -- i.e. data.index < get_committee_count_per_slot(state, data.target.epoch)
|
|
178
201
|
const committeeValidatorIndices = cachedAttData
|
|
179
202
|
? cachedAttData.committeeValidatorIndices
|
|
180
|
-
: getCommitteeValidatorIndices(shuffling, attSlot,
|
|
203
|
+
: getCommitteeValidatorIndices(shuffling, attSlot, committeeIndex);
|
|
181
204
|
|
|
182
205
|
// [REJECT] The number of aggregation bits matches the committee size
|
|
183
206
|
// -- i.e. `len(aggregation_bits) == len(get_beacon_committee(state, aggregate.data.slot, index))`.
|
|
@@ -216,16 +239,15 @@ async function validateAggregateAndProof(
|
|
|
216
239
|
// by the validator with index aggregate_and_proof.aggregator_index.
|
|
217
240
|
// [REJECT] The aggregator signature, signed_aggregate_and_proof.signature, is valid.
|
|
218
241
|
// [REJECT] The signature of aggregate is valid.
|
|
219
|
-
const aggregator = chain.index2pubkey[aggregateAndProof.aggregatorIndex];
|
|
220
242
|
const signingRoot = cachedAttData ? cachedAttData.signingRoot : getAttestationDataSigningRoot(chain.config, attData);
|
|
221
243
|
const indexedAttestationSignatureSet = createAggregateSignatureSetFromComponents(
|
|
222
|
-
indexedAttestation.attestingIndices
|
|
244
|
+
indexedAttestation.attestingIndices,
|
|
223
245
|
signingRoot,
|
|
224
246
|
indexedAttestation.signature
|
|
225
247
|
);
|
|
226
248
|
const signatureSets = [
|
|
227
|
-
getSelectionProofSignatureSet(chain.config, attSlot,
|
|
228
|
-
getAggregateAndProofSignatureSet(chain.config, attEpoch,
|
|
249
|
+
getSelectionProofSignatureSet(chain.config, attSlot, aggregatorIndex, signedAggregateAndProof),
|
|
250
|
+
getAggregateAndProofSignatureSet(chain.config, attEpoch, aggregatorIndex, signedAggregateAndProof),
|
|
229
251
|
indexedAttestationSignatureSet,
|
|
230
252
|
];
|
|
231
253
|
// no need to write to SeenAttestationDatas
|
|
@@ -248,7 +270,7 @@ async function validateAggregateAndProof(
|
|
|
248
270
|
// Same race-condition check as above for seen aggregators
|
|
249
271
|
if (
|
|
250
272
|
!skipValidationKnownAttesters &&
|
|
251
|
-
chain.seenAggregatedAttestations.isKnown(targetEpoch,
|
|
273
|
+
chain.seenAggregatedAttestations.isKnown(targetEpoch, committeeIndex, attDataRootHex, aggregationBits)
|
|
252
274
|
) {
|
|
253
275
|
throw new AttestationError(GossipAction.IGNORE, {
|
|
254
276
|
code: AttestationErrorCode.ATTESTERS_ALREADY_KNOWN,
|
|
@@ -260,7 +282,7 @@ async function validateAggregateAndProof(
|
|
|
260
282
|
chain.seenAggregators.add(targetEpoch, aggregatorIndex);
|
|
261
283
|
chain.seenAggregatedAttestations.add(
|
|
262
284
|
targetEpoch,
|
|
263
|
-
|
|
285
|
+
committeeIndex,
|
|
264
286
|
attDataRootHex,
|
|
265
287
|
{aggregationBits, trueBitCount: attestingIndices.length},
|
|
266
288
|
false
|