@lodestar/beacon-node 1.47.0-dev.ec596194e2 → 1.47.0-dev.ee197a8d7f

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.
Files changed (33) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +3 -6
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +4 -0
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
  8. package/lib/chain/archiveStore/historicalState/metrics.js +21 -0
  9. package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
  10. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  11. package/lib/chain/blocks/importBlock.js +2 -7
  12. package/lib/chain/blocks/importBlock.js.map +1 -1
  13. package/lib/chain/validation/proposerPreferences.d.ts +1 -1
  14. package/lib/chain/validation/proposerPreferences.js +1 -1
  15. package/lib/metrics/metrics/lodestar.d.ts +10 -0
  16. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  17. package/lib/metrics/metrics/lodestar.js +16 -0
  18. package/lib/metrics/metrics/lodestar.js.map +1 -1
  19. package/lib/network/libp2p/index.d.ts.map +1 -1
  20. package/lib/network/libp2p/index.js +10 -2
  21. package/lib/network/libp2p/index.js.map +1 -1
  22. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  23. package/lib/network/processor/gossipHandlers.js +7 -2
  24. package/lib/network/processor/gossipHandlers.js.map +1 -1
  25. package/package.json +14 -14
  26. package/src/api/impl/beacon/blocks/index.ts +4 -6
  27. package/src/api/impl/beacon/pool/index.ts +5 -0
  28. package/src/chain/archiveStore/historicalState/metrics.ts +22 -0
  29. package/src/chain/blocks/importBlock.ts +1 -6
  30. package/src/chain/validation/proposerPreferences.ts +1 -1
  31. package/src/metrics/metrics/lodestar.ts +16 -0
  32. package/src/network/libp2p/index.ts +11 -2
  33. package/src/network/processor/gossipHandlers.ts +9 -0
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.47.0-dev.ec596194e2",
14
+ "version": "1.47.0-dev.ee197a8d7f",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -126,17 +126,17 @@
126
126
  "@libp2p/peer-id": "^6.0.4",
127
127
  "@libp2p/prometheus-metrics": "^5.0.14",
128
128
  "@libp2p/tcp": "^11.0.13",
129
- "@lodestar/api": "^1.47.0-dev.ec596194e2",
130
- "@lodestar/config": "^1.47.0-dev.ec596194e2",
131
- "@lodestar/db": "^1.47.0-dev.ec596194e2",
132
- "@lodestar/fork-choice": "^1.47.0-dev.ec596194e2",
133
- "@lodestar/logger": "^1.47.0-dev.ec596194e2",
134
- "@lodestar/params": "^1.47.0-dev.ec596194e2",
135
- "@lodestar/reqresp": "^1.47.0-dev.ec596194e2",
136
- "@lodestar/state-transition": "^1.47.0-dev.ec596194e2",
137
- "@lodestar/types": "^1.47.0-dev.ec596194e2",
138
- "@lodestar/utils": "^1.47.0-dev.ec596194e2",
139
- "@lodestar/validator": "^1.47.0-dev.ec596194e2",
129
+ "@lodestar/api": "^1.47.0-dev.ee197a8d7f",
130
+ "@lodestar/config": "^1.47.0-dev.ee197a8d7f",
131
+ "@lodestar/db": "^1.47.0-dev.ee197a8d7f",
132
+ "@lodestar/fork-choice": "^1.47.0-dev.ee197a8d7f",
133
+ "@lodestar/logger": "^1.47.0-dev.ee197a8d7f",
134
+ "@lodestar/params": "^1.47.0-dev.ee197a8d7f",
135
+ "@lodestar/reqresp": "^1.47.0-dev.ee197a8d7f",
136
+ "@lodestar/state-transition": "^1.47.0-dev.ee197a8d7f",
137
+ "@lodestar/types": "^1.47.0-dev.ee197a8d7f",
138
+ "@lodestar/utils": "^1.47.0-dev.ee197a8d7f",
139
+ "@lodestar/validator": "^1.47.0-dev.ee197a8d7f",
140
140
  "@multiformats/multiaddr": "^13.0.1",
141
141
  "datastore-core": "^11.0.2",
142
142
  "datastore-level": "^12.0.2",
@@ -158,7 +158,7 @@
158
158
  "@libp2p/interface-internal": "^3.0.13",
159
159
  "@libp2p/logger": "^6.2.2",
