@lodestar/beacon-node 1.47.0-dev.0bcaaaebb5 → 1.47.0-dev.101e2c290d
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 +6 -8
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +25 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -1
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/events/index.d.ts +1 -1
- package/lib/api/impl/events/index.d.ts.map +1 -1
- package/lib/api/impl/events/index.js +12 -3
- package/lib/api/impl/events/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.js +1 -1
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.js +1 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/rest/base.d.ts.map +1 -1
- package/lib/api/rest/base.js +7 -0
- package/lib/api/rest/base.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.js +21 -0
- package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +2 -7
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +3 -2
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +11 -9
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +14 -6
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +2 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +6 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +14 -5
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.js +5 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +22 -12
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/bls/index.d.ts +1 -1
- package/lib/chain/bls/index.d.ts.map +1 -1
- package/lib/chain/bls/interface.d.ts +5 -5
- package/lib/chain/bls/interface.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +5 -11
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +116 -101
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +5 -19
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +10 -65
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/multithread/types.d.ts +29 -8
- package/lib/chain/bls/multithread/types.d.ts.map +1 -1
- package/lib/chain/bls/multithread/types.js +12 -0
- package/lib/chain/bls/multithread/types.js.map +1 -1
- package/lib/chain/bls/multithread/utils.d.ts +4 -0
- package/lib/chain/bls/multithread/utils.d.ts.map +1 -1
- package/lib/chain/bls/multithread/utils.js +10 -0
- package/lib/chain/bls/multithread/utils.js.map +1 -1
- package/lib/chain/bls/multithread/worker.js +49 -23
- package/lib/chain/bls/multithread/worker.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -10
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +8 -45
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +4 -4
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +18 -19
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/builderCircuitBreaker.d.ts +6 -5
- package/lib/chain/builderCircuitBreaker.d.ts.map +1 -1
- package/lib/chain/builderCircuitBreaker.js +28 -15
- package/lib/chain/builderCircuitBreaker.js.map +1 -1
- package/lib/chain/chain.d.ts +4 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +16 -6
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +1 -0
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +6 -1
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +6 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -1
- package/lib/chain/errors/proposerPreferences.js +1 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +4 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -2
- 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/opPools/attestationPool.d.ts +1 -1
- package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/attestationPool.js +1 -1
- package/lib/chain/opPools/attestationPool.js.map +1 -1
- package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts +16 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts.map +1 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.js +57 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.js.map +1 -0
- package/lib/chain/opPools/index.d.ts +1 -0
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js +1 -0
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +3 -3
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +1 -1
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +1 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/options.d.ts +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +24 -6
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +4 -2
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +2 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +2 -2
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +5 -5
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/seenCache/seenAttesters.d.ts +9 -5
- package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
- package/lib/chain/seenCache/seenAttesters.js +25 -4
- package/lib/chain/seenCache/seenAttesters.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +28 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +121 -13
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +5 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +6 -0
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +47 -5
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +117 -7
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +3 -3
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +1 -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 +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.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 +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +5 -14
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -1
- package/lib/chain/validation/proposerPreferences.js +13 -4
- package/lib/chain/validation/proposerPreferences.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/voluntaryExit.d.ts +9 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +46 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/execution/builder/http.d.ts +10 -7
- package/lib/execution/builder/http.d.ts.map +1 -1
- package/lib/execution/builder/http.js +11 -8
- package/lib/execution/builder/http.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +3 -3
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +9 -9
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +72 -22
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +130 -52
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +13 -0
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +37 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +10 -2
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +22 -43
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/constants.d.ts +7 -0
- package/lib/network/processor/constants.d.ts.map +1 -0
- package/lib/network/processor/constants.js +7 -0
- package/lib/network/processor/constants.js.map +1 -0
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +12 -3
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +3 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +36 -15
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +5 -11
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/util.d.ts +0 -1
- package/lib/network/util.d.ts.map +1 -1
- package/lib/network/util.js +0 -4
- package/lib/network/util.js.map +1 -1
- package/lib/node/deferredVoluntaryExitPublisher.d.ts +15 -0
- package/lib/node/deferredVoluntaryExitPublisher.d.ts.map +1 -0
- package/lib/node/deferredVoluntaryExitPublisher.js +38 -0
- package/lib/node/deferredVoluntaryExitPublisher.js.map +1 -0
- package/lib/node/nodejs.d.ts +2 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +2 -0
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/batch.d.ts +23 -5
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +61 -22
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +2 -1
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +23 -10
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/types.d.ts +32 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +33 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +13 -2
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +218 -63
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +16 -11
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +3 -1
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/package.json +35 -35
- package/src/api/impl/beacon/blocks/index.ts +7 -8
- package/src/api/impl/beacon/pool/index.ts +27 -2
- package/src/api/impl/beacon/state/utils.ts +2 -1
- package/src/api/impl/events/index.ts +12 -4
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +1 -1
- package/src/api/rest/base.ts +7 -0
- package/src/chain/archiveStore/archiveStore.ts +1 -1
- package/src/chain/archiveStore/historicalState/metrics.ts +22 -0
- package/src/chain/blocks/importBlock.ts +1 -6
- package/src/chain/blocks/importExecutionPayload.ts +12 -11
- package/src/chain/blocks/index.ts +18 -6
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +8 -2
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +17 -4
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +25 -16
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +1 -9
- package/src/chain/bls/index.ts +1 -1
- package/src/chain/bls/interface.ts +7 -3
- package/src/chain/bls/multithread/index.ts +148 -120
- package/src/chain/bls/multithread/jobItem.ts +12 -82
- package/src/chain/bls/multithread/types.ts +33 -8
- package/src/chain/bls/multithread/utils.ts +11 -0
- package/src/chain/bls/multithread/worker.ts +85 -27
- package/src/chain/bls/singleThread.ts +11 -55
- package/src/chain/bls/utils.ts +23 -24
- package/src/chain/builderCircuitBreaker.ts +31 -17
- package/src/chain/chain.ts +17 -6
- package/src/chain/errors/blockError.ts +8 -2
- package/src/chain/errors/proposerPreferences.ts +7 -0
- package/src/chain/forkChoice/index.ts +4 -0
- package/src/chain/interface.ts +4 -1
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/opPools/attestationPool.ts +1 -1
- package/src/chain/opPools/deferredVoluntaryExitPool.ts +65 -0
- package/src/chain/opPools/index.ts +1 -0
- package/src/chain/opPools/payloadAttestationPool.ts +3 -3
- package/src/chain/opPools/syncCommitteeMessagePool.ts +1 -1
- package/src/chain/opPools/syncContributionAndProofPool.ts +1 -1
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/options.ts +1 -1
- package/src/chain/prepareNextSlot.ts +24 -6
- package/src/chain/regen/interface.ts +4 -2
- package/src/chain/regen/queued.ts +5 -5
- package/src/chain/seenCache/seenAttesters.ts +31 -5
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +143 -14
- package/src/chain/stateCache/fifoBlockStateCache.ts +8 -1
- package/src/chain/stateCache/persistentCheckpointsCache.ts +133 -8
- package/src/chain/stateCache/types.ts +3 -3
- package/src/chain/validation/attestation.ts +1 -7
- package/src/chain/validation/attesterSlashing.ts +1 -8
- package/src/chain/validation/executionPayloadBid.ts +1 -2
- package/src/chain/validation/executionPayloadEnvelope.ts +0 -1
- package/src/chain/validation/payloadAttestationMessage.ts +6 -17
- package/src/chain/validation/proposerPreferences.ts +15 -5
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/voluntaryExit.ts +59 -2
- package/src/execution/builder/http.ts +11 -11
- package/src/metrics/metrics/beacon.ts +9 -9
- package/src/metrics/metrics/lodestar.ts +142 -57
- package/src/network/gossip/topic.ts +38 -0
- package/src/network/libp2p/index.ts +11 -2
- package/src/network/network.ts +27 -55
- package/src/network/processor/constants.ts +6 -0
- package/src/network/processor/gossipHandlers.ts +14 -1
- package/src/network/processor/index.ts +42 -19
- package/src/network/reqresp/score.ts +5 -11
- package/src/network/util.ts +0 -5
- package/src/node/deferredVoluntaryExitPublisher.ts +54 -0
- package/src/node/nodejs.ts +5 -1
- package/src/sync/range/batch.ts +83 -28
- package/src/sync/range/chain.ts +26 -11
- package/src/sync/types.ts +36 -1
- package/src/sync/unknownBlock.ts +255 -70
- package/src/sync/utils/downloadByRange.ts +21 -12
- package/src/sync/utils/downloadByRoot.ts +3 -1
- package/lib/chain/bls/maybeBatch.d.ts +0 -12
- package/lib/chain/bls/maybeBatch.d.ts.map +0 -1
- package/lib/chain/bls/maybeBatch.js +0 -35
- package/lib/chain/bls/maybeBatch.js.map +0 -1
- package/src/chain/bls/maybeBatch.ts +0 -45
package/src/network/network.ts
CHANGED
|
@@ -49,7 +49,12 @@ import {INetworkCore, NetworkCore, WorkerNetworkCore} from "./core/index.js";
|
|
|
49
49
|
import {INetworkEventBus, NetworkEvent, NetworkEventBus, NetworkEventData} from "./events.js";
|
|
50
50
|
import {getActiveForkBoundaries} from "./forks.js";
|
|
51
51
|
import {GossipHandlers, GossipTopicMap, GossipType, GossipTypeMap} from "./gossip/index.js";
|
|
52
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
getGossipSSZType,
|
|
54
|
+
gossipTopicAllowPublishToZeroPeers,
|
|
55
|
+
gossipTopicIgnoreDuplicatePublishError,
|
|
56
|
+
stringifyGossipTopic,
|
|
57
|
+
} from "./gossip/topic.js";
|
|
53
58
|
import {INetwork} from "./interface.js";
|
|
54
59
|
import {NetworkOptions} from "./options.js";
|
|
55
60
|
import {PeerAction, PeerScoreStats} from "./peers/index.js";
|
|
@@ -65,7 +70,7 @@ import {
|
|
|
65
70
|
} from "./reqresp/utils/collect.js";
|
|
66
71
|
import {collectSequentialBlocksInRange} from "./reqresp/utils/collectSequentialBlocksInRange.js";
|
|
67
72
|
import {CommitteeSubscription} from "./subnets/index.js";
|
|
68
|
-
import {isPublishDuplicateError,
|
|
73
|
+
import {isPublishDuplicateError, prettyPrintPeerIdStr} from "./util.js";
|
|
69
74
|
|
|
70
75
|
type NetworkModules = {
|
|
71
76
|
opts: NetworkOptions;
|
|
@@ -352,9 +357,7 @@ export class Network implements INetwork {
|
|
|
352
357
|
const epoch = computeEpochAtSlot(signedBlock.message.slot);
|
|
353
358
|
const boundary = this.config.getForkBoundaryAtEpoch(epoch);
|
|
354
359
|
|
|
355
|
-
return this.publishGossip<GossipType.beacon_block>({type: GossipType.beacon_block, boundary}, signedBlock
|
|
356
|
-
ignoreDuplicatePublishError: true,
|
|
357
|
-
});
|
|
360
|
+
return this.publishGossip<GossipType.beacon_block>({type: GossipType.beacon_block, boundary}, signedBlock);
|
|
358
361
|
}
|
|
359
362
|
|
|
360
363
|
async publishBlobSidecar(blobSidecar: deneb.BlobSidecar): Promise<number> {
|
|
@@ -363,9 +366,7 @@ export class Network implements INetwork {
|
|
|
363
366
|
|
|
364
367
|
const subnet = blobSidecar.index;
|
|
365
368
|
|
|
366
|
-
return this.publishGossip<GossipType.blob_sidecar>({type: GossipType.blob_sidecar, boundary, subnet}, blobSidecar
|
|
367
|
-
ignoreDuplicatePublishError: true,
|
|
368
|
-
});
|
|
369
|
+
return this.publishGossip<GossipType.blob_sidecar>({type: GossipType.blob_sidecar, boundary, subnet}, blobSidecar);
|
|
369
370
|
}
|
|
370
371
|
|
|
371
372
|
async publishDataColumnSidecar(
|
|
@@ -381,14 +382,7 @@ export class Network implements INetwork {
|
|
|
381
382
|
try {
|
|
382
383
|
const sentPeers = await this.publishGossip<GossipType.data_column_sidecar>(
|
|
383
384
|
{type: GossipType.data_column_sidecar, boundary, subnet},
|
|
384
|
-
dataColumnSidecar
|
|
385
|
-
{
|
|
386
|
-
// we ensure having all topic peers via prioritizePeers() function
|
|
387
|
-
// in the worse case, if there is 0 peer on the topic, the overall publish operation could be still a success
|
|
388
|
-
// because supernode will rebuild and publish missing data column sidecars for us
|
|
389
|
-
// hence we want to track sent peers as 0 instead of an error
|
|
390
|
-
allowPublishToZeroTopicPeers: true,
|
|
391
|
-
}
|
|
385
|
+
dataColumnSidecar
|
|
392
386
|
);
|
|
393
387
|
return {sentPeers, alreadyPublished: false};
|
|
394
388
|
} catch (e) {
|
|
@@ -405,8 +399,7 @@ export class Network implements INetwork {
|
|
|
405
399
|
|
|
406
400
|
return this.publishGossip<GossipType.beacon_aggregate_and_proof>(
|
|
407
401
|
{type: GossipType.beacon_aggregate_and_proof, boundary},
|
|
408
|
-
aggregateAndProof
|
|
409
|
-
{ignoreDuplicatePublishError: true}
|
|
402
|
+
aggregateAndProof
|
|
410
403
|
);
|
|
411
404
|
}
|
|
412
405
|
|
|
@@ -416,8 +409,7 @@ export class Network implements INetwork {
|
|
|
416
409
|
|
|
417
410
|
return this.publishGossip<GossipType.beacon_attestation>(
|
|
418
411
|
{type: GossipType.beacon_attestation, boundary, subnet},
|
|
419
|
-
attestation
|
|
420
|
-
{ignoreDuplicatePublishError: true}
|
|
412
|
+
attestation
|
|
421
413
|
);
|
|
422
414
|
}
|
|
423
415
|
|
|
@@ -425,9 +417,7 @@ export class Network implements INetwork {
|
|
|
425
417
|
const epoch = voluntaryExit.message.epoch;
|
|
426
418
|
const boundary = this.config.getForkBoundaryAtEpoch(epoch);
|
|
427
419
|
|
|
428
|
-
return this.publishGossip<GossipType.voluntary_exit>({type: GossipType.voluntary_exit, boundary}, voluntaryExit
|
|
429
|
-
ignoreDuplicatePublishError: true,
|
|
430
|
-
});
|
|
420
|
+
return this.publishGossip<GossipType.voluntary_exit>({type: GossipType.voluntary_exit, boundary}, voluntaryExit);
|
|
431
421
|
}
|
|
432
422
|
|
|
433
423
|
async publishBlsToExecutionChange(blsToExecutionChange: capella.SignedBLSToExecutionChange): Promise<number> {
|
|
@@ -438,8 +428,7 @@ export class Network implements INetwork {
|
|
|
438
428
|
if (fork >= ForkSeq.capella) {
|
|
439
429
|
const publishPromise = this.publishGossip<GossipType.bls_to_execution_change>(
|
|
440
430
|
{type: GossipType.bls_to_execution_change, boundary},
|
|
441
|
-
blsToExecutionChange
|
|
442
|
-
{ignoreDuplicatePublishError: true}
|
|
431
|
+
blsToExecutionChange
|
|
443
432
|
);
|
|
444
433
|
publishChanges.push(publishPromise);
|
|
445
434
|
}
|
|
@@ -457,8 +446,7 @@ export class Network implements INetwork {
|
|
|
457
446
|
|
|
458
447
|
return this.publishGossip<GossipType.proposer_slashing>(
|
|
459
448
|
{type: GossipType.proposer_slashing, boundary},
|
|
460
|
-
proposerSlashing
|
|
461
|
-
{ignoreDuplicatePublishError: true}
|
|
449
|
+
proposerSlashing
|
|
462
450
|
);
|
|
463
451
|
}
|
|
464
452
|
|
|
@@ -478,10 +466,7 @@ export class Network implements INetwork {
|
|
|
478
466
|
|
|
479
467
|
return this.publishGossip<GossipType.sync_committee>(
|
|
480
468
|
{type: GossipType.sync_committee, boundary, subnet},
|
|
481
|
-
signature
|
|
482
|
-
{
|
|
483
|
-
ignoreDuplicatePublishError: true,
|
|
484
|
-
}
|
|
469
|
+
signature
|
|
485
470
|
);
|
|
486
471
|
}
|
|
487
472
|
|
|
@@ -491,8 +476,7 @@ export class Network implements INetwork {
|
|
|
491
476
|
|
|
492
477
|
return this.publishGossip<GossipType.sync_committee_contribution_and_proof>(
|
|
493
478
|
{type: GossipType.sync_committee_contribution_and_proof, boundary},
|
|
494
|
-
contributionAndProof
|
|
495
|
-
{ignoreDuplicatePublishError: true}
|
|
479
|
+
contributionAndProof
|
|
496
480
|
);
|
|
497
481
|
}
|
|
498
482
|
|
|
@@ -522,8 +506,7 @@ export class Network implements INetwork {
|
|
|
522
506
|
|
|
523
507
|
return this.publishGossip<GossipType.execution_payload>(
|
|
524
508
|
{type: GossipType.execution_payload, boundary},
|
|
525
|
-
signedEnvelope
|
|
526
|
-
{ignoreDuplicatePublishError: true}
|
|
509
|
+
signedEnvelope
|
|
527
510
|
);
|
|
528
511
|
}
|
|
529
512
|
|
|
@@ -533,8 +516,7 @@ export class Network implements INetwork {
|
|
|
533
516
|
|
|
534
517
|
return this.publishGossip<GossipType.execution_payload_bid>(
|
|
535
518
|
{type: GossipType.execution_payload_bid, boundary},
|
|
536
|
-
signedBid
|
|
537
|
-
{ignoreDuplicatePublishError: true}
|
|
519
|
+
signedBid
|
|
538
520
|
);
|
|
539
521
|
}
|
|
540
522
|
|
|
@@ -544,8 +526,7 @@ export class Network implements INetwork {
|
|
|
544
526
|
|
|
545
527
|
return this.publishGossip<GossipType.payload_attestation_message>(
|
|
546
528
|
{type: GossipType.payload_attestation_message, boundary},
|
|
547
|
-
payloadAttestationMessage
|
|
548
|
-
{ignoreDuplicatePublishError: true}
|
|
529
|
+
payloadAttestationMessage
|
|
549
530
|
);
|
|
550
531
|
}
|
|
551
532
|
|
|
@@ -555,22 +536,21 @@ export class Network implements INetwork {
|
|
|
555
536
|
|
|
556
537
|
return this.publishGossip<GossipType.proposer_preferences>(
|
|
557
538
|
{type: GossipType.proposer_preferences, boundary},
|
|
558
|
-
signedProposerPreferences
|
|
559
|
-
{ignoreDuplicatePublishError: true}
|
|
539
|
+
signedProposerPreferences
|
|
560
540
|
);
|
|
561
541
|
}
|
|
562
542
|
|
|
563
543
|
private async publishGossip<K extends GossipType>(
|
|
564
544
|
topic: GossipTopicMap[K],
|
|
565
|
-
object: GossipTypeMap[K]
|
|
566
|
-
opts?: PublishOpts | undefined
|
|
545
|
+
object: GossipTypeMap[K]
|
|
567
546
|
): Promise<number> {
|
|
568
547
|
const topicStr = stringifyGossipTopic(this.config, topic);
|
|
569
548
|
const sszType = getGossipSSZType(topic);
|
|
570
549
|
const messageData = (sszType.serialize as (object: GossipTypeMap[GossipType]) => Uint8Array)(object);
|
|
571
|
-
opts = {
|
|
572
|
-
...opts,
|
|
550
|
+
const opts: PublishOpts = {
|
|
573
551
|
ignoreDuplicatePublishError: gossipTopicIgnoreDuplicatePublishError[topic.type],
|
|
552
|
+
// Leave undefined unless the topic opts out, so `--network.allowPublishToZeroPeers` still applies
|
|
553
|
+
allowPublishToZeroTopicPeers: gossipTopicAllowPublishToZeroPeers[topic.type] ? true : undefined,
|
|
574
554
|
};
|
|
575
555
|
const sentPeers = await this.core.publishGossip(topicStr, messageData, opts);
|
|
576
556
|
|
|
@@ -813,11 +793,7 @@ export class Network implements INetwork {
|
|
|
813
793
|
await this.waitForSyncMessageCutoff(finalityUpdate.signatureSlot);
|
|
814
794
|
await this.publishLightClientFinalityUpdate(finalityUpdate);
|
|
815
795
|
} catch (e) {
|
|
816
|
-
|
|
817
|
-
// Remove once https://github.com/ChainSafe/js-libp2p-gossipsub/issues/367
|
|
818
|
-
if (!isPublishToZeroPeersError(e as Error)) {
|
|
819
|
-
this.logger.debug("Error on BeaconGossipHandler.onLightclientFinalityUpdate", {}, e as Error);
|
|
820
|
-
}
|
|
796
|
+
this.logger.debug("Error on BeaconGossipHandler.onLightclientFinalityUpdate", {}, e as Error);
|
|
821
797
|
}
|
|
822
798
|
};
|
|
823
799
|
|
|
@@ -830,11 +806,7 @@ export class Network implements INetwork {
|
|
|
830
806
|
await this.waitForSyncMessageCutoff(optimisticUpdate.signatureSlot);
|
|
831
807
|
await this.publishLightClientOptimisticUpdate(optimisticUpdate);
|
|
832
808
|
} catch (e) {
|
|
833
|
-
|
|
834
|
-
// Remove once https://github.com/ChainSafe/js-libp2p-gossipsub/issues/367
|
|
835
|
-
if (!isPublishToZeroPeersError(e as Error)) {
|
|
836
|
-
this.logger.debug("Error on BeaconGossipHandler.onLightclientOptimisticUpdate", {}, e as Error);
|
|
837
|
-
}
|
|
809
|
+
this.logger.debug("Error on BeaconGossipHandler.onLightclientOptimisticUpdate", {}, e as Error);
|
|
838
810
|
}
|
|
839
811
|
};
|
|
840
812
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Max distinct peers tracked per unknown block/payload root.
|
|
3
|
+
* Normally we have 8 mesh peers per topic, and multi topics may point to the same root.
|
|
4
|
+
* Having 32 peers per root seems enough to search for missing blocks/payloads.
|
|
5
|
+
**/
|
|
6
|
+
export const MAX_PEERS_PER_ROOT = 32;
|
|
@@ -196,7 +196,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
196
196
|
forkName: fork,
|
|
197
197
|
sampledColumns: chain.custodyConfig.sampledColumns,
|
|
198
198
|
custodyColumns: chain.custodyConfig.custodyColumns,
|
|
199
|
-
|
|
199
|
+
seenTimestampSec,
|
|
200
|
+
source: PayloadEnvelopeInputSource.gossip,
|
|
200
201
|
});
|
|
201
202
|
}
|
|
202
203
|
|
|
@@ -640,6 +641,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
640
641
|
metrics?.gossipBlock.elapsedTimeTillProcessed.observe(delaySec);
|
|
641
642
|
|
|
642
643
|
if (isForkPostGloas(blockInput.forkName)) {
|
|
644
|
+
// we should have the payloadInput in the seen cache so no need getOrReload() here
|
|
643
645
|
const payloadInput = chain.seenPayloadEnvelopeInputCache.get(blockInput.blockRootHex);
|
|
644
646
|
// This payloadInput should have been created just after gossip validation
|
|
645
647
|
if (!payloadInput) {
|
|
@@ -1189,6 +1191,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1189
1191
|
chain.validatorMonitor?.registerExecutionPayloadEnvelope(OpSource.gossip, delaySec, signedEnvelope);
|
|
1190
1192
|
|
|
1191
1193
|
const blockRootHex = toRootHex(envelope.beaconBlockRoot);
|
|
1194
|
+
// a gossip payload cannot be `MAX_PAYLOAD_ENVELOPE_INPUT_CACHE_SIZE` slots after the block
|
|
1195
|
+
// otherwise it'll get to UnknownBlockInput flow
|
|
1192
1196
|
const payloadInput = chain.seenPayloadEnvelopeInputCache.get(blockRootHex);
|
|
1193
1197
|
|
|
1194
1198
|
if (!payloadInput) {
|
|
@@ -1255,11 +1259,15 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1255
1259
|
[GossipType.payload_attestation_message]: async ({
|
|
1256
1260
|
gossipData,
|
|
1257
1261
|
topic,
|
|
1262
|
+
seenTimestampSec,
|
|
1258
1263
|
}: GossipHandlerParamGeneric<GossipType.payload_attestation_message>) => {
|
|
1259
1264
|
const {serializedData} = gossipData;
|
|
1260
1265
|
const payloadAttestationMessage = sszDeserialize(topic, serializedData);
|
|
1261
1266
|
const validationResult = await validateGossipPayloadAttestationMessage(chain, payloadAttestationMessage);
|
|
1262
1267
|
|
|
1268
|
+
const delaySec = chain.clock.secFromSlot(payloadAttestationMessage.data.slot, seenTimestampSec);
|
|
1269
|
+
metrics?.gossipPayloadAttestationMessage.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
|
|
1270
|
+
|
|
1263
1271
|
try {
|
|
1264
1272
|
const insertOutcome = chain.payloadAttestationPool.add(
|
|
1265
1273
|
payloadAttestationMessage,
|
|
@@ -1286,11 +1294,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1286
1294
|
[GossipType.execution_payload_bid]: async ({
|
|
1287
1295
|
gossipData,
|
|
1288
1296
|
topic,
|
|
1297
|
+
seenTimestampSec,
|
|
1289
1298
|
}: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
|
|
1290
1299
|
const {serializedData} = gossipData;
|
|
1291
1300
|
const executionPayloadBid = sszDeserialize(topic, serializedData);
|
|
1292
1301
|
const {proposerIndex} = await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
|
|
1293
1302
|
|
|
1303
|
+
// this could be negative, because it's most likely the bid of next slot comes at this clock slot
|
|
1304
|
+
const elapsedSec = chain.clock.secFromSlot(executionPayloadBid.message.slot, seenTimestampSec);
|
|
1305
|
+
metrics?.gossipExecutionPayloadBid.elapsedTimeTillReceived.observe({source: OpSource.gossip}, elapsedSec);
|
|
1306
|
+
|
|
1294
1307
|
// Handle valid payload bid by storing in a bid pool
|
|
1295
1308
|
try {
|
|
1296
1309
|
const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid);
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
GossipValidatorBatchFn,
|
|
31
31
|
GossipValidatorFn,
|
|
32
32
|
} from "../gossip/interface.js";
|
|
33
|
+
import {MAX_PEERS_PER_ROOT} from "./constants.js";
|
|
33
34
|
import {createExtractBlockSlotRootFns} from "./extractSlotRootFns.js";
|
|
34
35
|
import {GossipHandlerOpts, ValidatorFnsModules, getGossipHandlers} from "./gossipHandlers.js";
|
|
35
36
|
import {createGossipQueues} from "./gossipQueues/index.js";
|
|
@@ -191,8 +192,12 @@ export class NetworkProcessor {
|
|
|
191
192
|
// in that case PendingGossipsubMessage needs to be stored in this Map and reprocessed once the payload comes
|
|
192
193
|
private readonly awaitingMessagesByPayloadBlockRoot: MapDef<RootHex, Set<PendingGossipsubMessage>>;
|
|
193
194
|
private awaitingPayloadMessageCount = 0;
|
|
194
|
-
private unknownBlocksBySlot = new MapDef<Slot,
|
|
195
|
-
|
|
195
|
+
private unknownBlocksBySlot = new MapDef<Slot, MapDef<RootHex, Set<PeerIdStr>>>(
|
|
196
|
+
() => new MapDef<RootHex, Set<PeerIdStr>>(() => new Set())
|
|
197
|
+
);
|
|
198
|
+
private unknownEnvelopesBySlot = new MapDef<Slot, MapDef<RootHex, Set<PeerIdStr>>>(
|
|
199
|
+
() => new MapDef<RootHex, Set<PeerIdStr>>(() => new Set())
|
|
200
|
+
);
|
|
196
201
|
|
|
197
202
|
constructor(
|
|
198
203
|
modules: NetworkProcessorModules,
|
|
@@ -271,35 +276,53 @@ export class NetworkProcessor {
|
|
|
271
276
|
* Search block via `ChainEvent.unknownBlockRoot` event
|
|
272
277
|
* Slot is the message slot, which is not necessarily the same as the block's slot, but it can be used for a good prune strategy.
|
|
273
278
|
* In the rare case, if 2 messages on 2 slots search for the same root (for example beacon_attestation) we may emit the same root twice but BlockInputSync should handle it well.
|
|
279
|
+
* We forward every distinct peer that gossiped this root (not just the first) so BlockInputSync can
|
|
280
|
+
* prefer them as by-root download candidates.
|
|
274
281
|
*/
|
|
275
282
|
searchUnknownBlock({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
|
|
276
|
-
if (
|
|
277
|
-
this.chain.seenBlock(root) ||
|
|
278
|
-
this.awaitingMessagesByBlockRoot.has(root) ||
|
|
279
|
-
this.unknownBlocksBySlot.getOrDefault(slot).has(root)
|
|
280
|
-
) {
|
|
283
|
+
if (this.chain.seenBlock(root)) {
|
|
281
284
|
return;
|
|
282
285
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
const peersForRoot = this.unknownBlocksBySlot.getOrDefault(slot);
|
|
287
|
+
const alreadySearching = peersForRoot.has(root) || this.awaitingMessagesByBlockRoot.has(root);
|
|
288
|
+
const forwardedPeers = peersForRoot.getOrDefault(root);
|
|
289
|
+
|
|
290
|
+
// brand-new search always emits (peer may be undefined)
|
|
291
|
+
let shouldEmit = !alreadySearching;
|
|
292
|
+
if (peer !== undefined && !forwardedPeers.has(peer) && forwardedPeers.size < MAX_PEERS_PER_ROOT) {
|
|
293
|
+
// First time we forward THIS peer for THIS root: emit so BlockInputSync accumulates it.
|
|
294
|
+
forwardedPeers.add(peer);
|
|
295
|
+
shouldEmit = true;
|
|
296
|
+
}
|
|
297
|
+
if (shouldEmit) {
|
|
298
|
+
this.chain.emitter.emit(ChainEvent.unknownBlockRoot, {rootHex: root, peer, source});
|
|
299
|
+
}
|
|
286
300
|
}
|
|
287
301
|
|
|
288
302
|
/**
|
|
289
303
|
* Search envelope via `ChainEvent.unknownEnvelopeBlockRoot` event
|
|
290
304
|
* Slot is the message slot, which is not necessarily the same as the envelope's slot, but it can be used for a good prune strategy.
|
|
291
305
|
* In the rare case, if 2 messages on 2 slots search for the same root (for example beacon_attestation) we may emit the same root twice but BlockInputSync should handle it well.
|
|
306
|
+
* Same peer-forwarding + dedup behavior as searchUnknownBlock.
|
|
292
307
|
*/
|
|
293
308
|
searchUnknownEnvelope({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
|
|
294
|
-
if (
|
|
295
|
-
this.chain.seenPayloadEnvelope(root) ||
|
|
296
|
-
this.awaitingMessagesByPayloadBlockRoot.has(root) ||
|
|
297
|
-
this.unknownEnvelopesBySlot.getOrDefault(slot).has(root)
|
|
298
|
-
) {
|
|
309
|
+
if (this.chain.seenPayloadEnvelope(root)) {
|
|
299
310
|
return;
|
|
300
311
|
}
|
|
301
|
-
this.unknownEnvelopesBySlot.getOrDefault(slot)
|
|
302
|
-
|
|
312
|
+
const peersForRoot = this.unknownEnvelopesBySlot.getOrDefault(slot);
|
|
313
|
+
// capture "already searching" BEFORE getOrDefault(root) creates the entry
|
|
314
|
+
const alreadySearching = peersForRoot.has(root) || this.awaitingMessagesByPayloadBlockRoot.has(root);
|
|
315
|
+
const forwardedPeers = peersForRoot.getOrDefault(root);
|
|
316
|
+
|
|
317
|
+
let shouldEmit = !alreadySearching; // brand-new search always emits (peer may be undefined)
|
|
318
|
+
if (peer !== undefined && !forwardedPeers.has(peer) && forwardedPeers.size < MAX_PEERS_PER_ROOT) {
|
|
319
|
+
// First time we forward THIS peer for THIS root: emit so BlockInputSync accumulates it.
|
|
320
|
+
forwardedPeers.add(peer);
|
|
321
|
+
shouldEmit = true;
|
|
322
|
+
}
|
|
323
|
+
if (shouldEmit) {
|
|
324
|
+
this.chain.emitter.emit(ChainEvent.unknownEnvelopeBlockRoot, {rootHex: root, slot, peer, source});
|
|
325
|
+
}
|
|
303
326
|
}
|
|
304
327
|
|
|
305
328
|
private onPendingGossipsubMessage = (message: PendingGossipsubMessage): void => {
|
|
@@ -616,7 +639,7 @@ export class NetworkProcessor {
|
|
|
616
639
|
|
|
617
640
|
for (const [slot, roots] of this.unknownBlocksBySlot) {
|
|
618
641
|
if (slot > minSlot) continue;
|
|
619
|
-
for (const rootHex of roots) {
|
|
642
|
+
for (const rootHex of roots.keys()) {
|
|
620
643
|
const gossipMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
|
|
621
644
|
if (gossipMessages !== undefined) {
|
|
622
645
|
for (const message of gossipMessages) {
|
|
@@ -641,7 +664,7 @@ export class NetworkProcessor {
|
|
|
641
664
|
|
|
642
665
|
for (const [slot, roots] of this.unknownEnvelopesBySlot) {
|
|
643
666
|
if (slot > minSlot) continue;
|
|
644
|
-
for (const rootHex of roots) {
|
|
667
|
+
for (const rootHex of roots.keys()) {
|
|
645
668
|
const gossipMessages = this.awaitingMessagesByPayloadBlockRoot.get(rootHex);
|
|
646
669
|
if (gossipMessages !== undefined) {
|
|
647
670
|
for (const message of gossipMessages) {
|
|
@@ -44,17 +44,11 @@ export function onOutgoingReqRespError(e: RequestError, method: ReqRespMethod):
|
|
|
44
44
|
// failure, so keep the stronger penalty (Fatal for Ping, as before).
|
|
45
45
|
return method === ReqRespMethod.Ping ? PeerAction.Fatal : PeerAction.LowToleranceError;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
case ReqRespMethod.Ping:
|
|
53
|
-
case ReqRespMethod.Status:
|
|
54
|
-
return PeerAction.HighToleranceError;
|
|
55
|
-
default:
|
|
56
|
-
return PeerAction.LowToleranceError;
|
|
57
|
-
}
|
|
47
|
+
// A dial failure means we could not open a stream. That is evidence about the transport, not
|
|
48
|
+
// about the peer's behavior, and it is dominated by transient congestion on our side, so
|
|
49
|
+
// penalize leniently for every method to avoid self-inflicted peer starvation (#9562). A
|
|
50
|
+
// genuinely dead peer still accumulates penalty and is eventually evicted, freeing the slot.
|
|
51
|
+
return PeerAction.HighToleranceError;
|
|
58
52
|
// TODO: Detect SSZDecodeError and return PeerAction.Fatal
|
|
59
53
|
|
|
60
54
|
case RequestErrorCode.RESP_TIMEOUT:
|
package/src/network/util.ts
CHANGED
|
@@ -23,11 +23,6 @@ export function getConnection(libp2p: Libp2p, peerIdStr: string): Connection | u
|
|
|
23
23
|
return getConnectionsMap(libp2p).get(peerIdStr)?.value[0] ?? undefined;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// https://github.com/libp2p/js-libp2p/blob/f87cba928991736d9646b3e054c367f55cab315c/packages/gossipsub/src/gossipsub.ts#L2076
|
|
27
|
-
export function isPublishToZeroPeersError(e: Error): boolean {
|
|
28
|
-
return e.message.includes("PublishError.NoPeersSubscribedToTopic");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
26
|
// https://github.com/libp2p/js-libp2p/blob/f87cba928991736d9646b3e054c367f55cab315c/packages/gossipsub/src/gossipsub.ts#L2076
|
|
32
27
|
export function isPublishDuplicateError(e: Error): boolean {
|
|
33
28
|
return e.message.includes("PublishError.Duplicate");
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {routes} from "@lodestar/api";
|
|
2
|
+
import {Logger} from "@lodestar/utils";
|
|
3
|
+
import {IBeaconChain} from "../chain/index.js";
|
|
4
|
+
import {INetwork} from "../network/index.js";
|
|
5
|
+
import {ClockEvent} from "../util/clock.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* On every epoch, drain the deferred voluntary exit pool and publish the exits that have become
|
|
9
|
+
* processable. Lives at the node layer rather than inside `BeaconChain` because publishing needs
|
|
10
|
+
* `network`, which the chain does not (and should not) depend on.
|
|
11
|
+
*/
|
|
12
|
+
export function startDeferredVoluntaryExitPublisher({
|
|
13
|
+
chain,
|
|
14
|
+
network,
|
|
15
|
+
logger,
|
|
16
|
+
signal,
|
|
17
|
+
}: {
|
|
18
|
+
chain: IBeaconChain;
|
|
19
|
+
network: INetwork;
|
|
20
|
+
logger: Logger;
|
|
21
|
+
signal: AbortSignal;
|
|
22
|
+
}): void {
|
|
23
|
+
const onEpoch = async (): Promise<void> => {
|
|
24
|
+
try {
|
|
25
|
+
// Use the cached head state directly rather than getHeadStateAtCurrentEpoch, which would regen
|
|
26
|
+
// the head forward to the current epoch. At init from a stale db-finalized state that regen can
|
|
27
|
+
// be many epoch transitions. The head state is fine here: this is a best-effort drain that
|
|
28
|
+
// re-runs every epoch, so a just-processable exit is republished next tick.
|
|
29
|
+
const state = chain.getHeadState();
|
|
30
|
+
const exits = chain.deferredVoluntaryExitPool.drainProcessableExits(state);
|
|
31
|
+
for (const exit of exits) {
|
|
32
|
+
try {
|
|
33
|
+
chain.opPool.insertVoluntaryExit(exit);
|
|
34
|
+
chain.emitter.emit(routes.events.EventType.voluntaryExit, exit);
|
|
35
|
+
await network.publishVoluntaryExit(exit);
|
|
36
|
+
logger.info("Voluntary exit successfully published for validator", {
|
|
37
|
+
validatorIndex: exit.message.validatorIndex,
|
|
38
|
+
});
|
|
39
|
+
} catch (e) {
|
|
40
|
+
logger.warn(
|
|
41
|
+
"Failed to publish deferred voluntary exit",
|
|
42
|
+
{validatorIndex: exit.message.validatorIndex},
|
|
43
|
+
e as Error
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
logger.warn("Failed to drain deferred voluntary exit pool", {}, e as Error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
chain.clock.addListener(ClockEvent.epoch, onEpoch);
|
|
53
|
+
signal.addEventListener("abort", () => chain.clock.removeListener(ClockEvent.epoch, onEpoch), {once: true});
|
|
54
|
+
}
|
package/src/node/nodejs.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {setMaxListeners} from "node:events";
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {Registry} from "prom-client";
|
|
4
|
+
import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
|
|
4
5
|
import {hasher} from "@chainsafe/persistent-merkle-tree";
|
|
5
6
|
import {BeaconApiMethods} from "@lodestar/api/beacon/server";
|
|
6
7
|
import {BeaconConfig} from "@lodestar/config";
|
|
7
8
|
import type {LoggerNode} from "@lodestar/logger/node";
|
|
8
9
|
import {ZERO_HASH_HEX} from "@lodestar/params";
|
|
9
|
-
import {IBeaconStateView,
|
|
10
|
+
import {IBeaconStateView, isStatePostBellatrix, isStatePostGloas} from "@lodestar/state-transition";
|
|
10
11
|
import {phase0} from "@lodestar/types";
|
|
11
12
|
import {sleep, toRootHex} from "@lodestar/utils";
|
|
12
13
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
@@ -21,6 +22,7 @@ import {Network, getReqRespHandlers} from "../network/index.js";
|
|
|
21
22
|
import {BackfillSync} from "../sync/backfill/index.js";
|
|
22
23
|
import {BeaconSync, IBeaconSync} from "../sync/index.js";
|
|
23
24
|
import {Clock} from "../util/clock.js";
|
|
25
|
+
import {startDeferredVoluntaryExitPublisher} from "./deferredVoluntaryExitPublisher.js";
|
|
24
26
|
import {runNodeNotifier} from "./notifier.js";
|
|
25
27
|
import {IBeaconNodeOptions} from "./options.js";
|
|
26
28
|
|
|
@@ -334,6 +336,8 @@ export class BeaconNode {
|
|
|
334
336
|
|
|
335
337
|
void runNodeNotifier({network, chain, sync, config, logger, signal});
|
|
336
338
|
|
|
339
|
+
startDeferredVoluntaryExitPublisher({chain, network, logger, signal});
|
|
340
|
+
|
|
337
341
|
return new BeaconNode({
|
|
338
342
|
opts,
|
|
339
343
|
config,
|