@lodestar/beacon-node 1.41.0-dev.4a2801bf60 → 1.41.0-dev.4e115ed25d
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 +121 -3
- 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 +104 -6
- 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/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/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 +2 -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/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/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 +6 -9
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +32 -16
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +2 -2
- package/lib/chain/emitter.d.ts.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/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 +110 -10
- package/lib/chain/produceBlock/produceBlockBody.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/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +4 -1
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.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.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +8 -1
- 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 +29 -9
- 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 +8 -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/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/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 +38 -41
- package/src/api/impl/beacon/blocks/index.ts +145 -2
- 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 +127 -5
- package/src/chain/archiveStore/archiveStore.ts +10 -0
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
- package/src/chain/archiveStore/historicalState/worker.ts +3 -3
- package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
- package/src/chain/blocks/blockInput/blockInput.ts +68 -3
- package/src/chain/blocks/blockInput/types.ts +1 -0
- package/src/chain/blocks/verifyBlocksDataAvailability.ts +3 -0
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
- 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 +51 -26
- package/src/chain/emitter.ts +2 -2
- package/src/chain/interface.ts +4 -11
- 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 +163 -13
- package/src/chain/seenCache/seenGossipBlockInput.ts +16 -7
- package/src/chain/validation/attestation.ts +4 -1
- package/src/chain/validation/attesterSlashing.ts +1 -1
- package/src/chain/validation/dataColumnSidecar.ts +2 -5
- package/src/chain/validation/payloadAttestationMessage.ts +9 -1
- 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 +33 -10
- 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 +14 -4
- package/src/network/processor/gossipValidatorFn.ts +1 -1
- package/src/network/processor/types.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/dataColumns.ts +37 -1
- package/src/util/multifork.ts +45 -0
- package/src/util/workerEvents.ts +1 -1
|
@@ -144,6 +144,11 @@ export function createBeaconMetrics(register: RegistryMetricCreator) {
|
|
|
144
144
|
help: "Time for preparing payload in advance",
|
|
145
145
|
buckets: [0.1, 1, 3, 5, 10],
|
|
146
146
|
}),
|
|
147
|
+
executionPayloadEnvelopeProcessingTime: register.histogram({
|
|
148
|
+
name: "beacon_block_payload_envelope_processing_seconds",
|
|
149
|
+
help: "Time to process execution payload envelope during block production",
|
|
150
|
+
buckets: [0.005, 0.01, 0.05, 0.1, 0.2, 0.5, 1],
|
|
151
|
+
}),
|
|
147
152
|
payloadFetchedTime: register.histogram<{prepType: PayloadPreparationType}>({
|
|
148
153
|
name: "beacon_block_payload_fetched_time",
|
|
149
154
|
help: "Time to fetch the payload from EL",
|
|
@@ -827,6 +827,15 @@ export function createLodestarMetrics(
|
|
|
827
827
|
help: "Total number of blobs retrieved from execution engine and published to gossip",
|
|
828
828
|
}),
|
|
829
829
|
},
|
|
830
|
+
// Gossip execution payload envelope
|
|
831
|
+
gossipExecutionPayloadEnvelope: {
|
|
832
|
+
elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
|
|
833
|
+
name: "lodestar_gossip_execution_payload_envelope_elapsed_time_till_received",
|
|
834
|
+
help: "Time elapsed between slot time and the time execution payload envelope received",
|
|
835
|
+
labelNames: ["source"],
|
|
836
|
+
buckets: [0.5, 1, 2, 4, 6, 12],
|
|
837
|
+
}),
|
|
838
|
+
},
|
|
830
839
|
recoverDataColumnSidecars: {
|
|
831
840
|
recoverTime: register.histogram({
|
|
832
841
|
name: "lodestar_recover_data_column_sidecar_recover_time_seconds",
|
|
@@ -919,6 +928,11 @@ export function createLodestarMetrics(
|
|
|
919
928
|
help: "The total result of calling notifyNewPayload execution engine api",
|
|
920
929
|
labelNames: ["result"],
|
|
921
930
|
}),
|
|
931
|
+
engineNotifyForkchoiceUpdateResult: register.gauge<{result: ExecutionPayloadStatus}>({
|
|
932
|
+
name: "lodestar_execution_engine_notify_forkchoice_update_result_total",
|
|
933
|
+
help: "The total result of calling notifyForkchoiceUpdate execution engine api",
|
|
934
|
+
labelNames: ["result"],
|
|
935
|
+
}),
|
|
922
936
|
backfillSync: {
|
|
923
937
|
backfilledTillSlot: register.gauge({
|
|
924
938
|
name: "lodestar_backfill_till_slot",
|
|
@@ -89,9 +89,9 @@ export class MonitoringService {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Stop sending client stats
|
|
92
|
+
* Stop sending client stats and wait for any pending request to complete
|
|
93
93
|
*/
|
|
94
|
-
close(): void {
|
|
94
|
+
async close(): Promise<void> {
|
|
95
95
|
if (this.status === Status.Closed) return;
|
|
96
96
|
this.status = Status.Closed;
|
|
97
97
|
|
|
@@ -103,6 +103,7 @@ export class MonitoringService {
|
|
|
103
103
|
}
|
|
104
104
|
if (this.pendingRequest) {
|
|
105
105
|
this.fetchAbortController?.abort(FetchAbortReason.Close);
|
|
106
|
+
await this.pendingRequest;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {PeerScoreStatsDump} from "@libp2p/gossipsub/score";
|
|
2
|
+
import type {PublishOpts} from "@libp2p/gossipsub/types";
|
|
3
|
+
import type {Connection, PrivateKey} from "@libp2p/interface";
|
|
2
4
|
import {peerIdFromPrivateKey} from "@libp2p/peer-id";
|
|
3
5
|
import {multiaddr} from "@multiformats/multiaddr";
|
|
4
|
-
import {PeerScoreStatsDump} from "@chainsafe/libp2p-gossipsub/score";
|
|
5
|
-
import {PublishOpts} from "@chainsafe/libp2p-gossipsub/types";
|
|
6
6
|
import {routes} from "@lodestar/api";
|
|
7
7
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
8
8
|
import type {LoggerNode} from "@lodestar/logger/node";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import workerThreads from "node:worker_threads";
|
|
3
3
|
import {privateKeyToProtobuf} from "@libp2p/crypto/keys";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import type {PeerScoreStatsDump} from "@libp2p/gossipsub/score";
|
|
5
|
+
import type {PublishOpts} from "@libp2p/gossipsub/types";
|
|
6
|
+
import type {PrivateKey} from "@libp2p/interface";
|
|
7
7
|
import {ModuleThread, Thread, Worker, spawn} from "@chainsafe/threads";
|
|
8
8
|
import {routes} from "@lodestar/api";
|
|
9
9
|
import {BeaconConfig, chainConfigToJson} from "@lodestar/config";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {PeerScoreStatsDump} from "@
|
|
2
|
-
import {PublishOpts} from "@
|
|
1
|
+
import type {PeerScoreStatsDump} from "@libp2p/gossipsub/score";
|
|
2
|
+
import type {PublishOpts} from "@libp2p/gossipsub/types";
|
|
3
3
|
import {routes} from "@lodestar/api";
|
|
4
4
|
import {SpecJson} from "@lodestar/config";
|
|
5
5
|
import {LoggerNodeOpts} from "@lodestar/logger/node";
|
package/src/network/events.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {EventEmitter} from "node:events";
|
|
2
|
-
import {
|
|
2
|
+
import type {TopicValidatorResult} from "@libp2p/gossipsub";
|
|
3
|
+
import type {PeerId} from "@libp2p/interface";
|
|
3
4
|
import {CustodyIndex, Status} from "@lodestar/types";
|
|
4
5
|
import {PeerIdStr} from "../util/peerId.js";
|
|
5
6
|
import {StrictEventEmitterSingleArg} from "../util/strictEvents.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {Message} from "@libp2p/
|
|
1
|
+
import type {Message} from "@libp2p/gossipsub";
|
|
2
|
+
import type {RPC} from "@libp2p/gossipsub/message";
|
|
3
|
+
import type {DataTransform} from "@libp2p/gossipsub/types";
|
|
2
4
|
// snappyjs is better for compression for smaller payloads
|
|
3
5
|
import xxhashFactory from "xxhash-wasm";
|
|
4
6
|
import {digest} from "@chainsafe/as-sha256";
|
|
5
|
-
import {RPC} from "@chainsafe/libp2p-gossipsub/message";
|
|
6
|
-
import {DataTransform} from "@chainsafe/libp2p-gossipsub/types";
|
|
7
7
|
import snappyWasm from "@chainsafe/snappy-wasm";
|
|
8
8
|
import {ForkName} from "@lodestar/params";
|
|
9
9
|
import {intToBytes} from "@lodestar/utils";
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type GossipSub,
|
|
3
|
+
type GossipSubEvents,
|
|
4
|
+
type PublishResult,
|
|
5
|
+
StrictNoSign,
|
|
6
|
+
type TopicValidatorResult,
|
|
7
|
+
gossipsub,
|
|
8
|
+
} from "@libp2p/gossipsub";
|
|
9
|
+
import type {MetricsRegister, TopicLabel, TopicStrToLabel} from "@libp2p/gossipsub/metrics";
|
|
10
|
+
import type {PeerScoreParams, PeerScoreStatsDump} from "@libp2p/gossipsub/score";
|
|
11
|
+
import type {AddrInfo, PublishOpts, TopicStr} from "@libp2p/gossipsub/types";
|
|
12
|
+
import type {PeerId} from "@libp2p/interface";
|
|
1
13
|
import {peerIdFromString} from "@libp2p/peer-id";
|
|
2
14
|
import {multiaddr} from "@multiformats/multiaddr";
|
|
3
15
|
import {ENR} from "@chainsafe/enr";
|
|
4
|
-
import {GossipSub, GossipsubEvents} from "@chainsafe/libp2p-gossipsub";
|
|
5
|
-
import {MetricsRegister, TopicLabel, TopicStrToLabel} from "@chainsafe/libp2p-gossipsub/metrics";
|
|
6
|
-
import {PeerScoreParams} from "@chainsafe/libp2p-gossipsub/score";
|
|
7
|
-
import {AddrInfo, SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
|
|
8
16
|
import {routes} from "@lodestar/api";
|
|
9
17
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
10
18
|
import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
|
|
@@ -69,6 +77,24 @@ export type Eth2GossipsubOpts = {
|
|
|
69
77
|
|
|
70
78
|
export type ForkBoundaryLabel = string;
|
|
71
79
|
|
|
80
|
+
// Many of the internal properties we need are not available on the public interface,
|
|
81
|
+
// so we create an extended type here to avoid excessive type assertions throughout the codebase.
|
|
82
|
+
// Mind that any updates to the gossipsub package may require updates to this type.
|
|
83
|
+
type GossipSubInternal = GossipSub & {
|
|
84
|
+
mesh: Map<string, Set<string>>;
|
|
85
|
+
peers: Map<string, PeerId>;
|
|
86
|
+
score: {score: (peerIdStr: string) => number};
|
|
87
|
+
direct: Set<string>;
|
|
88
|
+
topics: Map<string, Set<string>>;
|
|
89
|
+
start: () => Promise<void>;
|
|
90
|
+
stop: () => Promise<void>;
|
|
91
|
+
publish: (topic: TopicStr, data: Uint8Array, opts?: PublishOpts) => Promise<PublishResult>;
|
|
92
|
+
getMeshPeers: (topic: TopicStr) => string[];
|
|
93
|
+
dumpPeerScoreStats: () => PeerScoreStatsDump;
|
|
94
|
+
getScore: (peerIdStr: string) => number;
|
|
95
|
+
reportMessageValidationResult: (msgId: string, propagationSource: string, acceptance: TopicValidatorResult) => void;
|
|
96
|
+
};
|
|
97
|
+
|
|
72
98
|
/**
|
|
73
99
|
* Wrapper around js-libp2p-gossipsub with the following extensions:
|
|
74
100
|
* - Eth2 message id
|
|
@@ -82,13 +108,14 @@ export type ForkBoundaryLabel = string;
|
|
|
82
108
|
*
|
|
83
109
|
* See https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
|
|
84
110
|
*/
|
|
85
|
-
export class Eth2Gossipsub
|
|
111
|
+
export class Eth2Gossipsub {
|
|
86
112
|
readonly scoreParams: Partial<PeerScoreParams>;
|
|
87
113
|
private readonly config: BeaconConfig;
|
|
88
114
|
private readonly logger: Logger;
|
|
89
115
|
private readonly peersData: PeersData;
|
|
90
116
|
private readonly events: NetworkEventBus;
|
|
91
117
|
private readonly libp2p: Libp2p;
|
|
118
|
+
private readonly gossipsub: GossipSubInternal;
|
|
92
119
|
|
|
93
120
|
// Internal caches
|
|
94
121
|
private readonly gossipTopicCache: GossipTopicCache;
|
|
@@ -103,9 +130,6 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
103
130
|
let metrics: Eth2GossipsubMetrics | null = null;
|
|
104
131
|
if (metricsRegister) {
|
|
105
132
|
metrics = createEth2GossipsubMetrics(metricsRegister);
|
|
106
|
-
metrics.gossipMesh.peersByType.addCollect(() =>
|
|
107
|
-
this.onScrapeLodestarMetrics(metrics as Eth2GossipsubMetrics, networkConfig)
|
|
108
|
-
);
|
|
109
133
|
}
|
|
110
134
|
|
|
111
135
|
// Parse direct peers from multiaddr strings to AddrInfo objects
|
|
@@ -113,8 +137,8 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
113
137
|
|
|
114
138
|
// Gossipsub parameters defined here:
|
|
115
139
|
// https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
|
|
116
|
-
|
|
117
|
-
globalSignaturePolicy:
|
|
140
|
+
const gossipsubInstance = gossipsub({
|
|
141
|
+
globalSignaturePolicy: StrictNoSign,
|
|
118
142
|
allowPublishToZeroTopicPeers: allowPublishToZeroPeers,
|
|
119
143
|
D: gossipsubD ?? GOSSIP_D,
|
|
120
144
|
Dlo: gossipsubDLow ?? GOSSIP_D_LOW,
|
|
@@ -155,7 +179,12 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
155
179
|
// This should be large enough to not send IDONTWANT for "small" messages
|
|
156
180
|
// See https://github.com/ChainSafe/lodestar/pull/7077#issuecomment-2383679472
|
|
157
181
|
idontwantMinDataSize: 16829,
|
|
158
|
-
});
|
|
182
|
+
})(modules.libp2p.services.components) as GossipSubInternal;
|
|
183
|
+
|
|
184
|
+
if (metrics) {
|
|
185
|
+
metrics.gossipMesh.peersByType.addCollect(() => this.onScrapeLodestarMetrics(metrics, networkConfig));
|
|
186
|
+
}
|
|
187
|
+
this.gossipsub = gossipsubInstance;
|
|
159
188
|
this.scoreParams = scoreParams;
|
|
160
189
|
this.config = config;
|
|
161
190
|
this.logger = logger;
|
|
@@ -164,7 +193,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
164
193
|
this.libp2p = modules.libp2p;
|
|
165
194
|
this.gossipTopicCache = gossipTopicCache;
|
|
166
195
|
|
|
167
|
-
this.addEventListener("gossipsub:message", this.onGossipsubMessage.bind(this));
|
|
196
|
+
this.gossipsub.addEventListener("gossipsub:message", this.onGossipsubMessage.bind(this));
|
|
168
197
|
this.events.on(NetworkEvent.gossipMessageValidationResult, this.onValidationResult.bind(this));
|
|
169
198
|
|
|
170
199
|
// Having access to this data is CRUCIAL for debugging. While this is a massive log, it must not be deleted.
|
|
@@ -174,6 +203,38 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
174
203
|
}
|
|
175
204
|
}
|
|
176
205
|
|
|
206
|
+
async start(): Promise<void> {
|
|
207
|
+
await this.gossipsub.start();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async stop(): Promise<void> {
|
|
211
|
+
await this.gossipsub.stop();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
get mesh(): Map<string, Set<string>> {
|
|
215
|
+
return this.gossipsub.mesh;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
getTopics(): TopicStr[] {
|
|
219
|
+
return this.gossipsub.getTopics();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
getMeshPeers(topic: TopicStr): string[] {
|
|
223
|
+
return this.gossipsub.getMeshPeers(topic);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
publish(topic: TopicStr, data: Uint8Array, opts?: PublishOpts): Promise<PublishResult> {
|
|
227
|
+
return this.gossipsub.publish(topic, data, opts);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
dumpPeerScoreStats(): PeerScoreStatsDump {
|
|
231
|
+
return this.gossipsub.dumpPeerScoreStats();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
getScore(peerIdStr: string): number {
|
|
235
|
+
return this.gossipsub.getScore(peerIdStr);
|
|
236
|
+
}
|
|
237
|
+
|
|
177
238
|
/**
|
|
178
239
|
* Subscribe to a `GossipTopic`
|
|
179
240
|
*/
|
|
@@ -183,7 +244,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
183
244
|
this.gossipTopicCache.setTopic(topicStr, topic);
|
|
184
245
|
|
|
185
246
|
this.logger.verbose("Subscribe to gossipsub topic", {topic: topicStr});
|
|
186
|
-
this.subscribe(topicStr);
|
|
247
|
+
this.gossipsub.subscribe(topicStr);
|
|
187
248
|
}
|
|
188
249
|
|
|
189
250
|
/**
|
|
@@ -192,15 +253,14 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
192
253
|
unsubscribeTopic(topic: GossipTopic): void {
|
|
193
254
|
const topicStr = stringifyGossipTopic(this.config, topic);
|
|
194
255
|
this.logger.verbose("Unsubscribe to gossipsub topic", {topic: topicStr});
|
|
195
|
-
this.unsubscribe(topicStr);
|
|
256
|
+
this.gossipsub.unsubscribe(topicStr);
|
|
196
257
|
}
|
|
197
258
|
|
|
198
259
|
private onScrapeLodestarMetrics(metrics: Eth2GossipsubMetrics, networkConfig: NetworkConfig): void {
|
|
199
|
-
const mesh = this.mesh;
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
const score = this.score;
|
|
260
|
+
const mesh = this.gossipsub.mesh;
|
|
261
|
+
const topics = this.gossipsub.topics;
|
|
262
|
+
const peers = this.gossipsub.peers;
|
|
263
|
+
const score = this.gossipsub.score;
|
|
204
264
|
const meshPeersByClient = new Map<string, number>();
|
|
205
265
|
const meshPeerIdStrs = new Set<string>();
|
|
206
266
|
|
|
@@ -305,7 +365,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
305
365
|
metrics.gossipPeer.score.set(gossipScores);
|
|
306
366
|
}
|
|
307
367
|
|
|
308
|
-
private onGossipsubMessage(event:
|
|
368
|
+
private onGossipsubMessage(event: GossipSubEvents["gossipsub:message"]): void {
|
|
309
369
|
const {propagationSource, msgId, msg} = event.detail;
|
|
310
370
|
|
|
311
371
|
// Also validates that the topicStr is known
|
|
@@ -341,7 +401,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
341
401
|
// Without this we'll have huge event loop lag
|
|
342
402
|
// See https://github.com/ChainSafe/lodestar/issues/5604
|
|
343
403
|
callInNextEventLoop(() => {
|
|
344
|
-
this.reportMessageValidationResult(data.msgId, data.propagationSource, data.acceptance);
|
|
404
|
+
this.gossipsub.reportMessageValidationResult(data.msgId, data.propagationSource, data.acceptance);
|
|
345
405
|
});
|
|
346
406
|
}
|
|
347
407
|
|
|
@@ -379,7 +439,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
379
439
|
}
|
|
380
440
|
|
|
381
441
|
// Add to direct peers set only after addresses are stored
|
|
382
|
-
this.direct.add(peerIdStr);
|
|
442
|
+
this.gossipsub.direct.add(peerIdStr);
|
|
383
443
|
|
|
384
444
|
this.logger.info("Added direct peer via API", {peerId: peerIdStr});
|
|
385
445
|
return peerIdStr;
|
|
@@ -389,7 +449,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
389
449
|
* Remove a peer from direct peers.
|
|
390
450
|
*/
|
|
391
451
|
removeDirectPeer(peerIdStr: string): boolean {
|
|
392
|
-
const removed = this.direct.delete(peerIdStr);
|
|
452
|
+
const removed = this.gossipsub.direct.delete(peerIdStr);
|
|
393
453
|
if (removed) {
|
|
394
454
|
this.logger.info("Removed direct peer via API", {peerId: peerIdStr});
|
|
395
455
|
}
|
|
@@ -400,7 +460,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
400
460
|
* Get list of current direct peer IDs.
|
|
401
461
|
*/
|
|
402
462
|
getDirectPeers(): string[] {
|
|
403
|
-
return Array.from(this.direct);
|
|
463
|
+
return Array.from(this.gossipsub.direct);
|
|
404
464
|
}
|
|
405
465
|
}
|
|
406
466
|
|
|
@@ -498,7 +558,8 @@ export function parseDirectPeers(directPeerStrs: routes.lodestar.DirectPeer[], l
|
|
|
498
558
|
try {
|
|
499
559
|
const ma = multiaddr(peerStr);
|
|
500
560
|
|
|
501
|
-
const
|
|
561
|
+
const peerIdComponent = ma.getComponents().findLast((component) => component.name === "p2p");
|
|
562
|
+
const peerIdStr = peerIdComponent?.value;
|
|
502
563
|
if (!peerIdStr) {
|
|
503
564
|
logger.warn("Direct peer multiaddr must contain /p2p/ component with peer ID", {multiaddr: peerStr});
|
|
504
565
|
continue;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {Message, TopicValidatorResult} from "@libp2p/
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type {Message, TopicValidatorResult} from "@libp2p/gossipsub";
|
|
2
|
+
import type {PeerIdStr} from "@libp2p/gossipsub/types";
|
|
3
|
+
import type {Libp2p} from "libp2p";
|
|
4
4
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
5
5
|
import {
|
|
6
6
|
AttesterSlashing,
|
|
7
|
+
DataColumnSidecar,
|
|
7
8
|
LightClientFinalityUpdate,
|
|
8
9
|
LightClientOptimisticUpdate,
|
|
9
10
|
SignedAggregateAndProof,
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
altair,
|
|
15
16
|
capella,
|
|
16
17
|
deneb,
|
|
17
|
-
fulu,
|
|
18
18
|
gloas,
|
|
19
19
|
phase0,
|
|
20
20
|
} from "@lodestar/types";
|
|
@@ -98,7 +98,7 @@ export type GossipTypeMap = {
|
|
|
98
98
|
[GossipType.blob_sidecar]: deneb.BlobSidecar;
|
|
99
99
|
[GossipType.beacon_aggregate_and_proof]: SignedAggregateAndProof;
|
|
100
100
|
[GossipType.beacon_attestation]: SingleAttestation;
|
|
101
|
-
[GossipType.data_column_sidecar]:
|
|
101
|
+
[GossipType.data_column_sidecar]: DataColumnSidecar;
|
|
102
102
|
[GossipType.voluntary_exit]: phase0.SignedVoluntaryExit;
|
|
103
103
|
[GossipType.proposer_slashing]: phase0.ProposerSlashing;
|
|
104
104
|
[GossipType.attester_slashing]: AttesterSlashing;
|
|
@@ -117,7 +117,7 @@ export type GossipFnByType = {
|
|
|
117
117
|
[GossipType.blob_sidecar]: (blobSidecar: deneb.BlobSidecar) => Promise<void> | void;
|
|
118
118
|
[GossipType.beacon_aggregate_and_proof]: (aggregateAndProof: SignedAggregateAndProof) => Promise<void> | void;
|
|
119
119
|
[GossipType.beacon_attestation]: (attestation: SingleAttestation) => Promise<void> | void;
|
|
120
|
-
[GossipType.data_column_sidecar]: (dataColumnSidecar:
|
|
120
|
+
[GossipType.data_column_sidecar]: (dataColumnSidecar: DataColumnSidecar) => Promise<void> | void;
|
|
121
121
|
[GossipType.voluntary_exit]: (voluntaryExit: phase0.SignedVoluntaryExit) => Promise<void> | void;
|
|
122
122
|
[GossipType.proposer_slashing]: (proposerSlashing: phase0.ProposerSlashing) => Promise<void> | void;
|
|
123
123
|
[GossipType.attester_slashing]: (attesterSlashing: AttesterSlashing) => Promise<void> | void;
|
|
@@ -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;
|
|
@@ -72,8 +73,37 @@ export async function createNodeJsLibp2p(
|
|
|
72
73
|
noiseCrypto.chaCha20Poly1305Encrypt = asCrypto.chaCha20Poly1305Encrypt;
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
const libp2pMetrics = nodeJsLibp2pOpts.metrics
|
|
77
|
+
? (components: LodestarComponents) => {
|
|
78
|
+
const metrics = prometheusMetrics({
|
|
79
|
+
collectDefaultMetrics: false,
|
|
80
|
+
preserveExistingMetrics: true,
|
|
81
|
+
registry: nodeJsLibp2pOpts.metricsRegistry,
|
|
82
|
+
})(components);
|
|
83
|
+
|
|
84
|
+
// Work around identify EOF race:
|
|
85
|
+
// `trackProtocolStream` attaches a `message` listener immediately after protocol
|
|
86
|
+
// negotiation. For `/ipfs/id/1.0.0`, identify() adds its own reader later and can
|
|
87
|
+
// miss the first response frame when metrics listener drains events first.
|
|
88
|
+
const originalTrackProtocolStream = metrics.trackProtocolStream.bind(metrics);
|
|
89
|
+
metrics.trackProtocolStream = ((stream) => {
|
|
90
|
+
if (stream.protocol === "/ipfs/id/1.0.0") {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
originalTrackProtocolStream(stream);
|
|
94
|
+
}) as typeof metrics.trackProtocolStream;
|
|
95
|
+
|
|
96
|
+
return metrics;
|
|
97
|
+
}
|
|
98
|
+
: undefined;
|
|
99
|
+
|
|
75
100
|
return createLibp2p({
|
|
76
101
|
privateKey,
|
|
102
|
+
nodeInfo: {
|
|
103
|
+
name: "lodestar",
|
|
104
|
+
version: networkOpts.version ?? "unknown",
|
|
105
|
+
userAgent: networkOpts.private ? "" : networkOpts.version ? `lodestar/${networkOpts.version}` : "lodestar",
|
|
106
|
+
},
|
|
77
107
|
addresses: {
|
|
78
108
|
listen: localMultiaddrs,
|
|
79
109
|
announce: [],
|
|
@@ -93,15 +123,9 @@ export async function createNodeJsLibp2p(
|
|
|
93
123
|
},
|
|
94
124
|
}),
|
|
95
125
|
],
|
|
96
|
-
streamMuxers: [mplex({
|
|
126
|
+
streamMuxers: [mplex({disconnectThreshold})],
|
|
97
127
|
peerDiscovery,
|
|
98
|
-
metrics:
|
|
99
|
-
? prometheusMetrics({
|
|
100
|
-
collectDefaultMetrics: false,
|
|
101
|
-
preserveExistingMetrics: true,
|
|
102
|
-
registry: nodeJsLibp2pOpts.metricsRegistry,
|
|
103
|
-
})
|
|
104
|
-
: undefined,
|
|
128
|
+
metrics: libp2pMetrics,
|
|
105
129
|
connectionManager: {
|
|
106
130
|
// dialer config
|
|
107
131
|
maxParallelDials: 100,
|
|
@@ -124,7 +148,6 @@ export async function createNodeJsLibp2p(
|
|
|
124
148
|
datastore,
|
|
125
149
|
services: {
|
|
126
150
|
identify: identify({
|
|
127
|
-
agentVersion: networkOpts.private ? "" : networkOpts.version ? `lodestar/${networkOpts.version}` : "lodestar",
|
|
128
151
|
runOnConnectionOpen: false,
|
|
129
152
|
}),
|
|
130
153
|
// 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
|
};
|