160
160
  "@libp2p/utils": "^7.0.13",
161
- "@lodestar/spec-test-util": "^1.47.0-dev.ec596194e2",
161
+ "@lodestar/spec-test-util": "^1.47.0-dev.ee197a8d7f",
162
162
  "@types/js-yaml": "^4.0.5",
163
163
  "@types/qs": "^6.9.7",
164
164
  "@types/tmp": "^0.2.3",
@@ -175,5 +175,5 @@
175
175
  "beacon",
176
176
  "blockchain"
177
177
  ],
178
- "gitHead": "dba08d7a33a32e7e0a39fc6d3f61707e64f5e565"
178
+ "gitHead": "2e730bed9c064ffd8cfd4d1ff9f4a916fe82dfea"
179
179
  }
@@ -220,12 +220,6 @@ export function getBeaconBlockApi({
220
220
  // Block has already been seen, e.g. via gossip racing the publish API. Benign.
221
221
  chain.logger.debug("Ignoring already-known block during publishing", valLogMeta);
222
222
  return;
223
- case BlockErrorCode.REPEAT_PROPOSAL:
224
- // The proposer already produced a block for this slot. For a solo setup this is a
225
- // notable signal (duplicate-proposal attempt). For fallback / DVT setups it is
226
- // expected on every block where another node published first.
227
- chain.logger.warn("Ignoring repeat-proposal block during publishing", valLogMeta);
228
- return;
229
223
  }
230
224
  }
231
225
 
