@lodestar/beacon-node 1.41.0-dev.e1d339886d → 1.41.0-dev.e6c853da0e
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 +123 -4
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.js +8 -8
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +3 -4
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js +5 -24
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +6 -2
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/node/utils.d.ts +1 -1
- package/lib/api/impl/node/utils.d.ts.map +1 -1
- package/lib/api/impl/node/utils.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +130 -16
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +9 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +5 -6
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +9 -10
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +3 -3
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +3 -8
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
- package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
- package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
- package/lib/chain/archiveStore/utils/updateBackfillRange.js +1 -1
- package/lib/chain/archiveStore/utils/updateBackfillRange.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +20 -2
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +47 -0
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/blockInput/types.d.ts +13 -1
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/types.js +1 -0
- package/lib/chain/blocks/blockInput/types.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +27 -4
- 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 +2 -1
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.js +3 -0
- package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +4 -0
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +4 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts +12 -3
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +101 -96
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +3 -3
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +5 -5
- 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 -4
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +4 -4
- 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 +7 -4
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +7 -10
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +43 -27
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +5 -5
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +30 -24
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -6
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +3 -3
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +10 -2
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +24 -2
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +22 -7
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +109 -10
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +4 -1
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +6 -2
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +15 -7
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +1 -1
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +7 -4
- 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 +9 -2
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/blobSidecar.js +2 -2
- 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 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts +2 -2
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +1 -1
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +1 -2
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +4 -4
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +9 -3
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
- package/lib/db/beacon.d.ts +3 -1
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +5 -1
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +3 -1
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +2 -0
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +3 -1
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.js +1 -2
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
- package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.js +14 -1
- package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
- package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
- package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
- package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
- package/lib/db/repositories/index.d.ts +2 -0
- package/lib/db/repositories/index.d.ts.map +1 -1
- package/lib/db/repositories/index.js +2 -0
- package/lib/db/repositories/index.js.map +1 -1
- package/lib/execution/engine/http.d.ts +1 -0
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +3 -0
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +1 -0
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +5 -0
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +8 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +14 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/monitoring/service.d.ts +2 -2
- package/lib/monitoring/service.d.ts.map +1 -1
- package/lib/monitoring/service.js +3 -2
- package/lib/monitoring/service.js.map +1 -1
- package/lib/network/core/networkCore.d.ts +3 -3
- package/lib/network/core/networkCore.d.ts.map +1 -1
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -3
- package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
- package/lib/network/core/types.d.ts +2 -2
- package/lib/network/core/types.d.ts.map +1 -1
- package/lib/network/events.d.ts +2 -1
- package/lib/network/events.d.ts.map +1 -1
- package/lib/network/events.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts +3 -3
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts +13 -4
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +47 -20
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +6 -6
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.d.ts +1 -1
- package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.js +1 -1
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +113 -63
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +2 -2
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +6 -5
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/libp2p/index.d.ts +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +7 -2
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts +5 -4
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +10 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js +3 -0
- package/lib/network/options.js.map +1 -1
- package/lib/network/peers/datastore.d.ts +7 -5
- package/lib/network/peers/datastore.d.ts.map +1 -1
- package/lib/network/peers/datastore.js +10 -10
- package/lib/network/peers/datastore.js.map +1 -1
- package/lib/network/peers/peerManager.d.ts +3 -0
- package/lib/network/peers/peerManager.d.ts.map +1 -1
- package/lib/network/peers/peerManager.js +103 -53
- package/lib/network/peers/peerManager.js.map +1 -1
- package/lib/network/peers/utils/prioritizePeers.d.ts +3 -3
- package/lib/network/peers/utils/prioritizePeers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +9 -2
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipValidatorFn.js +1 -1
- package/lib/network/processor/types.d.ts +1 -1
- package/lib/network/processor/types.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +3 -2
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +3 -2
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +1 -1
- 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 +3 -2
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +0 -1
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/util.js +2 -2
- package/lib/network/util.js.map +1 -1
- package/lib/node/nodejs.d.ts +3 -5
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +6 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/util/blobs.d.ts +2 -2
- package/lib/util/blobs.d.ts.map +1 -1
- package/lib/util/blobs.js.map +1 -1
- package/lib/util/clock.d.ts +6 -0
- package/lib/util/clock.d.ts.map +1 -1
- package/lib/util/clock.js +9 -3
- package/lib/util/clock.js.map +1 -1
- package/lib/util/dataColumns.d.ts +11 -3
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +27 -0
- package/lib/util/dataColumns.js.map +1 -1
- package/lib/util/multifork.d.ts +8 -0
- package/lib/util/multifork.d.ts.map +1 -1
- package/lib/util/multifork.js +37 -0
- package/lib/util/multifork.js.map +1 -1
- package/package.json +39 -42
- package/src/api/impl/beacon/blocks/index.ts +147 -3
- package/src/api/impl/beacon/state/index.ts +8 -8
- package/src/api/impl/beacon/state/utils.ts +15 -29
- package/src/api/impl/debug/index.ts +9 -5
- package/src/api/impl/node/utils.ts +3 -3
- package/src/api/impl/validator/index.ts +153 -17
- package/src/chain/archiveStore/archiveStore.ts +15 -5
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
- package/src/chain/archiveStore/historicalState/worker.ts +3 -3
- package/src/chain/archiveStore/utils/archiveBlocks.ts +4 -5
- package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
- package/src/chain/archiveStore/utils/updateBackfillRange.ts +1 -1
- package/src/chain/blocks/blockInput/blockInput.ts +68 -3
- package/src/chain/blocks/blockInput/types.ts +13 -0
- package/src/chain/blocks/importBlock.ts +35 -4
- package/src/chain/blocks/index.ts +2 -1
- package/src/chain/blocks/verifyBlocksDataAvailability.ts +3 -0
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +7 -2
- package/src/chain/blocks/writeBlockInputToDb.ts +119 -101
- package/src/chain/bls/multithread/index.ts +7 -7
- package/src/chain/bls/multithread/jobItem.ts +3 -3
- package/src/chain/bls/singleThread.ts +5 -5
- package/src/chain/bls/utils.ts +8 -5
- package/src/chain/chain.ts +77 -40
- package/src/chain/emitter.ts +5 -5
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
- package/src/chain/forkChoice/index.ts +39 -21
- package/src/chain/interface.ts +4 -11
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/options.ts +1 -0
- package/src/chain/prepareNextSlot.ts +5 -5
- package/src/chain/produceBlock/computeNewStateRoot.ts +35 -3
- package/src/chain/produceBlock/produceBlockBody.ts +162 -13
- package/src/chain/regen/queued.ts +7 -2
- package/src/chain/regen/regen.ts +9 -3
- package/src/chain/seenCache/seenGossipBlockInput.ts +16 -7
- package/src/chain/validation/aggregateAndProof.ts +1 -1
- package/src/chain/validation/attestation.ts +7 -4
- package/src/chain/validation/attesterSlashing.ts +10 -1
- package/src/chain/validation/blobSidecar.ts +2 -2
- package/src/chain/validation/block.ts +9 -4
- package/src/chain/validation/dataColumnSidecar.ts +3 -6
- package/src/chain/validation/executionPayloadBid.ts +1 -2
- package/src/chain/validation/executionPayloadEnvelope.ts +4 -4
- package/src/chain/validation/payloadAttestationMessage.ts +10 -3
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +1 -1
- package/src/db/beacon.ts +8 -0
- package/src/db/buckets.ts +3 -0
- package/src/db/interface.ts +5 -0
- package/src/db/repositories/blockArchive.ts +1 -2
- package/src/db/repositories/dataColumnSidecar.ts +18 -3
- package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
- package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
- package/src/db/repositories/index.ts +2 -0
- package/src/execution/engine/http.ts +3 -0
- package/src/metrics/metrics/beacon.ts +5 -0
- package/src/metrics/metrics/lodestar.ts +14 -0
- package/src/monitoring/service.ts +3 -2
- package/src/network/core/networkCore.ts +3 -3
- package/src/network/core/networkCoreWorkerHandler.ts +3 -3
- package/src/network/core/types.ts +2 -2
- package/src/network/events.ts +2 -1
- package/src/network/gossip/encoding.ts +3 -3
- package/src/network/gossip/gossipsub.ts +86 -25
- package/src/network/gossip/interface.ts +6 -6
- package/src/network/gossip/scoringParameters.ts +4 -4
- package/src/network/gossip/topic.ts +2 -1
- package/src/network/interface.ts +7 -4
- package/src/network/libp2p/index.ts +8 -3
- package/src/network/network.ts +24 -6
- package/src/network/options.ts +3 -0
- package/src/network/peers/datastore.ts +13 -10
- package/src/network/peers/peerManager.ts +118 -54
- package/src/network/peers/utils/prioritizePeers.ts +3 -3
- package/src/network/processor/gossipHandlers.ts +19 -4
- package/src/network/processor/gossipValidatorFn.ts +1 -1
- package/src/network/processor/types.ts +1 -1
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +3 -2
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +3 -2
- package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +1 -1
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +3 -2
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
- package/src/network/reqresp/score.ts +0 -1
- package/src/network/util.ts +2 -2
- package/src/node/nodejs.ts +8 -9
- package/src/util/blobs.ts +3 -3
- package/src/util/clock.ts +9 -4
- package/src/util/dataColumns.ts +37 -1
- package/src/util/multifork.ts +45 -0
- package/src/util/workerEvents.ts +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
PeerScoreParams,
|
|
3
|
-
PeerScoreThresholds,
|
|
4
|
-
TopicScoreParams,
|
|
2
|
+
type PeerScoreParams,
|
|
3
|
+
type PeerScoreThresholds,
|
|
4
|
+
type TopicScoreParams,
|
|
5
5
|
defaultTopicScoreParams,
|
|
6
|
-
} from "@
|
|
6
|
+
} from "@libp2p/gossipsub/score";
|
|
7
7
|
import {BeaconConfig} from "@lodestar/config";
|
|
8
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";
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
SYNC_COMMITTEE_SUBNET_COUNT,
|
|
7
7
|
isForkPostAltair,
|
|
8
8
|
isForkPostElectra,
|
|
9
|
+
isForkPostFulu,
|
|
9
10
|
} from "@lodestar/params";
|
|
10
11
|
import {Attestation, SingleAttestation, ssz, sszTypesFor} from "@lodestar/types";
|
|
11
12
|
import {GossipAction, GossipActionError, GossipErrorCode} from "../../chain/errors/gossipValidation.js";
|
|
@@ -92,7 +93,7 @@ export function getGossipSSZType(topic: GossipTopic) {
|
|
|
92
93
|
case GossipType.blob_sidecar:
|
|
93
94
|
return ssz.deneb.BlobSidecar;
|
|
94
95
|
case GossipType.data_column_sidecar:
|
|
95
|
-
return ssz.fulu.DataColumnSidecar;
|
|
96
|
+
return isForkPostFulu(fork) ? sszTypesFor(fork).DataColumnSidecar : ssz.fulu.DataColumnSidecar;
|
|
96
97
|
case GossipType.beacon_aggregate_and_proof:
|
|
97
98
|
return sszTypesFor(fork).SignedAggregateAndProof;
|
|
98
99
|
case GossipType.beacon_attestation:
|
package/src/network/interface.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {Identify} from "@libp2p/identify";
|
|
2
|
-
import {
|
|
1
|
+
import type {Identify} from "@libp2p/identify";
|
|
2
|
+
import type {
|
|
3
3
|
ComponentLogger,
|
|
4
4
|
ConnectionGater,
|
|
5
5
|
ConnectionProtector,
|
|
@@ -16,9 +16,10 @@ import {
|
|
|
16
16
|
} from "@libp2p/interface";
|
|
17
17
|
import type {AddressManager, ConnectionManager, Registrar, TransportManager} from "@libp2p/interface-internal";
|
|
18
18
|
import type {Datastore} from "interface-datastore";
|
|
19
|
-
import {Libp2p as ILibp2p} from "libp2p";
|
|
19
|
+
import type {Libp2p as ILibp2p} from "libp2p";
|
|
20
20
|
import {
|
|
21
21
|
AttesterSlashing,
|
|
22
|
+
DataColumnSidecar,
|
|
22
23
|
LightClientFinalityUpdate,
|
|
23
24
|
LightClientOptimisticUpdate,
|
|
24
25
|
SignedAggregateAndProof,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
capella,
|
|
32
33
|
deneb,
|
|
33
34
|
fulu,
|
|
35
|
+
gloas,
|
|
34
36
|
phase0,
|
|
35
37
|
} from "@lodestar/types";
|
|
36
38
|
import {BlockInputSource} from "../chain/blocks/blockInput/types.js";
|
|
@@ -86,7 +88,7 @@ export interface INetwork extends INetworkCorePublic {
|
|
|
86
88
|
publishBlobSidecar(blobSidecar: deneb.BlobSidecar): Promise<number>;
|
|
87
89
|
publishBeaconAggregateAndProof(aggregateAndProof: SignedAggregateAndProof): Promise<number>;
|
|
88
90
|
publishBeaconAttestation(attestation: SingleAttestation, subnet: SubnetID): Promise<number>;
|
|
89
|
-
publishDataColumnSidecar(dataColumnSideCar:
|
|
91
|
+
publishDataColumnSidecar(dataColumnSideCar: DataColumnSidecar): Promise<number>;
|
|
90
92
|
publishVoluntaryExit(voluntaryExit: phase0.SignedVoluntaryExit): Promise<number>;
|
|
91
93
|
publishBlsToExecutionChange(blsToExecutionChange: capella.SignedBLSToExecutionChange): Promise<number>;
|
|
92
94
|
publishProposerSlashing(proposerSlashing: phase0.ProposerSlashing): Promise<number>;
|
|
@@ -95,6 +97,7 @@ export interface INetwork extends INetworkCorePublic {
|
|
|
95
97
|
publishContributionAndProof(contributionAndProof: altair.SignedContributionAndProof): Promise<number>;
|
|
96
98
|
publishLightClientFinalityUpdate(update: LightClientFinalityUpdate): Promise<number>;
|
|
97
99
|
publishLightClientOptimisticUpdate(update: LightClientOptimisticUpdate): Promise<number>;
|
|
100
|
+
publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number>;
|
|
98
101
|
|
|
99
102
|
// Debug
|
|
100
103
|
dumpGossipQueue(gossipType: GossipType): Promise<PendingGossipsubMessage[]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {bootstrap} from "@libp2p/bootstrap";
|
|
2
2
|
import {identify} from "@libp2p/identify";
|
|
3
|
-
import {PrivateKey} from "@libp2p/interface";
|
|
3
|
+
import type {PrivateKey} from "@libp2p/interface";
|
|
4
4
|
import {mdns} from "@libp2p/mdns";
|
|
5
5
|
import {mplex} from "@libp2p/mplex";
|
|
6
6
|
import {prometheusMetrics} from "@libp2p/prometheus-metrics";
|
|
@@ -39,6 +39,7 @@ export async function createNodeJsLibp2p(
|
|
|
39
39
|
nodeJsLibp2pOpts: NodeJsLibp2pOpts = {}
|
|
40
40
|
): Promise<Libp2p> {
|
|
41
41
|
const localMultiaddrs = networkOpts.localMultiaddrs || defaultNetworkOptions.localMultiaddrs;
|
|
42
|
+
const disconnectThreshold = networkOpts.disconnectThreshold ?? defaultNetworkOptions.disconnectThreshold;
|
|
42
43
|
const {peerStoreDir, disablePeerDiscovery} = nodeJsLibp2pOpts;
|
|
43
44
|
|
|
44
45
|
let datastore: undefined | Eth2PeerDataStore = undefined;
|
|
@@ -74,6 +75,11 @@ export async function createNodeJsLibp2p(
|
|
|
74
75
|
|
|
75
76
|
return createLibp2p({
|
|
76
77
|
privateKey,
|
|
78
|
+
nodeInfo: {
|
|
79
|
+
name: "lodestar",
|
|
80
|
+
version: networkOpts.version ?? "unknown",
|
|
81
|
+
userAgent: networkOpts.private ? "" : networkOpts.version ? `lodestar/${networkOpts.version}` : "lodestar",
|
|
82
|
+
},
|
|
77
83
|
addresses: {
|
|
78
84
|
listen: localMultiaddrs,
|
|
79
85
|
announce: [],
|
|
@@ -93,7 +99,7 @@ export async function createNodeJsLibp2p(
|
|
|
93
99
|
},
|
|
94
100
|
}),
|
|
95
101
|
],
|
|
96
|
-
streamMuxers: [mplex({
|
|
102
|
+
streamMuxers: [mplex({disconnectThreshold})],
|
|
97
103
|
peerDiscovery,
|
|
98
104
|
metrics: nodeJsLibp2pOpts.metrics
|
|
99
105
|
? prometheusMetrics({
|
|
@@ -124,7 +130,6 @@ export async function createNodeJsLibp2p(
|
|
|
124
130
|
datastore,
|
|
125
131
|
services: {
|
|
126
132
|
identify: identify({
|
|
127
|
-
agentVersion: networkOpts.private ? "" : networkOpts.version ? `lodestar/${networkOpts.version}` : "lodestar",
|
|
128
133
|
runOnConnectionOpen: false,
|
|
129
134
|
}),
|
|
130
135
|
// individual components are specified because the components object is a Proxy
|
package/src/network/network.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {PeerScoreStatsDump} from "@libp2p/gossipsub/score";
|
|
2
|
+
import type {PublishOpts} from "@libp2p/gossipsub/types";
|
|
3
|
+
import type {PeerId, PrivateKey} from "@libp2p/interface";
|
|
2
4
|
import {peerIdFromPrivateKey} from "@libp2p/peer-id";
|
|
3
|
-
import {PeerScoreStatsDump} from "@chainsafe/libp2p-gossipsub/score";
|
|
4
|
-
import {PublishOpts} from "@chainsafe/libp2p-gossipsub/types";
|
|
5
5
|
import {routes} from "@lodestar/api";
|
|
6
6
|
import {BeaconConfig} from "@lodestar/config";
|
|
7
7
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
@@ -10,6 +10,8 @@ import {ResponseIncoming} from "@lodestar/reqresp";
|
|
|
10
10
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
11
11
|
import {
|
|
12
12
|
AttesterSlashing,
|
|
13
|
+
DataColumnSidecar,
|
|
14
|
+
DataColumnSidecars,
|
|
13
15
|
LightClientBootstrap,
|
|
14
16
|
LightClientFinalityUpdate,
|
|
15
17
|
LightClientOptimisticUpdate,
|
|
@@ -24,6 +26,8 @@ import {
|
|
|
24
26
|
capella,
|
|
25
27
|
deneb,
|
|
26
28
|
fulu,
|
|
29
|
+
gloas,
|
|
30
|
+
isGloasDataColumnSidecar,
|
|
27
31
|
phase0,
|
|
28
32
|
} from "@lodestar/types";
|
|
29
33
|
import {prettyPrintIndices, sleep} from "@lodestar/utils";
|
|
@@ -354,8 +358,11 @@ export class Network implements INetwork {
|
|
|
354
358
|
});
|
|
355
359
|
}
|
|
356
360
|
|
|
357
|
-
async publishDataColumnSidecar(dataColumnSidecar:
|
|
358
|
-
const
|
|
361
|
+
async publishDataColumnSidecar(dataColumnSidecar: DataColumnSidecar): Promise<number> {
|
|
362
|
+
const slot = isGloasDataColumnSidecar(dataColumnSidecar)
|
|
363
|
+
? dataColumnSidecar.slot
|
|
364
|
+
: dataColumnSidecar.signedBlockHeader.message.slot;
|
|
365
|
+
const epoch = computeEpochAtSlot(slot);
|
|
359
366
|
const boundary = this.config.getForkBoundaryAtEpoch(epoch);
|
|
360
367
|
|
|
361
368
|
const subnet = computeSubnetForDataColumnSidecar(this.config, dataColumnSidecar);
|
|
@@ -489,6 +496,17 @@ export class Network implements INetwork {
|
|
|
489
496
|
);
|
|
490
497
|
}
|
|
491
498
|
|
|
499
|
+
async publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number> {
|
|
500
|
+
const epoch = computeEpochAtSlot(signedEnvelope.message.slot);
|
|
501
|
+
const boundary = this.config.getForkBoundaryAtEpoch(epoch);
|
|
502
|
+
|
|
503
|
+
return this.publishGossip<GossipType.execution_payload>(
|
|
504
|
+
{type: GossipType.execution_payload, boundary},
|
|
505
|
+
signedEnvelope,
|
|
506
|
+
{ignoreDuplicatePublishError: true}
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
492
510
|
private async publishGossip<K extends GossipType>(
|
|
493
511
|
topic: GossipTopicMap[K],
|
|
494
512
|
object: GossipTypeMap[K],
|
|
@@ -765,7 +783,7 @@ export class Network implements INetwork {
|
|
|
765
783
|
this.core.setTargetGroupCount(count);
|
|
766
784
|
};
|
|
767
785
|
|
|
768
|
-
private onPublishDataColumns = (sidecars:
|
|
786
|
+
private onPublishDataColumns = (sidecars: DataColumnSidecars): Promise<number[]> => {
|
|
769
787
|
return promiseAllMaybeAsync(sidecars.map((sidecar) => () => this.publishDataColumnSidecar(sidecar)));
|
|
770
788
|
};
|
|
771
789
|
|
package/src/network/options.ts
CHANGED
|
@@ -72,4 +72,7 @@ export const defaultNetworkOptions: NetworkOptions = {
|
|
|
72
72
|
// - for fusaka-devnets, we have 25-30 peers per subnet
|
|
73
73
|
// - for public testnets or mainnet, average number of peers per group is SAMPLES_PER_SLOT * targetPeers / NUMBER_OF_CUSTODY_GROUPS = 6.25 so this should not be an issue
|
|
74
74
|
targetGroupPeers: 6,
|
|
75
|
+
// Keep this high enough for normal req/resp bursts on stable connections.
|
|
76
|
+
// libp2p-mplex default (5) is too low and can cause frequent connection resets.
|
|
77
|
+
disconnectThreshold: 50,
|
|
75
78
|
};
|
|
@@ -8,6 +8,9 @@ type MemoryItem = {
|
|
|
8
8
|
data: Uint8Array;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
// biome-ignore lint/suspicious/noExplicitAny: used below (copied from upstream)
|
|
12
|
+
type AwaitGenerator<T, TReturn = any, TNext = any> = Generator<T, TReturn, TNext> | AsyncGenerator<T, TReturn, TNext>;
|
|
13
|
+
|
|
11
14
|
/**
|
|
12
15
|
* Before libp2p 0.35, peerstore stays in memory and periodically write to db after n dirty items
|
|
13
16
|
* This has a memory issue because all peer data stays in memory and loaded at startup time
|
|
@@ -93,7 +96,7 @@ export class Eth2PeerDataStore extends BaseDatastore {
|
|
|
93
96
|
* This throws error if not found
|
|
94
97
|
* see https://github.com/ipfs/js-datastore-level/blob/38f44058dd6be858e757a1c90b8edb31590ec0bc/src/index.js#L102
|
|
95
98
|
*/
|
|
96
|
-
async get(key: Key): Promise<Uint8Array> {
|
|
99
|
+
async get(key: Key, options?: AbortOptions): Promise<Uint8Array> {
|
|
97
100
|
const keyStr = key.toString();
|
|
98
101
|
const memoryItem = this._memoryDatastore.get(keyStr);
|
|
99
102
|
if (memoryItem) {
|
|
@@ -102,16 +105,16 @@ export class Eth2PeerDataStore extends BaseDatastore {
|
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
// this throws error if not found
|
|
105
|
-
const dbValue = await this._dbDatastore.get(key);
|
|
108
|
+
const dbValue = await this._dbDatastore.get(key, options);
|
|
106
109
|
// don't call this._memoryDatastore.set directly
|
|
107
110
|
// we want to get through prune() logic with fromDb as true
|
|
108
111
|
await this._put(key, dbValue, true);
|
|
109
112
|
return dbValue;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
async has(key: Key): Promise<boolean> {
|
|
115
|
+
async has(key: Key, options?: AbortOptions): Promise<boolean> {
|
|
113
116
|
try {
|
|
114
|
-
await this.get(key);
|
|
117
|
+
await this.get(key, options);
|
|
115
118
|
} catch (err) {
|
|
116
119
|
// this is the same to how js-datastore-level handles notFound error
|
|
117
120
|
// https://github.com/ipfs/js-datastore-level/blob/38f44058dd6be858e757a1c90b8edb31590ec0bc/src/index.js#L121
|
|
@@ -121,26 +124,26 @@ export class Eth2PeerDataStore extends BaseDatastore {
|
|
|
121
124
|
return true;
|
|
122
125
|
}
|
|
123
126
|
|
|
124
|
-
async delete(key: Key): Promise<void> {
|
|
127
|
+
async delete(key: Key, options?: AbortOptions): Promise<void> {
|
|
125
128
|
this._memoryDatastore.delete(key.toString());
|
|
126
|
-
await this._dbDatastore.delete(key);
|
|
129
|
+
await this._dbDatastore.delete(key, options);
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
async *_all(q: Query):
|
|
132
|
+
async *_all(q: Query, options?: AbortOptions): AwaitGenerator<Pair> {
|
|
130
133
|
for (const [key, value] of this._memoryDatastore.entries()) {
|
|
131
134
|
yield {
|
|
132
135
|
key: new Key(key),
|
|
133
136
|
value: value.data,
|
|
134
137
|
};
|
|
135
138
|
}
|
|
136
|
-
yield* this._dbDatastore.query(q);
|
|
139
|
+
yield* this._dbDatastore.query(q, options);
|
|
137
140
|
}
|
|
138
141
|
|
|
139
|
-
async *_allKeys(q: KeyQuery):
|
|
142
|
+
async *_allKeys(q: KeyQuery, options?: AbortOptions): AwaitGenerator<Key> {
|
|
140
143
|
for (const key of this._memoryDatastore.keys()) {
|
|
141
144
|
yield new Key(key);
|
|
142
145
|
}
|
|
143
|
-
yield* this._dbDatastore.queryKeys(q);
|
|
146
|
+
yield* this._dbDatastore.queryKeys(q, options);
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
private async _addDirtyItem(keyStr: string): Promise<void> {
|
|
@@ -9,6 +9,7 @@ import {prettyPrintIndices, toHex, withTimeout} from "@lodestar/utils";
|
|
|
9
9
|
import {GOODBYE_KNOWN_CODES, GoodByeReasonCode, Libp2pEvent} from "../../constants/index.js";
|
|
10
10
|
import {IClock} from "../../util/clock.js";
|
|
11
11
|
import {computeColumnsForCustodyGroup, getCustodyGroups} from "../../util/dataColumns.js";
|
|
12
|
+
import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
12
13
|
import {NetworkCoreMetrics} from "../core/metrics.js";
|
|
13
14
|
import {LodestarDiscv5Opts} from "../discv5/types.js";
|
|
14
15
|
import {INetworkEventBus, NetworkEvent, NetworkEventData} from "../events.js";
|
|
@@ -161,7 +162,6 @@ export class PeerManager {
|
|
|
161
162
|
|
|
162
163
|
// A single map of connected peers with all necessary data to handle PINGs, STATUS, and metrics
|
|
163
164
|
private connectedPeers: Map<PeerIdStr, PeerData>;
|
|
164
|
-
|
|
165
165
|
private opts: PeerManagerOpts;
|
|
166
166
|
private intervals: NodeJS.Timeout[] = [];
|
|
167
167
|
|
|
@@ -196,6 +196,13 @@ export class PeerManager {
|
|
|
196
196
|
|
|
197
197
|
this.lastStatus = this.statusCache.get();
|
|
198
198
|
|
|
199
|
+
// A connection may already be open before listeners are attached.
|
|
200
|
+
// Seed those peers so they are tracked in connectedPeers immediately.
|
|
201
|
+
this.bootstrapAlreadyOpenConnections();
|
|
202
|
+
// Defer status/ping to the next event loop tick so the heartbeat interval and
|
|
203
|
+
// event listeners are fully registered before we begin handshakes.
|
|
204
|
+
callInNextEventLoop(() => this.pingAndStatusTimeouts());
|
|
205
|
+
|
|
199
206
|
// On start-up will connected to existing peers in libp2p.peerStore, same as autoDial behaviour
|
|
200
207
|
this.heartbeat();
|
|
201
208
|
this.intervals = [
|
|
@@ -472,6 +479,14 @@ export class PeerManager {
|
|
|
472
479
|
clientAgent,
|
|
473
480
|
custodyColumns,
|
|
474
481
|
});
|
|
482
|
+
|
|
483
|
+
// Identify peer after status proves the connection is usable.
|
|
484
|
+
// This is the only place we trigger identify — avoids wasted streams on
|
|
485
|
+
// peers that close identify right after connection open or turn out to be
|
|
486
|
+
// irrelevant.
|
|
487
|
+
if (peerData?.agentVersion === null) {
|
|
488
|
+
void this.identifyPeer(peer.toString(), prettyPrintPeerId(peer), getConnection(this.libp2p, peer.toString()));
|
|
489
|
+
}
|
|
475
490
|
}
|
|
476
491
|
}
|
|
477
492
|
|
|
@@ -692,36 +707,39 @@ export class PeerManager {
|
|
|
692
707
|
}
|
|
693
708
|
}
|
|
694
709
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
710
|
+
private bootstrapAlreadyOpenConnections(): void {
|
|
711
|
+
let bootstrapped = 0;
|
|
712
|
+
|
|
713
|
+
for (const {value: connections} of getConnectionsMap(this.libp2p).values()) {
|
|
714
|
+
for (const connection of connections) {
|
|
715
|
+
// trackLibp2pConnection handles deduplication via overwriteExisting: false
|
|
716
|
+
if (this.trackLibp2pConnection(connection, {overwriteExisting: false, triggerHandshakeNow: false})) {
|
|
717
|
+
bootstrapped++;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (bootstrapped > 0) {
|
|
723
|
+
this.logger.verbose("Bootstrapped already-open libp2p peers", {bootstrapped});
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
private trackLibp2pConnection(
|
|
728
|
+
connection: Connection,
|
|
729
|
+
opts: {overwriteExisting: boolean; triggerHandshakeNow: boolean}
|
|
730
|
+
): boolean {
|
|
731
|
+
const {direction, status, remotePeer} = connection;
|
|
704
732
|
const remotePeerStr = remotePeer.toString();
|
|
705
733
|
const remotePeerPrettyStr = prettyPrintPeerId(remotePeer);
|
|
706
|
-
this.logger.verbose("peer connected", {peer: remotePeerPrettyStr, direction, status});
|
|
707
|
-
// NOTE: The peerConnect event is not emitted here here, but after asserting peer relevance
|
|
708
|
-
this.metrics?.peerConnectedEvent.inc({direction, status});
|
|
709
734
|
|
|
710
|
-
if (
|
|
735
|
+
if (status !== "open") {
|
|
711
736
|
this.logger.debug("Peer disconnected before identify protocol initiated", {
|
|
712
737
|
peerId: remotePeerPrettyStr,
|
|
713
|
-
status
|
|
738
|
+
status,
|
|
714
739
|
});
|
|
715
|
-
return;
|
|
740
|
+
return false;
|
|
716
741
|
}
|
|
717
742
|
|
|
718
|
-
// On connection:
|
|
719
|
-
// - Outbound connections: send a STATUS and PING request
|
|
720
|
-
// - Inbound connections: expect to be STATUS'd, schedule STATUS and PING for latter
|
|
721
|
-
// NOTE: libp2p may emit two "peer:connect" events: One for inbound, one for outbound
|
|
722
|
-
// If that happens, it's okay. Only the "outbound" connection triggers immediate action
|
|
723
|
-
const now = Date.now();
|
|
724
|
-
|
|
725
743
|
// Ethereum uses secp256k1 for node IDs, reject peers with other key types
|
|
726
744
|
if (remotePeer.type !== "secp256k1") {
|
|
727
745
|
this.logger.debug("Peer does not have secp256k1 key, disconnecting", {
|
|
@@ -729,52 +747,64 @@ export class PeerManager {
|
|
|
729
747
|
type: remotePeer.type,
|
|
730
748
|
});
|
|
731
749
|
void this.goodbyeAndDisconnect(remotePeer, GoodByeReasonCode.IRRELEVANT_NETWORK);
|
|
732
|
-
return;
|
|
750
|
+
return false;
|
|
733
751
|
}
|
|
734
752
|
|
|
753
|
+
if (!opts.overwriteExisting && this.connectedPeers.has(remotePeerStr)) {
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// On connection:
|
|
758
|
+
// - Outbound connections: send a STATUS and PING request
|
|
759
|
+
// - Inbound connections: expect to be STATUS'd, schedule STATUS and PING for later
|
|
760
|
+
// NOTE: libp2p may emit two "peer:connect" events: One for inbound, one for outbound
|
|
761
|
+
// If that happens, it's okay. Only the "outbound" connection triggers immediate action
|
|
762
|
+
const now = Date.now();
|
|
763
|
+
const existingPeerData = this.connectedPeers.get(remotePeerStr);
|
|
735
764
|
const nodeId = computeNodeId(remotePeer);
|
|
736
765
|
const peerData: PeerData = {
|
|
737
|
-
|
|
766
|
+
// Keep existing timestamps if this peer already had another open connection.
|
|
767
|
+
// libp2p may emit multiple connection:open events per peer.
|
|
768
|
+
lastReceivedMsgUnixTsMs: existingPeerData?.lastReceivedMsgUnixTsMs ?? (direction === "outbound" ? 0 : now),
|
|
738
769
|
// If inbound, request after STATUS_INBOUND_GRACE_PERIOD
|
|
739
|
-
lastStatusUnixTsMs:
|
|
740
|
-
|
|
741
|
-
|
|
770
|
+
lastStatusUnixTsMs:
|
|
771
|
+
existingPeerData?.lastStatusUnixTsMs ??
|
|
772
|
+
(direction === "outbound" ? 0 : now - STATUS_INTERVAL_MS + STATUS_INBOUND_GRACE_PERIOD),
|
|
773
|
+
connectedUnixTsMs: existingPeerData?.connectedUnixTsMs ?? now,
|
|
774
|
+
relevantStatus: existingPeerData?.relevantStatus ?? RelevantPeerStatus.Unknown,
|
|
742
775
|
direction,
|
|
743
776
|
nodeId,
|
|
744
777
|
peerId: remotePeer,
|
|
745
|
-
status: null,
|
|
746
|
-
metadata: null,
|
|
747
|
-
agentVersion: null,
|
|
748
|
-
agentClient: null,
|
|
749
|
-
encodingPreference: null,
|
|
778
|
+
status: existingPeerData?.status ?? null,
|
|
779
|
+
metadata: existingPeerData?.metadata ?? null,
|
|
780
|
+
agentVersion: existingPeerData?.agentVersion ?? null,
|
|
781
|
+
agentClient: existingPeerData?.agentClient ?? null,
|
|
782
|
+
encodingPreference: existingPeerData?.encodingPreference ?? null,
|
|
750
783
|
};
|
|
751
784
|
this.connectedPeers.set(remotePeerStr, peerData);
|
|
752
785
|
|
|
753
|
-
if (direction === "outbound") {
|
|
754
|
-
// this.pingAndStatusTimeouts();
|
|
786
|
+
if (direction === "outbound" && opts.triggerHandshakeNow) {
|
|
755
787
|
void this.requestPing(remotePeer);
|
|
756
788
|
void this.requestStatus(remotePeer, this.statusCache.get());
|
|
757
789
|
}
|
|
758
790
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
});
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* The libp2p Upgrader has successfully upgraded a peer connection on a particular multiaddress
|
|
796
|
+
* This event is routed through the connectionManager
|
|
797
|
+
*
|
|
798
|
+
* Registers a peer as connected. The `direction` parameter determines if the peer is being
|
|
799
|
+
* dialed or connecting to us.
|
|
800
|
+
*/
|
|
801
|
+
private onLibp2pPeerConnect = (evt: CustomEvent<Connection>): void => {
|
|
802
|
+
const {direction, status, remotePeer} = evt.detail;
|
|
803
|
+
this.logger.verbose("peer connected", {peer: prettyPrintPeerId(remotePeer), direction, status});
|
|
804
|
+
// NOTE: The peerConnect event is not emitted here here, but after asserting peer relevance
|
|
805
|
+
this.metrics?.peerConnectedEvent.inc({direction, status});
|
|
806
|
+
|
|
807
|
+
this.trackLibp2pConnection(evt.detail, {overwriteExisting: true, triggerHandshakeNow: true});
|
|
778
808
|
};
|
|
779
809
|
|
|
780
810
|
/**
|
|
@@ -784,6 +814,19 @@ export class PeerManager {
|
|
|
784
814
|
const {direction, status, remotePeer} = evt.detail;
|
|
785
815
|
const peerIdStr = remotePeer.toString();
|
|
786
816
|
|
|
817
|
+
const openConnections =
|
|
818
|
+
getConnectionsMap(this.libp2p)
|
|
819
|
+
.get(peerIdStr)
|
|
820
|
+
?.value.filter((connection) => connection.status === "open") ?? [];
|
|
821
|
+
if (openConnections.length > 0) {
|
|
822
|
+
this.logger.debug("Ignoring peer disconnect event while another connection is still open", {
|
|
823
|
+
peerId: prettyPrintPeerIdStr(peerIdStr),
|
|
824
|
+
direction,
|
|
825
|
+
status,
|
|
826
|
+
});
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
|
|
787
830
|
let logMessage = "onLibp2pPeerDisconnect";
|
|
788
831
|
const logContext: Record<string, string | number> = {
|
|
789
832
|
peerId: prettyPrintPeerIdStr(peerIdStr),
|
|
@@ -818,6 +861,27 @@ export class PeerManager {
|
|
|
818
861
|
}
|
|
819
862
|
}
|
|
820
863
|
|
|
864
|
+
private async identifyPeer(peerIdStr: string, peerIdPretty: string, connection?: Connection): Promise<void> {
|
|
865
|
+
if (!connection || connection.status !== "open") {
|
|
866
|
+
this.logger.debug("Peer has no open connection for identify", {peerId: peerIdPretty});
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
try {
|
|
871
|
+
const result = await this.libp2p.services.identify.identify(connection);
|
|
872
|
+
const agentVersion = result.agentVersion;
|
|
873
|
+
if (agentVersion) {
|
|
874
|
+
const connectedPeerData = this.connectedPeers.get(peerIdStr);
|
|
875
|
+
if (connectedPeerData) {
|
|
876
|
+
connectedPeerData.agentVersion = agentVersion;
|
|
877
|
+
connectedPeerData.agentClient = getKnownClientFromAgentVersion(agentVersion);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
} catch (e) {
|
|
881
|
+
this.logger.debug("Error setting agentVersion for the peer", {peerId: peerIdPretty}, e as Error);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
821
885
|
private async goodbyeAndDisconnect(peer: PeerId, goodbye: GoodByeReasonCode): Promise<void> {
|
|
822
886
|
const reason = GOODBYE_KNOWN_CODES[goodbye.toString()] || "";
|
|
823
887
|
const peerIdStr = peer.toString();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {MessageStreamDirection, PeerId} from "@libp2p/interface";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {ChainConfig} from "@lodestar/config";
|
|
4
4
|
import {ATTESTATION_SUBNET_COUNT, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
|
|
@@ -95,7 +95,7 @@ function computeStatusScore(ours: Status, theirs: Status | null, opts: Prioritiz
|
|
|
95
95
|
|
|
96
96
|
type PeerInfo = {
|
|
97
97
|
id: PeerId;
|
|
98
|
-
direction:
|
|
98
|
+
direction: MessageStreamDirection | null;
|
|
99
99
|
statusScore: StatusScore;
|
|
100
100
|
attnets: phase0.AttestationSubnets;
|
|
101
101
|
syncnets: altair.SyncSubnets;
|
|
@@ -137,7 +137,7 @@ export enum ExcessPeerDisconnectReason {
|
|
|
137
137
|
export function prioritizePeers(
|
|
138
138
|
connectedPeersInfo: {
|
|
139
139
|
id: PeerId;
|
|
140
|
-
direction:
|
|
140
|
+
direction: MessageStreamDirection | null;
|
|
141
141
|
status: Status | null;
|
|
142
142
|
attnets: phase0.AttestationSubnets | null;
|
|
143
143
|
syncnets: altair.SyncSubnets | null;
|
|
@@ -2,6 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
|
|
3
3
|
import {
|
|
4
4
|
ForkName,
|
|
5
|
+
ForkPostDeneb,
|
|
5
6
|
ForkPostElectra,
|
|
6
7
|
ForkPreElectra,
|
|
7
8
|
ForkSeq,
|
|
@@ -70,6 +71,7 @@ import {validateGossipPayloadAttestationMessage} from "../../chain/validation/pa
|
|
|
70
71
|
import {OpSource} from "../../chain/validatorMonitor.js";
|
|
71
72
|
import {Metrics} from "../../metrics/index.js";
|
|
72
73
|
import {kzgCommitmentToVersionedHash} from "../../util/blobs.js";
|
|
74
|
+
import {getBlobKzgCommitments} from "../../util/dataColumns.ts";
|
|
73
75
|
import {INetworkCore} from "../core/index.js";
|
|
74
76
|
import {NetworkEventBus} from "../events.js";
|
|
75
77
|
import {
|
|
@@ -417,9 +419,11 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
417
419
|
chain.getBlobsTracker.triggerGetBlobs(blockInput);
|
|
418
420
|
} else {
|
|
419
421
|
metrics?.blockInputFetchStats.totalDataAvailableBlockInputs.inc();
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
422
|
+
const blobCount = getBlobKzgCommitments(
|
|
423
|
+
blockInput.forkName,
|
|
424
|
+
signedBlock as SignedBeaconBlock<ForkPostDeneb>
|
|
425
|
+
).length;
|
|
426
|
+
metrics?.blockInputFetchStats.totalDataAvailableBlockInputBlobs.inc(blobCount);
|
|
423
427
|
}
|
|
424
428
|
|
|
425
429
|
chain
|
|
@@ -548,7 +552,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
548
552
|
seenTimestampSec,
|
|
549
553
|
}: GossipHandlerParamGeneric<GossipType.data_column_sidecar>) => {
|
|
550
554
|
const {serializedData} = gossipData;
|
|
551
|
-
|
|
555
|
+
// TODO GLOAS: handle gloas.DataColumnSidecar
|
|
556
|
+
const dataColumnSidecar = sszDeserialize(topic, serializedData) as fulu.DataColumnSidecar;
|
|
552
557
|
const dataColumnSlot = dataColumnSidecar.signedBlockHeader.message.slot;
|
|
553
558
|
const index = dataColumnSidecar.index;
|
|
554
559
|
|
|
@@ -821,11 +826,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
821
826
|
[GossipType.execution_payload]: async ({
|
|
822
827
|
gossipData,
|
|
823
828
|
topic,
|
|
829
|
+
seenTimestampSec,
|
|
824
830
|
}: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
|
|
825
831
|
const {serializedData} = gossipData;
|
|
826
832
|
const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
|
|
827
833
|
await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
|
|
828
834
|
|
|
835
|
+
const slot = executionPayloadEnvelope.message.slot;
|
|
836
|
+
const delaySec = seenTimestampSec - computeTimeAtSlot(config, slot, chain.genesisTime);
|
|
837
|
+
metrics?.gossipExecutionPayloadEnvelope.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
|
|
838
|
+
|
|
829
839
|
// TODO GLOAS: Handle valid envelope. Need an import flow that calls `processExecutionPayloadEnvelope` and fork choice
|
|
830
840
|
},
|
|
831
841
|
[GossipType.payload_attestation_message]: async ({
|
|
@@ -846,6 +856,11 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
846
856
|
} catch (e) {
|
|
847
857
|
logger.error("Error adding to payloadAttestation pool", {}, e as Error);
|
|
848
858
|
}
|
|
859
|
+
chain.forkChoice.notifyPtcMessages(
|
|
860
|
+
toRootHex(payloadAttestationMessage.data.beaconBlockRoot),
|
|
861
|
+
[validationResult.validatorCommitteeIndex],
|
|
862
|
+
payloadAttestationMessage.data.payloadPresent
|
|
863
|
+
);
|
|
849
864
|
},
|
|
850
865
|
[GossipType.execution_payload_bid]: async ({
|
|
851
866
|
gossipData,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {TopicValidatorResult} from "@libp2p/
|
|
1
|
+
import {TopicValidatorResult} from "@libp2p/gossipsub";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
3
|
import {Logger} from "@lodestar/utils";
|
|
4
4
|
import {AttestationError, GossipAction, GossipActionError} from "../../chain/errors/index.js";
|
|
@@ -47,9 +47,10 @@ export async function* onBeaconBlocksByRange(
|
|
|
47
47
|
|
|
48
48
|
// Non-finalized range of blocks
|
|
49
49
|
if (endSlot > finalizedSlot) {
|
|
50
|
-
const
|
|
50
|
+
const headBlock = chain.forkChoice.getHead();
|
|
51
|
+
const headRoot = headBlock.blockRoot;
|
|
51
52
|
// TODO DENEB: forkChoice should mantain an array of canonical blocks, and change only on reorg
|
|
52
|
-
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot);
|
|
53
|
+
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
|
|
53
54
|
// getAllAncestorBlocks response includes the head node, so it's the full chain.
|
|
54
55
|
|
|
55
56
|
// Iterate head chain with ascending block numbers
|
|
@@ -34,9 +34,10 @@ export async function* onBlobSidecarsByRange(
|
|
|
34
34
|
|
|
35
35
|
// Non-finalized range of blobs
|
|
36
36
|
if (endSlot > finalizedSlot) {
|
|
37
|
-
const
|
|
37
|
+
const headBlock = chain.forkChoice.getHead();
|
|
38
|
+
const headRoot = headBlock.blockRoot;
|
|
38
39
|
// TODO DENEB: forkChoice should mantain an array of canonical blocks, and change only on reorg
|
|
39
|
-
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot);
|
|
40
|
+
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
|
|
40
41
|
|
|
41
42
|
// Iterate head chain with ascending block numbers
|
|
42
43
|
for (let i = headChain.length - 1; i >= 0; i--) {
|