@lodestar/beacon-node 1.40.0-dev.c975f70481 → 1.40.0-dev.f016f9d123
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 +8 -18
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +3 -6
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +15 -2
- 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 +9 -8
- package/lib/api/impl/validator/index.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/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +4 -0
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +2 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +6 -0
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +2 -6
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +0 -14
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +0 -2
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -8
- 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/writeBlockInputToDb.d.ts +1 -4
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +20 -28
- 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 +21 -4
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +180 -15
- 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/interface.d.ts +21 -3
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.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/prepareNextSlot.js +6 -4
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +5 -3
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +3 -8
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -1
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +1 -2
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +2 -16
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +3 -7
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +3 -16
- 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/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 +3 -3
- 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 +5 -4
- 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 +3 -3
- 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 +2 -0
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +49 -7
- 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 +27 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +64 -0
- package/lib/metrics/metrics/lodestar.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/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +34 -3
- 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/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +2 -4
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts +1 -2
- package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRoot.js +5 -26
- package/lib/network/reqresp/handlers/beaconBlocksByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts +1 -2
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +5 -7
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +1 -2
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -5
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/index.js +2 -2
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/sync/backfill/backfill.js +2 -2
- 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/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +0 -1
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +0 -3
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +0 -3
- package/lib/sync/unknownBlock.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +8 -18
- package/src/api/impl/debug/index.ts +2 -6
- package/src/api/impl/lodestar/index.ts +18 -3
- package/src/api/impl/validator/index.ts +12 -11
- package/src/chain/ColumnReconstructionTracker.ts +8 -4
- package/src/chain/archiveStore/utils/archiveBlocks.ts +4 -0
- package/src/chain/blocks/blockInput/blockInput.ts +8 -0
- package/src/chain/blocks/importBlock.ts +2 -6
- package/src/chain/blocks/index.ts +0 -19
- package/src/chain/blocks/types.ts +0 -2
- package/src/chain/blocks/verifyBlock.ts +0 -9
- package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
- package/src/chain/blocks/writeBlockInputToDb.ts +24 -30
- 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 +205 -23
- 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/interface.ts +32 -1
- 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/prepareNextSlot.ts +6 -6
- package/src/chain/produceBlock/produceBlockBody.ts +7 -5
- package/src/chain/regen/interface.ts +2 -12
- package/src/chain/regen/queued.ts +3 -23
- package/src/chain/regen/regen.ts +4 -24
- 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/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 +2 -7
- package/src/chain/validation/block.ts +5 -4
- package/src/chain/validation/dataColumnSidecar.ts +2 -7
- 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 +62 -8
- package/src/db/repositories/checkpointState.ts +1 -1
- package/src/metrics/metrics/lodestar.ts +65 -0
- 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/processor/gossipHandlers.ts +48 -3
- package/src/network/processor/gossipQueues/index.ts +16 -0
- package/src/network/processor/index.ts +3 -0
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +2 -4
- package/src/network/reqresp/handlers/beaconBlocksByRoot.ts +5 -32
- package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +5 -9
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +5 -2
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -5
- package/src/network/reqresp/handlers/index.ts +2 -2
- package/src/sync/backfill/backfill.ts +2 -2
- package/src/sync/backfill/verify.ts +2 -3
- package/src/sync/range/chain.ts +0 -1
- package/src/sync/range/range.ts +0 -3
- package/src/sync/unknownBlock.ts +0 -3
|
@@ -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
|
+
}
|
|
@@ -80,9 +80,8 @@ export class PrepareNextSlotScheduler {
|
|
|
80
80
|
await sleep(this.config.getSlotComponentDurationMs(PREPARE_NEXT_SLOT_BPS), this.signal);
|
|
81
81
|
|
|
82
82
|
// calling updateHead() here before we produce a block to reduce reorg possibility
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
);
|
|
83
|
+
const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
|
|
84
|
+
const {slot: headSlot, blockRoot: headRoot} = headBlock;
|
|
86
85
|
|
|
87
86
|
// PS: previously this was comparing slots, but that gave no leway on the skipped
|
|
88
87
|
// slots on epoch bounday. Making it more fluid.
|
|
@@ -112,7 +111,7 @@ export class PrepareNextSlotScheduler {
|
|
|
112
111
|
// Pre Bellatrix: we only do precompute state transition for the last slot of epoch
|
|
113
112
|
// For Bellatrix, we always do the `processSlots()` to prepare payload for the next slot
|
|
114
113
|
const prepareState = await this.chain.regen.getBlockSlotState(
|
|
115
|
-
|
|
114
|
+
headBlock,
|
|
116
115
|
prepareSlot,
|
|
117
116
|
// the slot 0 of next epoch will likely use this Previous Root Checkpoint state for state transition so we transfer cache here
|
|
118
117
|
// the resulting state with cache will be cached in Checkpoint State Cache which is used for the upcoming block processing
|
|
@@ -129,7 +128,8 @@ export class PrepareNextSlotScheduler {
|
|
|
129
128
|
|
|
130
129
|
if (feeRecipient) {
|
|
131
130
|
// If we are proposing next slot, we need to predict if we can proposer-boost-reorg or not
|
|
132
|
-
const
|
|
131
|
+
const proposerHead = this.chain.predictProposerHead(clockSlot);
|
|
132
|
+
const {slot: proposerHeadSlot, blockRoot: proposerHeadRoot} = proposerHead;
|
|
133
133
|
|
|
134
134
|
// If we predict we can reorg, update prepareState with proposer head block
|
|
135
135
|
if (proposerHeadRoot !== headRoot || proposerHeadSlot !== headSlot) {
|
|
@@ -141,7 +141,7 @@ export class PrepareNextSlotScheduler {
|
|
|
141
141
|
});
|
|
142
142
|
this.metrics?.weakHeadDetected.inc();
|
|
143
143
|
updatedPrepareState = (await this.chain.regen.getBlockSlotState(
|
|
144
|
-
|
|
144
|
+
proposerHead,
|
|
145
145
|
prepareSlot,
|
|
146
146
|
// only transfer cache if epoch transition because that's the state we will use to stateTransition() the 1st block of epoch
|
|
147
147
|
{dontTransferCache: !isEpochTransition},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
2
|
+
import {ProtoBlock, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
3
3
|
import {
|
|
4
4
|
ForkName,
|
|
5
5
|
ForkPostBellatrix,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
electra,
|
|
44
44
|
fulu,
|
|
45
45
|
} from "@lodestar/types";
|
|
46
|
-
import {Logger, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
46
|
+
import {Logger, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
47
47
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
48
48
|
import {numToQuantity} from "../../execution/engine/utils.js";
|
|
49
49
|
import {
|
|
@@ -86,7 +86,7 @@ export type BlockAttributes = {
|
|
|
86
86
|
randaoReveal: BLSSignature;
|
|
87
87
|
graffiti: Bytes32;
|
|
88
88
|
slot: Slot;
|
|
89
|
-
|
|
89
|
+
parentBlock: ProtoBlock;
|
|
90
90
|
feeRecipient?: string;
|
|
91
91
|
};
|
|
92
92
|
|
|
@@ -155,13 +155,14 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
155
155
|
const {
|
|
156
156
|
slot: blockSlot,
|
|
157
157
|
feeRecipient: requestedFeeRecipient,
|
|
158
|
-
|
|
158
|
+
parentBlock,
|
|
159
159
|
proposerIndex,
|
|
160
160
|
proposerPubKey,
|
|
161
161
|
commonBlockBodyPromise,
|
|
162
162
|
} = blockAttr;
|
|
163
163
|
let executionPayloadValue: Wei;
|
|
164
164
|
let blockBody: AssembledBodyType<T>;
|
|
165
|
+
const parentBlockRoot = fromHex(parentBlock.blockRoot);
|
|
165
166
|
// even though shouldOverrideBuilder is relevant for the engine response, for simplicity of typing
|
|
166
167
|
// we just return it undefined for the builder which anyway doesn't get consumed downstream
|
|
167
168
|
let shouldOverrideBuilder: boolean | undefined;
|
|
@@ -637,7 +638,7 @@ export async function produceCommonBlockBody<T extends BlockType>(
|
|
|
637
638
|
this: BeaconChain,
|
|
638
639
|
blockType: T,
|
|
639
640
|
currentState: CachedBeaconStateAllForks,
|
|
640
|
-
{randaoReveal, graffiti, slot,
|
|
641
|
+
{randaoReveal, graffiti, slot, parentBlock}: BlockAttributes
|
|
641
642
|
): Promise<CommonBlockBody> {
|
|
642
643
|
const stepsMetrics =
|
|
643
644
|
blockType === BlockType.Full
|
|
@@ -691,6 +692,7 @@ export async function produceCommonBlockBody<T extends BlockType>(
|
|
|
691
692
|
|
|
692
693
|
const endSyncAggregate = stepsMetrics?.startTimer();
|
|
693
694
|
if (ForkSeq[fork] >= ForkSeq.altair) {
|
|
695
|
+
const parentBlockRoot = fromHex(parentBlock.blockRoot);
|
|
694
696
|
const previousSlot = slot - 1;
|
|
695
697
|
const syncAggregate = this.syncContributionAndProofPool.getAggregate(previousSlot, parentBlockRoot);
|
|
696
698
|
this.metrics?.production.producedSyncAggregateParticipants.observe(
|
|
@@ -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
|
}
|
|
@@ -26,7 +27,6 @@ export enum RegenFnName {
|
|
|
26
27
|
getBlockSlotState = "getBlockSlotState",
|
|
27
28
|
getState = "getState",
|
|
28
29
|
getPreState = "getPreState",
|
|
29
|
-
getCheckpointState = "getCheckpointState",
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export type StateRegenerationOpts = {
|
|
@@ -63,21 +63,11 @@ export interface IStateRegeneratorInternal {
|
|
|
63
63
|
rCaller: RegenCaller
|
|
64
64
|
): Promise<CachedBeaconStateAllForks>;
|
|
65
65
|
|
|
66
|
-
/**
|
|
67
|
-
* Return a valid checkpoint state
|
|
68
|
-
* This will always return a state with `state.slot % SLOTS_PER_EPOCH === 0`
|
|
69
|
-
*/
|
|
70
|
-
getCheckpointState(
|
|
71
|
-
cp: phase0.Checkpoint,
|
|
72
|
-
opts: StateRegenerationOpts,
|
|
73
|
-
rCaller: RegenCaller
|
|
74
|
-
): Promise<CachedBeaconStateAllForks>;
|
|
75
|
-
|
|
76
66
|
/**
|
|
77
67
|
* Return the state of `blockRoot` processed to slot `slot`
|
|
78
68
|
*/
|
|
79
69
|
getBlockSlotState(
|
|
80
|
-
|
|
70
|
+
block: ProtoBlock,
|
|
81
71
|
slot: Slot,
|
|
82
72
|
opts: StateRegenerationOpts,
|
|
83
73
|
rCaller: RegenCaller
|
|
@@ -5,7 +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
|
|
8
|
+
import {CheckpointHex} from "../stateCache/index.js";
|
|
9
9
|
import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
|
|
10
10
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
11
11
|
import {
|
|
@@ -220,24 +220,6 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
220
220
|
return this.jobQueue.push({key: "getPreState", args: [block, opts, rCaller]});
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
async getCheckpointState(
|
|
224
|
-
cp: phase0.Checkpoint,
|
|
225
|
-
opts: StateRegenerationOpts,
|
|
226
|
-
rCaller: RegenCaller
|
|
227
|
-
): Promise<CachedBeaconStateAllForks> {
|
|
228
|
-
this.metrics?.regenFnCallTotal.inc({caller: rCaller, entrypoint: RegenFnName.getCheckpointState});
|
|
229
|
-
|
|
230
|
-
// First attempt to fetch the state from cache before queueing
|
|
231
|
-
const checkpointState = this.checkpointStateCache.get(toCheckpointHex(cp));
|
|
232
|
-
if (checkpointState) {
|
|
233
|
-
return checkpointState;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// The state is not immediately available in the caches, enqueue the job
|
|
237
|
-
this.metrics?.regenFnQueuedTotal.inc({caller: rCaller, entrypoint: RegenFnName.getCheckpointState});
|
|
238
|
-
return this.jobQueue.push({key: "getCheckpointState", args: [cp, opts, rCaller]});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
223
|
/**
|
|
242
224
|
* Get state of provided `blockRoot` and dial forward to `slot`
|
|
243
225
|
* Use this api with care because we don't want the queue to be busy
|
|
@@ -245,7 +227,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
245
227
|
* @returns
|
|
246
228
|
*/
|
|
247
229
|
async getBlockSlotState(
|
|
248
|
-
|
|
230
|
+
block: ProtoBlock,
|
|
249
231
|
slot: Slot,
|
|
250
232
|
opts: StateRegenerationOpts,
|
|
251
233
|
rCaller: RegenCaller
|
|
@@ -253,7 +235,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
253
235
|
this.metrics?.regenFnCallTotal.inc({caller: rCaller, entrypoint: RegenFnName.getBlockSlotState});
|
|
254
236
|
|
|
255
237
|
// The state is not immediately available in the caches, enqueue the job
|
|
256
|
-
return this.jobQueue.push({key: "getBlockSlotState", args: [
|
|
238
|
+
return this.jobQueue.push({key: "getBlockSlotState", args: [block, slot, opts, rCaller]});
|
|
257
239
|
}
|
|
258
240
|
|
|
259
241
|
async getState(stateRoot: RootHex, rCaller: RegenCaller): Promise<CachedBeaconStateAllForks> {
|
|
@@ -281,8 +263,6 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
281
263
|
switch (regenRequest.key) {
|
|
282
264
|
case "getPreState":
|
|
283
265
|
return await this.regen.getPreState(...regenRequest.args);
|
|
284
|
-
case "getCheckpointState":
|
|
285
|
-
return await this.regen.getCheckpointState(...regenRequest.args);
|
|
286
266
|
case "getBlockSlotState":
|
|
287
267
|
return await this.regen.getBlockSlotState(...regenRequest.args);
|
|
288
268
|
case "getState":
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
processSlots,
|
|
12
12
|
stateTransition,
|
|
13
13
|
} from "@lodestar/state-transition";
|
|
14
|
-
import {BeaconBlock, RootHex, SignedBeaconBlock, Slot
|
|
14
|
+
import {BeaconBlock, RootHex, SignedBeaconBlock, Slot} from "@lodestar/types";
|
|
15
15
|
import {Logger, fromHex, toRootHex} from "@lodestar/utils";
|
|
16
16
|
import {IBeaconDb} from "../../db/index.js";
|
|
17
17
|
import {Metrics} from "../../metrics/index.js";
|
|
@@ -74,45 +74,24 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
74
74
|
// We may have the checkpoint state with parent root inside the checkpoint state cache
|
|
75
75
|
// through gossip validation.
|
|
76
76
|
if (parentEpoch < blockEpoch) {
|
|
77
|
-
return this.
|
|
77
|
+
return this.getBlockSlotState(parentBlock, block.slot, opts, regenCaller, allowDiskReload);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// Otherwise, get the state normally.
|
|
81
81
|
return this.getState(parentBlock.stateRoot, regenCaller, allowDiskReload);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/**
|
|
85
|
-
* Get state after block `cp.root` dialed forward to first slot of `cp.epoch`
|
|
86
|
-
*/
|
|
87
|
-
async getCheckpointState(
|
|
88
|
-
cp: phase0.Checkpoint,
|
|
89
|
-
opts: StateRegenerationOpts,
|
|
90
|
-
regenCaller: RegenCaller,
|
|
91
|
-
allowDiskReload = false
|
|
92
|
-
): Promise<CachedBeaconStateAllForks> {
|
|
93
|
-
const checkpointStartSlot = computeStartSlotAtEpoch(cp.epoch);
|
|
94
|
-
return this.getBlockSlotState(toRootHex(cp.root), checkpointStartSlot, opts, regenCaller, allowDiskReload);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
84
|
/**
|
|
98
85
|
* Get state after block `blockRoot` dialed forward to `slot`
|
|
99
86
|
* - allowDiskReload should be used with care, as it will cause the state to be reloaded from disk
|
|
100
87
|
*/
|
|
101
88
|
async getBlockSlotState(
|
|
102
|
-
|
|
89
|
+
block: ProtoBlock,
|
|
103
90
|
slot: Slot,
|
|
104
91
|
opts: StateRegenerationOpts,
|
|
105
92
|
regenCaller: RegenCaller,
|
|
106
93
|
allowDiskReload = false
|
|
107
94
|
): Promise<CachedBeaconStateAllForks> {
|
|
108
|
-
const block = this.modules.forkChoice.getBlockHex(blockRoot);
|
|
109
|
-
if (!block) {
|
|
110
|
-
throw new RegenError({
|
|
111
|
-
code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
|
|
112
|
-
blockRoot,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
95
|
if (slot < block.slot) {
|
|
117
96
|
throw new RegenError({
|
|
118
97
|
code: RegenErrorCode.SLOT_BEFORE_BLOCK_SLOT,
|
|
@@ -121,6 +100,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
121
100
|
});
|
|
122
101
|
}
|
|
123
102
|
|
|
103
|
+
const {blockRoot} = block;
|
|
124
104
|
const {checkpointStateCache} = this.modules;
|
|
125
105
|
const epoch = computeEpochAtSlot(slot);
|
|
126
106
|
const latestCheckpointStateCtx = allowDiskReload
|
|
@@ -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
|
+
}
|