@@ -1032,6 +1026,7 @@ export function getBeaconBlockApi({
1032
1026
  },
1033
1027
 
1034
1028
  async publishExecutionPayloadBid({signedExecutionPayloadBid}) {
1029
+ const seenTimestampSec = Date.now() / 1000;
1035
1030
  const bid = signedExecutionPayloadBid.message;
1036
1031
  const slot = bid.slot;
1037
1032
  const fork = config.getForkName(slot);
@@ -1042,6 +1037,9 @@ export function getBeaconBlockApi({
1042
1037
 
1043
1038
  await validateApiExecutionPayloadBid(chain, signedExecutionPayloadBid);
1044
1039
 
1040
+ const elapsedSec = chain.clock.secFromSlot(slot, seenTimestampSec);
1041
+ metrics?.gossipExecutionPayloadBid.elapsedTimeTillReceived.observe({source: OpSource.api}, elapsedSec);
1042
+
1045
1043
  try {
1046
1044
  const insertOutcome = chain.executionPayloadBidPool.add(signedExecutionPayloadBid);
1047
1045
  metrics?.opPool.executionPayloadBidPool.apiInsertOutcome.inc({insertOutcome});
@@ -25,6 +25,7 @@ import {validateApiPayloadAttestationMessage} from "../../../../chain/validation
25
25
  import {validateApiProposerSlashing} from "../../../../chain/validation/proposerSlashing.js";
26
26
  import {validateApiSyncCommittee} from "../../../../chain/validation/syncCommittee.js";
27
27
  import {validateApiVoluntaryExit} from "../../../../chain/validation/voluntaryExit.js";
28
+ import {OpSource} from "../../../../chain/validatorMonitor.js";
28
29
  import {validateGossipFnRetryUnknownRoot} from "../../../../network/processor/gossipHandlers.js";
29
30
  import {ApiError, FailureList, IndexedError} from "../../errors.js";
30
31
  import {ApiModules} from "../../types.js";
@@ -211,6 +212,7 @@ export function getBeaconPoolApi({
211
212
  },
212
213
 
213
214
  async submitPayloadAttestationMessages({payloadAttestationMessages}) {
215
+ const seenTimestampSec = Date.now() / 1000;
214
216
  const failures: FailureList = [];
215
217
 
216
218
  await Promise.all(
@@ -226,6 +228,9 @@ export function getBeaconPoolApi({
226
228
  beaconBlockRoot
227
229
  );
228
230
 
231
+ const delaySec = chain.clock.secFromSlot(slot, seenTimestampSec);
232
+ metrics?.gossipPayloadAttestationMessage.elapsedTimeTillReceived.observe({source: OpSource.api}, delaySec);
233
+
229
234
  const insertOutcome = chain.payloadAttestationPool.add(
230
235
  payloadAttestationMessage,
231
236
  attDataRootHex,
@@ -1,3 +1,4 @@
1
+ import {ForkName} from "@lodestar/params";
1
2
  import {
2
3
  BeaconStateTransitionMetrics,
3
4
  EpochTransitionStep,
@@ -45,6 +46,27 @@ export function createHistoricalStateTransitionMetrics(
45
46
  labelNames: ["step"],
46
47
  buckets: [0.01, 0.05, 0.1, 0.2, 0.5, 0.75, 1],
47
48
  }),
49
+ forkUpgradeTime: metricsRegister.histogram<{fork: ForkName}>({
50
+ name: "lodestar_historical_state_stfn_fork_upgrade_seconds",
51
+ help: "Time to upgrade the state at a fork boundary in seconds",
52
+ labelNames: ["fork"],
53
+ buckets: [0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30],
54
+ }),
55
+ onboardBuildersTime: metricsRegister.histogram({
56
+ name: "lodestar_historical_state_stfn_gloas_onboard_builders_seconds",
57
+ help: "Time spent in onboardBuildersFromPendingDeposits at the gloas fork transition",
58
+ buckets: [0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30],
59
+ }),
60
+ onboardBuildersDeposits: metricsRegister.gauge<{outcome: "onboarded" | "topup" | "kept" | "dropped"}>({
61
+ name: "lodestar_historical_state_stfn_gloas_onboard_builders_deposits",
62
+ help: "Pending deposits handled at the gloas fork transition, by outcome",
63
+ labelNames: ["outcome"],
64
+ }),
65
+ onboardBuildersSignatureChecks: metricsRegister.gauge<{source: "cache" | "verified"}>({
66
+ name: "lodestar_historical_state_stfn_gloas_onboard_builders_signature_checks",
67
+ help: "Builder deposit signature checks at the gloas fork transition, by whether the pre-verify cache served them",
68
+ labelNames: ["source"],
69
+ }),
48
70
  processBlockTime: metricsRegister.histogram({
49
71
  name: "lodestar_historical_state_stfn_process_block_seconds",
50
72
  help: "Time to process a single block in seconds",
@@ -22,7 +22,6 @@ import {
22
22
  RootCache,
23
23
  computeEpochAtSlot,
24
24
  computeTimeAtSlot,
25
- isStartSlotOfEpoch,
26
25
  isStatePostAltair,
27
26
  isStatePostBellatrix,
28
27
  } from "@lodestar/state-transition";
@@ -404,11 +403,7 @@ export async function importBlock(
404
403
  notOverrideFcuReason = NotReorgedReason.NotProposerOfNextSlot;
405
404
  }
406
405
  } catch (e) {
407
- if (isStartSlotOfEpoch(proposalSlot)) {
408
- notOverrideFcuReason = NotReorgedReason.AtEpochBoundary;
409
- } else {
410
- this.logger.warn("Unable to get beacon proposer. Do not override fcu.", {proposalSlot}, e as Error);
411
- }
406
+ this.logger.warn("Unable to get beacon proposer. Do not override fcu.", {proposalSlot}, e as Error);
412
407
  }
413
408
 
414
409
  if (shouldOverrideFcu) {
@@ -13,7 +13,7 @@ import {IBeaconChain} from "../index.js";
13
13
 
14
14
  /**
15
15
  * Validates a gossiped `SignedProposerPreferences` per
16
- * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/gloas/p2p-interface.md#new-proposer_preferences
16
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/p2p-interface.md#new-proposer_preferences
17
17
  */
18
18
  export async function validateGossipProposerPreferences(
19
19
  chain: IBeaconChain,
@@ -908,6 +908,22 @@ export function createLodestarMetrics(
908
908
  labelNames: ["error"],
909
909
  }),
910
910
  },
911
+ gossipExecutionPayloadBid: {
912
+ elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
913
+ name: "lodestar_gossip_execution_payload_bid_elapsed_time_till_received_seconds",
914
+ help: "Time elapsed between the bid's slot start and the time the execution payload bid was received (negative = received before its slot, broadcast in the previous slot; positive = received during its own slot, late)",
915
+ labelNames: ["source"],
916
+ buckets: [-6, -3, -1, 0, 3],
917
+ }),
918
+ },
919
+ gossipPayloadAttestationMessage: {
920
+ elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
921
+ name: "lodestar_gossip_payload_attestation_message_elapsed_time_till_received_seconds",
922
+ help: "Time elapsed between slot time and the time the payload attestation message was received",
923
+ labelNames: ["source"],
924
+ buckets: [3, 6, 9, 12],
925
+ }),
926
+ },
911
927
  // recovery in the case of specific blob rows required
912
928
  recoverBlobSidecars: {
913
929
  blobsReconstructed: register.counter({
@@ -1,3 +1,4 @@
1
+ import {getCiphers} from "node:crypto";
1
2
  import {bootstrap} from "@libp2p/bootstrap";
2
3
  import {identify} from "@libp2p/identify";
3
4
  import type {PrivateKey} from "@libp2p/interface";
@@ -9,12 +10,20 @@ import {Libp2pInit, createLibp2p} from "libp2p";
9
10
  import {Registry} from "prom-client";
10
11
  import {ENR} from "@chainsafe/enr";
11
12
  import {noise} from "@chainsafe/libp2p-noise";
12
- import {defaultCrypto} from "@chainsafe/libp2p-noise/crypto";
13
+ import {asCrypto, defaultCrypto} from "@chainsafe/libp2p-noise/crypto";
13
14
  import {quic} from "@chainsafe/libp2p-quic";
14
15
  import {Libp2p, LodestarComponents} from "../interface.js";
15
16
  import {NetworkOptions, defaultNetworkOptions} from "../options.js";
16
17
  import {Eth2PeerDataStore} from "../peers/datastore.js";
17
18
 
19
+ const noiseCrypto = getCiphers().includes("chacha20-poly1305")
20
+ ? defaultCrypto
21
+ : {
22
+ ...defaultCrypto,
23
+ chaCha20Poly1305Encrypt: asCrypto.chaCha20Poly1305Encrypt,
24
+ chaCha20Poly1305Decrypt: asCrypto.chaCha20Poly1305Decrypt,
25
+ };
26
+
18
27
  export type NodeJsLibp2pOpts = {
19
28
  peerStoreDir?: string;
20
29
  disablePeerDiscovery?: boolean;
@@ -122,7 +131,7 @@ export async function createNodeJsLibp2p(
122
131
  listen: localMultiaddrs,
123
132
  announce: [],
124
133
  },
125
- connectionEncrypters: [noise({crypto: defaultCrypto})],
134
+ connectionEncrypters: [noise({crypto: noiseCrypto})],
126
135
  transports,
127
136
  streamMuxers: [mplex({disconnectThreshold})],
128
137
  peerDiscovery,
@@ -1255,11 +1255,15 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1255
1255
  [GossipType.payload_attestation_message]: async ({
1256
1256
  gossipData,
1257
1257
  topic,
1258
+ seenTimestampSec,
1258
1259
  }: GossipHandlerParamGeneric<GossipType.payload_attestation_message>) => {
1259
1260
  const {serializedData} = gossipData;
1260
1261
  const payloadAttestationMessage = sszDeserialize(topic, serializedData);
1261
1262
  const validationResult = await validateGossipPayloadAttestationMessage(chain, payloadAttestationMessage);
1262
1263
 
1264
+ const delaySec = chain.clock.secFromSlot(payloadAttestationMessage.data.slot, seenTimestampSec);
1265
+ metrics?.gossipPayloadAttestationMessage.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
1266
+
1263
1267
  try {
1264
1268
  const insertOutcome = chain.payloadAttestationPool.add(
1265
1269
  payloadAttestationMessage,
@@ -1286,11 +1290,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1286
1290
  [GossipType.execution_payload_bid]: async ({
1287
1291
  gossipData,
1288
1292
  topic,
1293
+ seenTimestampSec,
1289
1294
  }: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
1290
1295
  const {serializedData} = gossipData;
1291
1296
  const executionPayloadBid = sszDeserialize(topic, serializedData);
1292
1297
  const {proposerIndex} = await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
1293
1298
 
1299
+ // this could be negative, because it's most likely the bid of next slot comes at this clock slot
1300
+ const elapsedSec = chain.clock.secFromSlot(executionPayloadBid.message.slot, seenTimestampSec);
1301
+ metrics?.gossipExecutionPayloadBid.elapsedTimeTillReceived.observe({source: OpSource.gossip}, elapsedSec);
1302
+
1294
1303
  // Handle valid payload bid by storing in a bid pool
1295
1304
  try {
1296
1305
  const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid);