@lodestar/beacon-node 1.40.0-dev.c1d3b3c5cc → 1.40.0-dev.c4af2af040
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 -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/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 +36 -1
- 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/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 +9 -4
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +48 -43
- 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 +7 -2
- 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/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/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 +4 -9
- 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 +2 -3
- 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 +5 -7
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +7 -17
- 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.js +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 +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 +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 +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.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.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/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +31 -19
- package/src/api/impl/lodestar/index.ts +29 -3
- package/src/api/impl/validator/index.ts +14 -12
- package/src/chain/ColumnReconstructionTracker.ts +8 -4
- package/src/chain/blocks/blockInput/blockInput.ts +45 -2
- 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/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 +56 -55
- 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 +16 -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/options.ts +0 -2
- package/src/chain/prepareNextSlot.ts +6 -6
- package/src/chain/produceBlock/produceBlockBody.ts +7 -5
- package/src/chain/regen/interface.ts +3 -13
- package/src/chain/regen/queued.ts +3 -24
- package/src/chain/regen/regen.ts +10 -25
- 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 +1 -1
- 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 +2 -7
- package/src/chain/validation/block.ts +6 -6
- 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 +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 +2 -2
- package/src/sync/backfill/verify.ts +2 -3
- 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/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
- package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import {peerIdFromString} from "@libp2p/peer-id";
|
|
2
|
+
import {multiaddr} from "@multiformats/multiaddr";
|
|
3
|
+
import {ENR} from "@chainsafe/enr";
|
|
1
4
|
import {GossipSub, GossipsubEvents} from "@chainsafe/libp2p-gossipsub";
|
|
2
5
|
import {MetricsRegister, TopicLabel, TopicStrToLabel} from "@chainsafe/libp2p-gossipsub/metrics";
|
|
3
6
|
import {PeerScoreParams} from "@chainsafe/libp2p-gossipsub/score";
|
|
4
|
-
import {SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
|
|
7
|
+
import {AddrInfo, SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
|
|
8
|
+
import {routes} from "@lodestar/api";
|
|
5
9
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
6
10
|
import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
|
|
7
11
|
import {SubnetID} from "@lodestar/types";
|
|
@@ -55,6 +59,12 @@ export type Eth2GossipsubOpts = {
|
|
|
55
59
|
disableFloodPublish?: boolean;
|
|
56
60
|
skipParamsLog?: boolean;
|
|
57
61
|
disableLightClientServer?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
|
|
64
|
+
* Supports multiaddr strings with peer ID (e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...")
|
|
65
|
+
* or ENR strings (e.g., "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...")
|
|
66
|
+
*/
|
|
67
|
+
directPeers?: string[];
|
|
58
68
|
};
|
|
59
69
|
|
|
60
70
|
export type ForkBoundaryLabel = string;
|
|
@@ -78,6 +88,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
78
88
|
private readonly logger: Logger;
|
|
79
89
|
private readonly peersData: PeersData;
|
|
80
90
|
private readonly events: NetworkEventBus;
|
|
91
|
+
private readonly libp2p: Libp2p;
|
|
81
92
|
|
|
82
93
|
// Internal caches
|
|
83
94
|
private readonly gossipTopicCache: GossipTopicCache;
|
|
@@ -97,6 +108,9 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
97
108
|
);
|
|
98
109
|
}
|
|
99
110
|
|
|
111
|
+
// Parse direct peers from multiaddr strings to AddrInfo objects
|
|
112
|
+
const directPeers = parseDirectPeers(opts.directPeers ?? [], logger);
|
|
113
|
+
|
|
100
114
|
// Gossipsub parameters defined here:
|
|
101
115
|
// https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
|
|
102
116
|
super(modules.libp2p.services.components, {
|
|
@@ -106,6 +120,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
106
120
|
Dlo: gossipsubDLow ?? GOSSIP_D_LOW,
|
|
107
121
|
Dhi: gossipsubDHigh ?? GOSSIP_D_HIGH,
|
|
108
122
|
Dlazy: 6,
|
|
123
|
+
directPeers,
|
|
109
124
|
heartbeatInterval: GOSSIPSUB_HEARTBEAT_INTERVAL,
|
|
110
125
|
fanoutTTL: 60 * 1000,
|
|
111
126
|
mcacheLength: 6,
|
|
@@ -146,6 +161,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
146
161
|
this.logger = logger;
|
|
147
162
|
this.peersData = peersData;
|
|
148
163
|
this.events = events;
|
|
164
|
+
this.libp2p = modules.libp2p;
|
|
149
165
|
this.gossipTopicCache = gossipTopicCache;
|
|
150
166
|
|
|
151
167
|
this.addEventListener("gossipsub:message", this.onGossipsubMessage.bind(this));
|
|
@@ -328,6 +344,64 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
328
344
|
this.reportMessageValidationResult(data.msgId, data.propagationSource, data.acceptance);
|
|
329
345
|
});
|
|
330
346
|
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Add a peer as a direct peer at runtime. Accepts multiaddr with peer ID or ENR string.
|
|
350
|
+
* Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
|
|
351
|
+
*/
|
|
352
|
+
async addDirectPeer(peerStr: routes.lodestar.DirectPeer): Promise<string | null> {
|
|
353
|
+
const parsed = parseDirectPeers([peerStr], this.logger);
|
|
354
|
+
if (parsed.length === 0) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const {id: peerId, addrs} = parsed[0];
|
|
359
|
+
const peerIdStr = peerId.toString();
|
|
360
|
+
|
|
361
|
+
// Prevent adding self as a direct peer
|
|
362
|
+
if (peerId.equals(this.libp2p.peerId)) {
|
|
363
|
+
this.logger.warn("Cannot add self as a direct peer", {peerId: peerIdStr});
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Direct peers need addresses to connect - reject if none provided
|
|
368
|
+
if (addrs.length === 0) {
|
|
369
|
+
this.logger.warn("Cannot add direct peer without addresses", {peerId: peerIdStr});
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Add addresses to peer store first so we can connect
|
|
374
|
+
try {
|
|
375
|
+
await this.libp2p.peerStore.merge(peerId, {multiaddrs: addrs});
|
|
376
|
+
} catch (e) {
|
|
377
|
+
this.logger.warn("Failed to add direct peer addresses to peer store", {peerId: peerIdStr}, e as Error);
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Add to direct peers set only after addresses are stored
|
|
382
|
+
this.direct.add(peerIdStr);
|
|
383
|
+
|
|
384
|
+
this.logger.info("Added direct peer via API", {peerId: peerIdStr});
|
|
385
|
+
return peerIdStr;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Remove a peer from direct peers.
|
|
390
|
+
*/
|
|
391
|
+
removeDirectPeer(peerIdStr: string): boolean {
|
|
392
|
+
const removed = this.direct.delete(peerIdStr);
|
|
393
|
+
if (removed) {
|
|
394
|
+
this.logger.info("Removed direct peer via API", {peerId: peerIdStr});
|
|
395
|
+
}
|
|
396
|
+
return removed;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Get list of current direct peer IDs.
|
|
401
|
+
*/
|
|
402
|
+
getDirectPeers(): string[] {
|
|
403
|
+
return Array.from(this.direct);
|
|
404
|
+
}
|
|
331
405
|
}
|
|
332
406
|
|
|
333
407
|
/**
|
|
@@ -381,3 +455,75 @@ function getForkBoundaryLabel(boundary: ForkBoundary): ForkBoundaryLabel {
|
|
|
381
455
|
|
|
382
456
|
return label;
|
|
383
457
|
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Parse direct peer strings into AddrInfo objects for GossipSub.
|
|
461
|
+
* Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
|
|
462
|
+
*
|
|
463
|
+
* Supported formats:
|
|
464
|
+
* - Multiaddr with peer ID: `/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...`
|
|
465
|
+
* - ENR: `enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...`
|
|
466
|
+
*
|
|
467
|
+
* For multiaddrs, the string must contain a /p2p/ component with the peer ID.
|
|
468
|
+
* For ENRs, the TCP multiaddr and peer ID are extracted from the encoded record.
|
|
469
|
+
*/
|
|
470
|
+
export function parseDirectPeers(directPeerStrs: routes.lodestar.DirectPeer[], logger: Logger): AddrInfo[] {
|
|
471
|
+
const directPeers: AddrInfo[] = [];
|
|
472
|
+
|
|
473
|
+
for (const peerStr of directPeerStrs) {
|
|
474
|
+
// Check if this is an ENR (starts with "enr:")
|
|
475
|
+
if (peerStr.startsWith("enr:")) {
|
|
476
|
+
try {
|
|
477
|
+
const enr = ENR.decodeTxt(peerStr);
|
|
478
|
+
const peerId = enr.peerId;
|
|
479
|
+
|
|
480
|
+
// Get TCP multiaddr from ENR
|
|
481
|
+
const multiaddrTCP = enr.getLocationMultiaddr("tcp");
|
|
482
|
+
if (!multiaddrTCP) {
|
|
483
|
+
logger.warn("ENR does not contain TCP multiaddr", {enr: peerStr});
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
directPeers.push({
|
|
488
|
+
id: peerId,
|
|
489
|
+
addrs: [multiaddrTCP],
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
logger.info("Added direct peer from ENR", {peerId: peerId.toString(), addr: multiaddrTCP.toString()});
|
|
493
|
+
} catch (e) {
|
|
494
|
+
logger.warn("Failed to parse direct peer ENR", {enr: peerStr}, e as Error);
|
|
495
|
+
}
|
|
496
|
+
} else {
|
|
497
|
+
// Parse as multiaddr
|
|
498
|
+
try {
|
|
499
|
+
const ma = multiaddr(peerStr);
|
|
500
|
+
|
|
501
|
+
const peerIdStr = ma.getPeerId();
|
|
502
|
+
if (!peerIdStr) {
|
|
503
|
+
logger.warn("Direct peer multiaddr must contain /p2p/ component with peer ID", {multiaddr: peerStr});
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
try {
|
|
508
|
+
const peerId = peerIdFromString(peerIdStr);
|
|
509
|
+
|
|
510
|
+
// Get the address without the /p2p/ component
|
|
511
|
+
const addr = ma.decapsulate("/p2p/" + peerIdStr);
|
|
512
|
+
|
|
513
|
+
directPeers.push({
|
|
514
|
+
id: peerId,
|
|
515
|
+
addrs: [addr],
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
logger.info("Added direct peer", {peerId: peerIdStr, addr: addr.toString()});
|
|
519
|
+
} catch (e) {
|
|
520
|
+
logger.warn("Invalid peer ID in direct peer multiaddr", {multiaddr: peerStr, peerId: peerIdStr}, e as Error);
|
|
521
|
+
}
|
|
522
|
+
} catch (e) {
|
|
523
|
+
logger.warn("Failed to parse direct peer multiaddr", {multiaddr: peerStr}, e as Error);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return directPeers;
|
|
529
|
+
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
capella,
|
|
16
16
|
deneb,
|
|
17
17
|
fulu,
|
|
18
|
+
gloas,
|
|
18
19
|
phase0,
|
|
19
20
|
} from "@lodestar/types";
|
|
20
21
|
import {Logger} from "@lodestar/utils";
|
|
@@ -37,6 +38,9 @@ export enum GossipType {
|
|
|
37
38
|
light_client_finality_update = "light_client_finality_update",
|
|
38
39
|
light_client_optimistic_update = "light_client_optimistic_update",
|
|
39
40
|
bls_to_execution_change = "bls_to_execution_change",
|
|
41
|
+
execution_payload = "execution_payload",
|
|
42
|
+
payload_attestation_message = "payload_attestation_message",
|
|
43
|
+
execution_payload_bid = "execution_payload_bid",
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
export type SequentialGossipType = Exclude<GossipType, GossipType.beacon_attestation>;
|
|
@@ -71,6 +75,9 @@ export type GossipTopicTypeMap = {
|
|
|
71
75
|
[GossipType.light_client_finality_update]: {type: GossipType.light_client_finality_update};
|
|
72
76
|
[GossipType.light_client_optimistic_update]: {type: GossipType.light_client_optimistic_update};
|
|
73
77
|
[GossipType.bls_to_execution_change]: {type: GossipType.bls_to_execution_change};
|
|
78
|
+
[GossipType.execution_payload]: {type: GossipType.execution_payload};
|
|
79
|
+
[GossipType.payload_attestation_message]: {type: GossipType.payload_attestation_message};
|
|
80
|
+
[GossipType.execution_payload_bid]: {type: GossipType.execution_payload_bid};
|
|
74
81
|
};
|
|
75
82
|
|
|
76
83
|
export type GossipTopicMap = {
|
|
@@ -100,6 +107,9 @@ export type GossipTypeMap = {
|
|
|
100
107
|
[GossipType.light_client_finality_update]: LightClientFinalityUpdate;
|
|
101
108
|
[GossipType.light_client_optimistic_update]: LightClientOptimisticUpdate;
|
|
102
109
|
[GossipType.bls_to_execution_change]: capella.SignedBLSToExecutionChange;
|
|
110
|
+
[GossipType.execution_payload]: gloas.SignedExecutionPayloadEnvelope;
|
|
111
|
+
[GossipType.payload_attestation_message]: gloas.PayloadAttestationMessage;
|
|
112
|
+
[GossipType.execution_payload_bid]: gloas.SignedExecutionPayloadBid;
|
|
103
113
|
};
|
|
104
114
|
|
|
105
115
|
export type GossipFnByType = {
|
|
@@ -124,6 +134,13 @@ export type GossipFnByType = {
|
|
|
124
134
|
[GossipType.bls_to_execution_change]: (
|
|
125
135
|
blsToExecutionChange: capella.SignedBLSToExecutionChange
|
|
126
136
|
) => Promise<void> | void;
|
|
137
|
+
[GossipType.execution_payload]: (
|
|
138
|
+
executionPayloadEnvelope: gloas.SignedExecutionPayloadEnvelope
|
|
139
|
+
) => Promise<void> | void;
|
|
140
|
+
[GossipType.payload_attestation_message]: (
|
|
141
|
+
payloadAttestationMessage: gloas.PayloadAttestationMessage
|
|
142
|
+
) => Promise<void> | void;
|
|
143
|
+
[GossipType.execution_payload_bid]: (executionPayloadBid: gloas.SignedExecutionPayloadBid) => Promise<void> | void;
|
|
127
144
|
};
|
|
128
145
|
|
|
129
146
|
export type GossipFn = GossipFnByType[keyof GossipFnByType];
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
defaultTopicScoreParams,
|
|
6
6
|
} from "@chainsafe/libp2p-gossipsub/score";
|
|
7
7
|
import {BeaconConfig} from "@lodestar/config";
|
|
8
|
-
import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, TARGET_AGGREGATORS_PER_COMMITTEE} from "@lodestar/params";
|
|
8
|
+
import {ATTESTATION_SUBNET_COUNT, PTC_SIZE, SLOTS_PER_EPOCH, TARGET_AGGREGATORS_PER_COMMITTEE} from "@lodestar/params";
|
|
9
9
|
import {computeCommitteeCount} from "@lodestar/state-transition";
|
|
10
10
|
import {getActiveForkBoundaries} from "../forks.js";
|
|
11
11
|
import {Eth2Context} from "./gossipsub.js";
|
|
@@ -24,6 +24,9 @@ const VOLUNTARY_EXIT_WEIGHT = 0.05;
|
|
|
24
24
|
const PROPOSER_SLASHING_WEIGHT = 0.05;
|
|
25
25
|
const ATTESTER_SLASHING_WEIGHT = 0.05;
|
|
26
26
|
const BLS_TO_EXECUTION_CHANGE_WEIGHT = 0.05;
|
|
27
|
+
const EXECUTION_PAYLOAD_WEIGHT = 0.5;
|
|
28
|
+
const PAYLOAD_ATTESTATION_WEIGHT = 0.05;
|
|
29
|
+
const EXECUTION_PAYLOAD_BID_WEIGHT = 0.05;
|
|
27
30
|
|
|
28
31
|
const beaconAttestationSubnetWeight = 1 / ATTESTATION_SUBNET_COUNT;
|
|
29
32
|
const maxPositiveScore =
|
|
@@ -34,7 +37,10 @@ const maxPositiveScore =
|
|
|
34
37
|
VOLUNTARY_EXIT_WEIGHT +
|
|
35
38
|
PROPOSER_SLASHING_WEIGHT +
|
|
36
39
|
ATTESTER_SLASHING_WEIGHT +
|
|
37
|
-
BLS_TO_EXECUTION_CHANGE_WEIGHT
|
|
40
|
+
BLS_TO_EXECUTION_CHANGE_WEIGHT +
|
|
41
|
+
EXECUTION_PAYLOAD_WEIGHT +
|
|
42
|
+
PAYLOAD_ATTESTATION_WEIGHT +
|
|
43
|
+
EXECUTION_PAYLOAD_BID_WEIGHT);
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
46
|
* The following params is implemented by Lighthouse at
|
|
@@ -172,6 +178,26 @@ function getAllTopicsScoreParams(
|
|
|
172
178
|
expectedMessageRate: 1 / 5 / SLOTS_PER_EPOCH,
|
|
173
179
|
firstMessageDecayTime: epochDurationMs * 100,
|
|
174
180
|
});
|
|
181
|
+
topicsParams[
|
|
182
|
+
stringifyGossipTopic(config, {
|
|
183
|
+
type: GossipType.payload_attestation_message,
|
|
184
|
+
boundary,
|
|
185
|
+
})
|
|
186
|
+
] = getTopicScoreParams(config, precomputedParams, {
|
|
187
|
+
topicWeight: PAYLOAD_ATTESTATION_WEIGHT,
|
|
188
|
+
expectedMessageRate: PTC_SIZE,
|
|
189
|
+
firstMessageDecayTime: epochDurationMs * 100,
|
|
190
|
+
});
|
|
191
|
+
topicsParams[
|
|
192
|
+
stringifyGossipTopic(config, {
|
|
193
|
+
type: GossipType.execution_payload_bid,
|
|
194
|
+
boundary,
|
|
195
|
+
})
|
|
196
|
+
] = getTopicScoreParams(config, precomputedParams, {
|
|
197
|
+
topicWeight: EXECUTION_PAYLOAD_BID_WEIGHT,
|
|
198
|
+
expectedMessageRate: 1024, // TODO GLOAS: Need an estimate for this
|
|
199
|
+
firstMessageDecayTime: epochDurationMs * 100,
|
|
200
|
+
});
|
|
175
201
|
|
|
176
202
|
// other topics
|
|
177
203
|
topicsParams[
|
|
@@ -190,6 +216,22 @@ function getAllTopicsScoreParams(
|
|
|
190
216
|
currentSlot: eth2Context.currentSlot,
|
|
191
217
|
},
|
|
192
218
|
});
|
|
219
|
+
topicsParams[
|
|
220
|
+
stringifyGossipTopic(config, {
|
|
221
|
+
type: GossipType.execution_payload,
|
|
222
|
+
boundary,
|
|
223
|
+
})
|
|
224
|
+
] = getTopicScoreParams(config, precomputedParams, {
|
|
225
|
+
topicWeight: EXECUTION_PAYLOAD_WEIGHT,
|
|
226
|
+
expectedMessageRate: 1,
|
|
227
|
+
firstMessageDecayTime: epochDurationMs * 20,
|
|
228
|
+
meshMessageInfo: {
|
|
229
|
+
decaySlots: SLOTS_PER_EPOCH * 5,
|
|
230
|
+
capFactor: 3,
|
|
231
|
+
activationWindow: epochDurationMs,
|
|
232
|
+
currentSlot: eth2Context.currentSlot,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
193
235
|
|
|
194
236
|
const activeValidatorCount = eth2Context.activeValidatorCount;
|
|
195
237
|
const {aggregatorsPerslot, committeesPerSlot} = expectedAggregatorCountPerSlot(activeValidatorCount);
|
|
@@ -69,6 +69,9 @@ function stringifyGossipTopicType(topic: GossipTopic): string {
|
|
|
69
69
|
case GossipType.light_client_finality_update:
|
|
70
70
|
case GossipType.light_client_optimistic_update:
|
|
71
71
|
case GossipType.bls_to_execution_change:
|
|
72
|
+
case GossipType.execution_payload:
|
|
73
|
+
case GossipType.payload_attestation_message:
|
|
74
|
+
case GossipType.execution_payload_bid:
|
|
72
75
|
return topic.type;
|
|
73
76
|
case GossipType.beacon_attestation:
|
|
74
77
|
case GossipType.sync_committee:
|
|
@@ -114,6 +117,12 @@ export function getGossipSSZType(topic: GossipTopic) {
|
|
|
114
117
|
: ssz.altair.LightClientFinalityUpdate;
|
|
115
118
|
case GossipType.bls_to_execution_change:
|
|
116
119
|
return ssz.capella.SignedBLSToExecutionChange;
|
|
120
|
+
case GossipType.execution_payload:
|
|
121
|
+
return ssz.gloas.SignedExecutionPayloadEnvelope;
|
|
122
|
+
case GossipType.payload_attestation_message:
|
|
123
|
+
return ssz.gloas.PayloadAttestationMessage;
|
|
124
|
+
case GossipType.execution_payload_bid:
|
|
125
|
+
return ssz.gloas.SignedExecutionPayloadBid;
|
|
117
126
|
}
|
|
118
127
|
}
|
|
119
128
|
|
|
@@ -190,6 +199,9 @@ export function parseGossipTopic(forkDigestContext: ForkDigestContext, topicStr:
|
|
|
190
199
|
case GossipType.light_client_finality_update:
|
|
191
200
|
case GossipType.light_client_optimistic_update:
|
|
192
201
|
case GossipType.bls_to_execution_change:
|
|
202
|
+
case GossipType.execution_payload:
|
|
203
|
+
case GossipType.payload_attestation_message:
|
|
204
|
+
case GossipType.execution_payload_bid:
|
|
193
205
|
return {type: gossipTypeStr, boundary, encoding};
|
|
194
206
|
}
|
|
195
207
|
|
|
@@ -240,6 +252,12 @@ export function getCoreTopicsAtFork(
|
|
|
240
252
|
{type: GossipType.attester_slashing},
|
|
241
253
|
];
|
|
242
254
|
|
|
255
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
256
|
+
topics.push({type: GossipType.execution_payload});
|
|
257
|
+
topics.push({type: GossipType.payload_attestation_message});
|
|
258
|
+
topics.push({type: GossipType.execution_payload_bid});
|
|
259
|
+
}
|
|
260
|
+
|
|
243
261
|
// After fulu also track data_column_sidecar_{index}
|
|
244
262
|
if (ForkSeq[fork] >= ForkSeq.fulu) {
|
|
245
263
|
topics.push(...getDataColumnSidecarTopics(networkConfig));
|
|
@@ -329,4 +347,7 @@ export const gossipTopicIgnoreDuplicatePublishError: Record<GossipType, boolean>
|
|
|
329
347
|
[GossipType.light_client_finality_update]: false,
|
|
330
348
|
[GossipType.light_client_optimistic_update]: false,
|
|
331
349
|
[GossipType.bls_to_execution_change]: true,
|
|
350
|
+
[GossipType.execution_payload]: true,
|
|
351
|
+
[GossipType.payload_attestation_message]: true,
|
|
352
|
+
[GossipType.execution_payload_bid]: true,
|
|
332
353
|
};
|
package/src/network/network.ts
CHANGED
|
@@ -641,6 +641,18 @@ export class Network implements INetwork {
|
|
|
641
641
|
return this.core.disconnectPeer(peer);
|
|
642
642
|
}
|
|
643
643
|
|
|
644
|
+
addDirectPeer(peer: routes.lodestar.DirectPeer): Promise<string | null> {
|
|
645
|
+
return this.core.addDirectPeer(peer);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
removeDirectPeer(peerId: string): Promise<boolean> {
|
|
649
|
+
return this.core.removeDirectPeer(peerId);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
getDirectPeers(): Promise<string[]> {
|
|
653
|
+
return this.core.getDirectPeers();
|
|
654
|
+
}
|
|
655
|
+
|
|
644
656
|
dumpPeer(peerIdStr: string): Promise<routes.lodestar.LodestarNodePeer | undefined> {
|
|
645
657
|
return this.core.dumpPeer(peerIdStr);
|
|
646
658
|
}
|
package/src/network/options.ts
CHANGED
|
@@ -15,6 +15,12 @@ export interface NetworkOptions
|
|
|
15
15
|
Omit<Eth2GossipsubOpts, "disableLightClientServer"> {
|
|
16
16
|
localMultiaddrs: string[];
|
|
17
17
|
bootMultiaddrs?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
|
|
20
|
+
* Format: multiaddr strings with peer ID, e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7..."
|
|
21
|
+
* Both peers must configure each other as direct peers for the feature to work properly.
|
|
22
|
+
*/
|
|
23
|
+
directPeers?: string[];
|
|
18
24
|
subscribeAllSubnets?: boolean;
|
|
19
25
|
mdns?: boolean;
|
|
20
26
|
connectToDiscv5Bootnodes?: boolean;
|
|
@@ -721,6 +721,17 @@ export class PeerManager {
|
|
|
721
721
|
// NOTE: libp2p may emit two "peer:connect" events: One for inbound, one for outbound
|
|
722
722
|
// If that happens, it's okay. Only the "outbound" connection triggers immediate action
|
|
723
723
|
const now = Date.now();
|
|
724
|
+
|
|
725
|
+
// Ethereum uses secp256k1 for node IDs, reject peers with other key types
|
|
726
|
+
if (remotePeer.type !== "secp256k1") {
|
|
727
|
+
this.logger.debug("Peer does not have secp256k1 key, disconnecting", {
|
|
728
|
+
peer: remotePeerPrettyStr,
|
|
729
|
+
type: remotePeer.type,
|
|
730
|
+
});
|
|
731
|
+
void this.goodbyeAndDisconnect(remotePeer, GoodByeReasonCode.IRRELEVANT_NETWORK);
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
|
|
724
735
|
const nodeId = computeNodeId(remotePeer);
|
|
725
736
|
const peerData: PeerData = {
|
|
726
737
|
lastReceivedMsgUnixTsMs: direction === "outbound" ? 0 : now,
|
|
@@ -48,6 +48,8 @@ import {
|
|
|
48
48
|
import {IBeaconChain} from "../../chain/interface.js";
|
|
49
49
|
import {validateGossipBlobSidecar} from "../../chain/validation/blobSidecar.js";
|
|
50
50
|
import {validateGossipDataColumnSidecar} from "../../chain/validation/dataColumnSidecar.js";
|
|
51
|
+
import {validateGossipExecutionPayloadBid} from "../../chain/validation/executionPayloadBid.js";
|
|
52
|
+
import {validateGossipExecutionPayloadEnvelope} from "../../chain/validation/executionPayloadEnvelope.js";
|
|
51
53
|
import {
|
|
52
54
|
AggregateAndProofValidationResult,
|
|
53
55
|
GossipAttestation,
|
|
@@ -64,6 +66,7 @@ import {
|
|
|
64
66
|
} from "../../chain/validation/index.js";
|
|
65
67
|
import {validateLightClientFinalityUpdate} from "../../chain/validation/lightClientFinalityUpdate.js";
|
|
66
68
|
import {validateLightClientOptimisticUpdate} from "../../chain/validation/lightClientOptimisticUpdate.js";
|
|
69
|
+
import {validateGossipPayloadAttestationMessage} from "../../chain/validation/payloadAttestationMessage.js";
|
|
67
70
|
import {OpSource} from "../../chain/validatorMonitor.js";
|
|
68
71
|
import {Metrics} from "../../metrics/index.js";
|
|
69
72
|
import {kzgCommitmentToVersionedHash} from "../../util/blobs.js";
|
|
@@ -576,7 +579,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
576
579
|
break;
|
|
577
580
|
}
|
|
578
581
|
|
|
579
|
-
if (!blockInput.
|
|
582
|
+
if (!blockInput.hasComputedAllData()) {
|
|
580
583
|
// immediately attempt fetch of data columns from execution engine
|
|
581
584
|
chain.getBlobsTracker.triggerGetBlobs(blockInput);
|
|
582
585
|
// if we've received at least half of the columns, trigger reconstruction of the rest
|
|
@@ -815,6 +818,51 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
815
818
|
|
|
816
819
|
chain.emitter.emit(routes.events.EventType.blsToExecutionChange, blsToExecutionChange);
|
|
817
820
|
},
|
|
821
|
+
[GossipType.execution_payload]: async ({
|
|
822
|
+
gossipData,
|
|
823
|
+
topic,
|
|
824
|
+
}: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
|
|
825
|
+
const {serializedData} = gossipData;
|
|
826
|
+
const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
|
|
827
|
+
await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
|
|
828
|
+
|
|
829
|
+
// TODO GLOAS: Handle valid envelope. Need an import flow that calls `processExecutionPayloadEnvelope` and fork choice
|
|
830
|
+
},
|
|
831
|
+
[GossipType.payload_attestation_message]: async ({
|
|
832
|
+
gossipData,
|
|
833
|
+
topic,
|
|
834
|
+
}: GossipHandlerParamGeneric<GossipType.payload_attestation_message>) => {
|
|
835
|
+
const {serializedData} = gossipData;
|
|
836
|
+
const payloadAttestationMessage = sszDeserialize(topic, serializedData);
|
|
837
|
+
const validationResult = await validateGossipPayloadAttestationMessage(chain, payloadAttestationMessage);
|
|
838
|
+
|
|
839
|
+
try {
|
|
840
|
+
const insertOutcome = chain.payloadAttestationPool.add(
|
|
841
|
+
payloadAttestationMessage,
|
|
842
|
+
validationResult.attDataRootHex,
|
|
843
|
+
validationResult.validatorCommitteeIndex
|
|
844
|
+
);
|
|
845
|
+
metrics?.opPool.payloadAttestationPool.gossipInsertOutcome.inc({insertOutcome});
|
|
846
|
+
} catch (e) {
|
|
847
|
+
logger.error("Error adding to payloadAttestation pool", {}, e as Error);
|
|
848
|
+
}
|
|
849
|
+
},
|
|
850
|
+
[GossipType.execution_payload_bid]: async ({
|
|
851
|
+
gossipData,
|
|
852
|
+
topic,
|
|
853
|
+
}: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
|
|
854
|
+
const {serializedData} = gossipData;
|
|
855
|
+
const executionPayloadBid = sszDeserialize(topic, serializedData);
|
|
856
|
+
await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
|
|
857
|
+
|
|
858
|
+
// Handle valid payload bid by storing in a bid pool
|
|
859
|
+
try {
|
|
860
|
+
const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid.message);
|
|
861
|
+
metrics?.opPool.executionPayloadBidPool.gossipInsertOutcome.inc({insertOutcome});
|
|
862
|
+
} catch (e) {
|
|
863
|
+
logger.error("Error adding to executionPayloadBid pool", {}, e as Error);
|
|
864
|
+
}
|
|
865
|
+
},
|
|
818
866
|
};
|
|
819
867
|
}
|
|
820
868
|
|
|
@@ -67,6 +67,22 @@ const linearGossipQueueOpts: {
|
|
|
67
67
|
type: QueueType.FIFO,
|
|
68
68
|
dropOpts: {type: DropType.count, count: 1},
|
|
69
69
|
},
|
|
70
|
+
[GossipType.execution_payload]: {
|
|
71
|
+
maxLength: 1024,
|
|
72
|
+
type: QueueType.FIFO,
|
|
73
|
+
dropOpts: {type: DropType.count, count: 1},
|
|
74
|
+
},
|
|
75
|
+
[GossipType.payload_attestation_message]: {
|
|
76
|
+
maxLength: 1024,
|
|
77
|
+
type: QueueType.FIFO,
|
|
78
|
+
dropOpts: {type: DropType.count, count: 1},
|
|
79
|
+
},
|
|
80
|
+
// TODO GLOAS: It is hard to predict how many bids are there. Put 1024 for max length for now
|
|
81
|
+
[GossipType.execution_payload_bid]: {
|
|
82
|
+
maxLength: 1024,
|
|
83
|
+
type: QueueType.FIFO,
|
|
84
|
+
dropOpts: {type: DropType.count, count: 1},
|
|
85
|
+
},
|
|
70
86
|
};
|
|
71
87
|
|
|
72
88
|
const indexedGossipQueueOpts: {
|
|
@@ -78,6 +78,9 @@ const executeGossipWorkOrderObj: Record<GossipType, WorkOpts> = {
|
|
|
78
78
|
[GossipType.sync_committee]: {},
|
|
79
79
|
[GossipType.light_client_finality_update]: {},
|
|
80
80
|
[GossipType.light_client_optimistic_update]: {},
|
|
81
|
+
[GossipType.execution_payload]: {bypassQueue: true},
|
|
82
|
+
[GossipType.payload_attestation_message]: {},
|
|
83
|
+
[GossipType.execution_payload_bid]: {},
|
|
81
84
|
};
|
|
82
85
|
const executeGossipWorkOrder = Object.keys(executeGossipWorkOrderObj) as (keyof typeof executeGossipWorkOrderObj)[];
|
|
83
86
|
|
|
@@ -750,7 +750,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
|
|
|
750
750
|
|
|
751
751
|
// GENESIS_SLOT doesn't has valid signature
|
|
752
752
|
if (anchorBlock.message.slot === GENESIS_SLOT) return;
|
|
753
|
-
await verifyBlockProposerSignature(this.chain.config, this.chain.
|
|
753
|
+
await verifyBlockProposerSignature(this.chain.config, this.chain.bls, [anchorBlock]);
|
|
754
754
|
|
|
755
755
|
// We can write to the disk if this is ahead of prevFinalizedCheckpointBlock otherwise
|
|
756
756
|
// we will need to go make checks on the top of sync loop before writing as it might
|
|
@@ -815,7 +815,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
|
|
|
815
815
|
|
|
816
816
|
// If any of the block's proposer signature fail, we can't trust this peer at all
|
|
817
817
|
if (verifiedBlocks.length > 0) {
|
|
818
|
-
await verifyBlockProposerSignature(this.chain.config, this.chain.
|
|
818
|
+
await verifyBlockProposerSignature(this.chain.config, this.chain.bls, verifiedBlocks);
|
|
819
819
|
|
|
820
820
|
// This is bad, like super bad. Abort the backfill
|
|
821
821
|
if (!nextAnchor)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {GENESIS_SLOT} from "@lodestar/params";
|
|
3
|
-
import {ISignatureSet,
|
|
3
|
+
import {ISignatureSet, getBlockProposerSignatureSet} from "@lodestar/state-transition";
|
|
4
4
|
import {Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
|
|
5
5
|
import {IBlsVerifier} from "../../chain/bls/index.js";
|
|
6
6
|
import {BackfillSyncError, BackfillSyncErrorCode} from "./errors.js";
|
|
@@ -42,14 +42,13 @@ export function verifyBlockSequence(
|
|
|
42
42
|
|
|
43
43
|
export async function verifyBlockProposerSignature(
|
|
44
44
|
config: BeaconConfig,
|
|
45
|
-
index2pubkey: Index2PubkeyCache,
|
|
46
45
|
bls: IBlsVerifier,
|
|
47
46
|
blocks: SignedBeaconBlock[]
|
|
48
47
|
): Promise<void> {
|
|
49
48
|
if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT) return;
|
|
50
49
|
const signatures = blocks.reduce((sigs: ISignatureSet[], block) => {
|
|
51
50
|
// genesis block doesn't have valid signature
|
|
52
|
-
if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(config,
|
|
51
|
+
if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(config, block));
|
|
53
52
|
return sigs;
|
|
54
53
|
}, []);
|
|
55
54
|
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { routes } from "@lodestar/api";
|
|
2
|
-
import { CachedBeaconStateAllForks } from "@lodestar/state-transition";
|
|
3
|
-
import { Epoch, RootHex } from "@lodestar/types";
|
|
4
|
-
import { Metrics } from "../../metrics/index.js";
|
|
5
|
-
import { BlockStateCache } from "./types.js";
|
|
6
|
-
/**
|
|
7
|
-
* Old implementation of StateCache (used to call `StateContextCache`)
|
|
8
|
-
* - Prune per checkpoint so number of states ranges from 96 to 128
|
|
9
|
-
* - Keep a separate head state to make sure it is always available
|
|
10
|
-
*/
|
|
11
|
-
export declare class BlockStateCacheImpl implements BlockStateCache {
|
|
12
|
-
/**
|
|
13
|
-
* Max number of states allowed in the cache
|
|
14
|
-
*/
|
|
15
|
-
readonly maxStates: number;
|
|
16
|
-
private readonly cache;
|
|
17
|
-
/** Epoch -> Set<blockRoot> */
|
|
18
|
-
private readonly epochIndex;
|
|
19
|
-
private readonly metrics;
|
|
20
|
-
/**
|
|
21
|
-
* Strong reference to prevent head state from being pruned.
|
|
22
|
-
* null if head state is being regen and not available at the moment.
|
|
23
|
-
*/
|
|
24
|
-
private head;
|
|
25
|
-
constructor({ maxStates, metrics }: {
|
|
26
|
-
maxStates?: number;
|
|
27
|
-
metrics?: Metrics | null;
|
|
28
|
-
});
|
|
29
|
-
get(rootHex: RootHex): CachedBeaconStateAllForks | null;
|
|
30
|
-
add(item: CachedBeaconStateAllForks): void;
|
|
31
|
-
setHeadState(item: CachedBeaconStateAllForks | null): void;
|
|
32
|
-
/**
|
|
33
|
-
* Get a seed state for state reload.
|
|
34
|
-
* This is to conform to the api only as this cache is not used in n-historical state.
|
|
35
|
-
* See ./fifoBlockStateCache.ts for implementation
|
|
36
|
-
*/
|
|
37
|
-
getSeedState(): CachedBeaconStateAllForks;
|
|
38
|
-
clear(): void;
|
|
39
|
-
get size(): number;
|
|
40
|
-
/**
|
|
41
|
-
* TODO make this more robust.
|
|
42
|
-
* Without more thought, this currently breaks our assumptions about recent state availablity
|
|
43
|
-
*/
|
|
44
|
-
prune(headStateRootHex: RootHex): void;
|
|
45
|
-
/**
|
|
46
|
-
* Prune per finalized epoch.
|
|
47
|
-
*/
|
|
48
|
-
deleteAllBeforeEpoch(finalizedEpoch: Epoch): void;
|
|
49
|
-
/** ONLY FOR DEBUGGING PURPOSES. For lodestar debug API */
|
|
50
|
-
dumpSummary(): routes.lodestar.StateCacheItem[];
|
|
51
|
-
getStates(): IterableIterator<CachedBeaconStateAllForks>;
|
|
52
|
-
private deleteAllEpochItems;
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=blockStateCacheImpl.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blockStateCacheImpl.d.ts","sourceRoot":"","sources":["../../../src/chain/stateCache/blockStateCacheImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAC,OAAO,EAAC,MAAM,wBAAwB,CAAC;AAE/C,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAC;AAI3C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgD;IACtE,8BAA8B;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAuE;gBAEvE,EAAC,SAAsB,EAAE,OAAO,EAAC,EAAE;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;KAAC;IAS7F,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,IAAI;IAavD,GAAG,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI;IAgB1C,YAAY,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI;IAS1D;;;;OAIG;IACH,YAAY,IAAI,yBAAyB;IAIzC,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,EAAE,OAAO,GAAG,IAAI;IAgBtC;;OAEG;IACH,oBAAoB,CAAC,cAAc,EAAE,KAAK,GAAG,IAAI;IAQjD,0DAA0D;IAC1D,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE;IAU/C,SAAS,IAAI,gBAAgB,CAAC,yBAAyB,CAAC;IAIxD,OAAO,CAAC,mBAAmB;CAM5B"}
|