@lodestar/beacon-node 1.41.0-dev.eb7efb2b90 → 1.41.0-dev.ef310100c0

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 (239) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +121 -3
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/state/index.js +8 -8
  5. package/lib/api/impl/beacon/state/index.js.map +1 -1
  6. package/lib/api/impl/beacon/state/utils.d.ts +3 -4
  7. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/utils.js +5 -24
  9. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +5 -2
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/lightclient/index.d.ts.map +1 -1
  14. package/lib/api/impl/lightclient/index.js +19 -2
  15. package/lib/api/impl/lightclient/index.js.map +1 -1
  16. package/lib/api/impl/validator/index.d.ts.map +1 -1
  17. package/lib/api/impl/validator/index.js +104 -6
  18. package/lib/api/impl/validator/index.js.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  20. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.js +9 -0
  22. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +5 -6
  24. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +9 -10
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/worker.js +3 -3
  28. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  29. package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
  30. package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
  31. package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
  32. package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
  33. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  34. package/lib/chain/blocks/importBlock.js +0 -2
  35. package/lib/chain/blocks/importBlock.js.map +1 -1
  36. package/lib/chain/blocks/index.d.ts.map +1 -1
  37. package/lib/chain/blocks/index.js +2 -1
  38. package/lib/chain/blocks/index.js.map +1 -1
  39. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  40. package/lib/chain/blocks/writeBlockInputToDb.js +3 -0
  41. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  42. package/lib/chain/bls/multithread/index.d.ts +3 -3
  43. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  44. package/lib/chain/bls/multithread/index.js +5 -5
  45. package/lib/chain/bls/multithread/index.js.map +1 -1
  46. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  47. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  48. package/lib/chain/bls/multithread/jobItem.js +2 -2
  49. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  50. package/lib/chain/bls/singleThread.d.ts +4 -4
  51. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  52. package/lib/chain/bls/singleThread.js +4 -4
  53. package/lib/chain/bls/singleThread.js.map +1 -1
  54. package/lib/chain/bls/utils.d.ts +2 -2
  55. package/lib/chain/bls/utils.d.ts.map +1 -1
  56. package/lib/chain/bls/utils.js +7 -4
  57. package/lib/chain/bls/utils.js.map +1 -1
  58. package/lib/chain/chain.d.ts +6 -9
  59. package/lib/chain/chain.d.ts.map +1 -1
  60. package/lib/chain/chain.js +32 -16
  61. package/lib/chain/chain.js.map +1 -1
  62. package/lib/chain/emitter.d.ts +2 -2
  63. package/lib/chain/emitter.d.ts.map +1 -1
  64. package/lib/chain/interface.d.ts +4 -6
  65. package/lib/chain/interface.d.ts.map +1 -1
  66. package/lib/chain/interface.js.map +1 -1
  67. package/lib/chain/lightClient/index.d.ts.map +1 -1
  68. package/lib/chain/lightClient/index.js +1 -1
  69. package/lib/chain/lightClient/index.js.map +1 -1
  70. package/lib/chain/options.d.ts.map +1 -1
  71. package/lib/chain/options.js.map +1 -1
  72. package/lib/chain/prepareNextSlot.js +3 -3
  73. package/lib/chain/prepareNextSlot.js.map +1 -1
  74. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +10 -2
  75. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  76. package/lib/chain/produceBlock/computeNewStateRoot.js +24 -2
  77. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  78. package/lib/chain/produceBlock/produceBlockBody.d.ts +22 -7
  79. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  80. package/lib/chain/produceBlock/produceBlockBody.js +110 -10
  81. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  82. package/lib/chain/validation/attestation.d.ts.map +1 -1
  83. package/lib/chain/validation/attestation.js +4 -1
  84. package/lib/chain/validation/attestation.js.map +1 -1
  85. package/lib/chain/validation/attesterSlashing.js +1 -1
  86. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  87. package/lib/chain/validation/dataColumnSidecar.d.ts +2 -2
  88. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  89. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  90. package/lib/chain/validation/payloadAttestationMessage.js +8 -1
  91. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  92. package/lib/chain/validation/proposerSlashing.js +1 -1
  93. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  94. package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
  95. package/lib/db/beacon.d.ts +3 -1
  96. package/lib/db/beacon.d.ts.map +1 -1
  97. package/lib/db/beacon.js +5 -1
  98. package/lib/db/beacon.js.map +1 -1
  99. package/lib/db/buckets.d.ts +3 -1
  100. package/lib/db/buckets.d.ts.map +1 -1
  101. package/lib/db/buckets.js +2 -0
  102. package/lib/db/buckets.js.map +1 -1
  103. package/lib/db/interface.d.ts +3 -1
  104. package/lib/db/interface.d.ts.map +1 -1
  105. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  106. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  107. package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
  108. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  109. package/lib/db/repositories/dataColumnSidecar.js +14 -1
  110. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  111. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
  112. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  113. package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
  114. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  115. package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
  116. package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
  117. package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
  118. package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
  119. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
  120. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
  121. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
  122. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
  123. package/lib/db/repositories/index.d.ts +2 -0
  124. package/lib/db/repositories/index.d.ts.map +1 -1
  125. package/lib/db/repositories/index.js +2 -0
  126. package/lib/db/repositories/index.js.map +1 -1
  127. package/lib/execution/engine/http.d.ts +1 -0
  128. package/lib/execution/engine/http.d.ts.map +1 -1
  129. package/lib/execution/engine/http.js +3 -0
  130. package/lib/execution/engine/http.js.map +1 -1
  131. package/lib/metrics/metrics/beacon.d.ts +1 -0
  132. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  133. package/lib/metrics/metrics/beacon.js +5 -0
  134. package/lib/metrics/metrics/beacon.js.map +1 -1
  135. package/lib/metrics/metrics/lodestar.d.ts +8 -0
  136. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  137. package/lib/metrics/metrics/lodestar.js +14 -0
  138. package/lib/metrics/metrics/lodestar.js.map +1 -1
  139. package/lib/monitoring/service.d.ts +2 -2
  140. package/lib/monitoring/service.d.ts.map +1 -1
  141. package/lib/monitoring/service.js +3 -2
  142. package/lib/monitoring/service.js.map +1 -1
  143. package/lib/network/gossip/interface.d.ts +3 -3
  144. package/lib/network/gossip/interface.d.ts.map +1 -1
  145. package/lib/network/gossip/topic.d.ts +113 -63
  146. package/lib/network/gossip/topic.d.ts.map +1 -1
  147. package/lib/network/gossip/topic.js +2 -2
  148. package/lib/network/gossip/topic.js.map +1 -1
  149. package/lib/network/interface.d.ts +3 -2
  150. package/lib/network/interface.d.ts.map +1 -1
  151. package/lib/network/network.d.ts +3 -2
  152. package/lib/network/network.d.ts.map +1 -1
  153. package/lib/network/network.js +10 -1
  154. package/lib/network/network.js.map +1 -1
  155. package/lib/network/peers/peerManager.d.ts +2 -0
  156. package/lib/network/peers/peerManager.d.ts.map +1 -1
  157. package/lib/network/peers/peerManager.js +54 -26
  158. package/lib/network/peers/peerManager.js.map +1 -1
  159. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  160. package/lib/network/processor/gossipHandlers.js +5 -1
  161. package/lib/network/processor/gossipHandlers.js.map +1 -1
  162. package/lib/network/reqresp/handlers/lightClientUpdatesByRange.d.ts.map +1 -1
  163. package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js +7 -1
  164. package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js.map +1 -1
  165. package/lib/node/nodejs.d.ts +3 -5
  166. package/lib/node/nodejs.d.ts.map +1 -1
  167. package/lib/node/nodejs.js +6 -4
  168. package/lib/node/nodejs.js.map +1 -1
  169. package/lib/util/blobs.d.ts +2 -2
  170. package/lib/util/blobs.d.ts.map +1 -1
  171. package/lib/util/blobs.js.map +1 -1
  172. package/lib/util/dataColumns.d.ts +11 -3
  173. package/lib/util/dataColumns.d.ts.map +1 -1
  174. package/lib/util/dataColumns.js +27 -0
  175. package/lib/util/dataColumns.js.map +1 -1
  176. package/lib/util/multifork.d.ts +8 -0
  177. package/lib/util/multifork.d.ts.map +1 -1
  178. package/lib/util/multifork.js +37 -0
  179. package/lib/util/multifork.js.map +1 -1
  180. package/lib/util/serializedCache.d.ts +5 -0
  181. package/lib/util/serializedCache.d.ts.map +1 -1
  182. package/lib/util/serializedCache.js +5 -0
  183. package/lib/util/serializedCache.js.map +1 -1
  184. package/package.json +15 -15
  185. package/src/api/impl/beacon/blocks/index.ts +145 -2
  186. package/src/api/impl/beacon/state/index.ts +8 -8
  187. package/src/api/impl/beacon/state/utils.ts +15 -29
  188. package/src/api/impl/debug/index.ts +8 -5
  189. package/src/api/impl/lightclient/index.ts +19 -2
  190. package/src/api/impl/validator/index.ts +127 -5
  191. package/src/chain/archiveStore/archiveStore.ts +10 -0
  192. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
  193. package/src/chain/archiveStore/historicalState/worker.ts +3 -3
  194. package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
  195. package/src/chain/blocks/importBlock.ts +0 -3
  196. package/src/chain/blocks/index.ts +2 -1
  197. package/src/chain/blocks/writeBlockInputToDb.ts +3 -0
  198. package/src/chain/bls/multithread/index.ts +7 -7
  199. package/src/chain/bls/multithread/jobItem.ts +3 -3
  200. package/src/chain/bls/singleThread.ts +5 -5
  201. package/src/chain/bls/utils.ts +8 -5
  202. package/src/chain/chain.ts +51 -26
  203. package/src/chain/emitter.ts +2 -2
  204. package/src/chain/interface.ts +4 -11
  205. package/src/chain/lightClient/index.ts +4 -1
  206. package/src/chain/options.ts +1 -0
  207. package/src/chain/prepareNextSlot.ts +5 -5
  208. package/src/chain/produceBlock/computeNewStateRoot.ts +35 -3
  209. package/src/chain/produceBlock/produceBlockBody.ts +163 -13
  210. package/src/chain/validation/attestation.ts +4 -1
  211. package/src/chain/validation/attesterSlashing.ts +1 -1
  212. package/src/chain/validation/dataColumnSidecar.ts +2 -5
  213. package/src/chain/validation/payloadAttestationMessage.ts +9 -1
  214. package/src/chain/validation/proposerSlashing.ts +1 -1
  215. package/src/chain/validation/syncCommitteeContributionAndProof.ts +1 -1
  216. package/src/db/beacon.ts +8 -0
  217. package/src/db/buckets.ts +3 -0
  218. package/src/db/interface.ts +5 -0
  219. package/src/db/repositories/dataColumnSidecar.ts +18 -3
  220. package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
  221. package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
  222. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
  223. package/src/db/repositories/index.ts +2 -0
  224. package/src/execution/engine/http.ts +3 -0
  225. package/src/metrics/metrics/beacon.ts +5 -0
  226. package/src/metrics/metrics/lodestar.ts +14 -0
  227. package/src/monitoring/service.ts +3 -2
  228. package/src/network/gossip/interface.ts +3 -3
  229. package/src/network/gossip/topic.ts +2 -1
  230. package/src/network/interface.ts +4 -1
  231. package/src/network/network.ts +21 -3
  232. package/src/network/peers/peerManager.ts +65 -27
  233. package/src/network/processor/gossipHandlers.ts +7 -1
  234. package/src/network/reqresp/handlers/lightClientUpdatesByRange.ts +6 -1
  235. package/src/node/nodejs.ts +8 -9
  236. package/src/util/blobs.ts +3 -3
  237. package/src/util/dataColumns.ts +37 -1
  238. package/src/util/multifork.ts +45 -0
  239. package/src/util/serializedCache.ts +5 -0
@@ -45,7 +45,7 @@ export async function validateAttesterSlashing(
45
45
  // verifySignature = false, verified in batch below
46
46
  assertValidAttesterSlashing(
47
47
  chain.config,
48
- chain.index2pubkey,
48
+ chain.pubkeyCache,
49
49
  state.slot,
50
50
  state.validators.length,
51
51
  attesterSlashing,
@@ -10,7 +10,7 @@ import {
10
10
  getBlockHeaderProposerSignatureSetByHeaderSlot,
11
11
  getBlockHeaderProposerSignatureSetByParentStateSlot,
12
12
  } from "@lodestar/state-transition";
13
- import {Root, Slot, SubnetID, fulu, ssz} from "@lodestar/types";
13
+ import {DataColumnSidecar, Root, Slot, SubnetID, fulu, ssz} from "@lodestar/types";
14
14
  import {byteArrayEquals, toRootHex, verifyMerkleBranch} from "@lodestar/utils";
15
15
  import {Metrics} from "../../metrics/metrics.js";
16
16
  import {kzg} from "../../util/kzg.js";
@@ -457,9 +457,6 @@ export async function validateBlockDataColumnSidecars(
457
457
  * SPEC FUNCTION
458
458
  * https://github.com/ethereum/consensus-specs/blob/v1.6.0-alpha.4/specs/fulu/p2p-interface.md#compute_subnet_for_data_column_sidecar
459
459
  */
460
- export function computeSubnetForDataColumnSidecar(
461
- config: ChainConfig,
462
- columnSidecar: fulu.DataColumnSidecar
463
- ): SubnetID {
460
+ export function computeSubnetForDataColumnSidecar(config: ChainConfig, columnSidecar: DataColumnSidecar): SubnetID {
464
461
  return columnSidecar.index % config.DATA_COLUMN_SIDECAR_SUBNET_COUNT;
465
462
  }
@@ -87,8 +87,16 @@ async function validatePayloadAttestationMessage(
87
87
  }
88
88
 
89
89
  // [REJECT] `payload_attestation_message.signature` is valid with respect to the validator's public key.
90
+ const validatorPubkey = chain.pubkeyCache.get(validatorIndex);
91
+ if (!validatorPubkey) {
92
+ throw new PayloadAttestationError(GossipAction.REJECT, {
93
+ code: PayloadAttestationErrorCode.INVALID_ATTESTER,
94
+ attesterIndex: validatorIndex,
95
+ });
96
+ }
97
+
90
98
  const signatureSet = createSingleSignatureSetFromComponents(
91
- chain.index2pubkey[validatorIndex],
99
+ validatorPubkey,
92
100
  getPayloadAttestationDataSigningRoot(chain.config, data),
93
101
  payloadAttestationMessage.signature
94
102
  );
@@ -37,7 +37,7 @@ async function validateProposerSlashing(
37
37
  try {
38
38
  const proposer = state.validators.getReadonly(proposerSlashing.signedHeader1.message.proposerIndex);
39
39
  // verifySignature = false, verified in batch below
40
- assertValidProposerSlashing(chain.config, chain.index2pubkey, state.slot, proposerSlashing, proposer, false);
40
+ assertValidProposerSlashing(chain.config, chain.pubkeyCache, state.slot, proposerSlashing, proposer, false);
41
41
  } catch (e) {
42
42
  throw new ProposerSlashingError(GossipAction.REJECT, {
43
43
  code: ProposerSlashingErrorCode.INVALID,
@@ -106,7 +106,7 @@ export async function validateSyncCommitteeGossipContributionAndProof(
106
106
  /**
107
107
  * Retrieve pubkeys in contribution aggregate using epochCtx:
108
108
  * - currSyncCommitteeIndexes cache
109
- * - index2pubkey cache
109
+ * - pubkeyCache
110
110
  */
111
111
  function getContributionIndices(
112
112
  state: CachedBeaconStateAltair,
package/src/db/beacon.ts CHANGED
@@ -15,6 +15,8 @@ import {
15
15
  CheckpointHeaderRepository,
16
16
  DataColumnSidecarArchiveRepository,
17
17
  DataColumnSidecarRepository,
18
+ ExecutionPayloadEnvelopeArchiveRepository,
19
+ ExecutionPayloadEnvelopeRepository,
18
20
  ProposerSlashingRepository,
19
21
  StateArchiveRepository,
20
22
  SyncCommitteeRepository,
@@ -36,6 +38,9 @@ export class BeaconDb implements IBeaconDb {
36
38
  dataColumnSidecar: DataColumnSidecarRepository;
37
39
  dataColumnSidecarArchive: DataColumnSidecarArchiveRepository;
38
40
 
41
+ executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository;
42
+ executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository;
43
+
39
44
  stateArchive: StateArchiveRepository;
40
45
  checkpointState: CheckpointStateRepository;
41
46
 
@@ -65,6 +70,9 @@ export class BeaconDb implements IBeaconDb {
65
70
  this.dataColumnSidecar = new DataColumnSidecarRepository(config, db);
66
71
  this.dataColumnSidecarArchive = new DataColumnSidecarArchiveRepository(config, db);
67
72
 
73
+ this.executionPayloadEnvelope = new ExecutionPayloadEnvelopeRepository(config, db);
74
+ this.executionPayloadEnvelopeArchive = new ExecutionPayloadEnvelopeArchiveRepository(config, db);
75
+
68
76
  this.stateArchive = new StateArchiveRepository(config, db);
69
77
  this.checkpointState = new CheckpointStateRepository(config, db);
70
78
  this.voluntaryExit = new VoluntaryExitRepository(config, db);
package/src/db/buckets.ts CHANGED
@@ -69,6 +69,9 @@ export enum Bucket {
69
69
 
70
70
  fulu_dataColumnSidecars = 57, // FULU BeaconBlockRoot -> DataColumnSidecars
71
71
  fulu_dataColumnSidecarsArchive = 58, // FULU BeaconBlockSlot -> DataColumnSidecars
72
+
73
+ gloas_executionPayloadEnvelope = 59, // GLOAS BeaconBlockRoot -> SignedExecutionPayloadEnvelope
74
+ gloas_executionPayloadEnvelopeArchive = 60, // GLOAS Slot -> SignedExecutionPayloadEnvelope
72
75
  }
73
76
 
74
77
  export function getBucketNameByValue<T extends Bucket>(enumValue: T): keyof typeof Bucket {
@@ -12,6 +12,8 @@ import {
12
12
  CheckpointHeaderRepository,
13
13
  DataColumnSidecarArchiveRepository,
14
14
  DataColumnSidecarRepository,
15
+ ExecutionPayloadEnvelopeArchiveRepository,
16
+ ExecutionPayloadEnvelopeRepository,
15
17
  ProposerSlashingRepository,
16
18
  StateArchiveRepository,
17
19
  SyncCommitteeRepository,
@@ -35,6 +37,9 @@ export interface IBeaconDb {
35
37
  dataColumnSidecar: DataColumnSidecarRepository;
36
38
  dataColumnSidecarArchive: DataColumnSidecarArchiveRepository;
37
39
 
40
+ executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository;
41
+ executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository;
42
+
38
43
  // finalized states
39
44
  stateArchive: StateArchiveRepository;
40
45
  // checkpoint states
@@ -1,7 +1,8 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {Db, PrefixedRepository, decodeNumberForDbKey, encodeNumberForDbKey} from "@lodestar/db";
3
3
  import {NUMBER_OF_COLUMNS} from "@lodestar/params";
4
- import {ColumnIndex, Root, fulu, ssz} from "@lodestar/types";
4
+ import {ColumnIndex, DataColumnSidecar, Root, isGloasDataColumnSidecar, ssz} from "@lodestar/types";
5
+ import {isGloasDataColumnSidecarBytes} from "../../util/multifork.js";
5
6
  import {Bucket, getBucketNameByValue} from "../buckets.js";
6
7
 
7
8
  const COLUMN_INDEX_BYTE_SIZE = 2;
@@ -15,7 +16,7 @@ type BlockRoot = Root;
15
16
  *
16
17
  * Indexed data by `blockRoot` + `columnIndex`
17
18
  */
18
- export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, ColumnIndex, fulu.DataColumnSidecar> {
19
+ export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, ColumnIndex, DataColumnSidecar> {
19
20
  constructor(config: ChainForkConfig, db: Db) {
20
21
  const bucket = Bucket.fulu_dataColumnSidecars;
21
22
  super(config, db, bucket, ssz.fulu.DataColumnSidecar, getBucketNameByValue(bucket));
@@ -24,10 +25,24 @@ export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, C
24
25
  /**
25
26
  * Id is hashTreeRoot of unsigned BeaconBlock
26
27
  */
27
- getId(value: fulu.DataColumnSidecar): ColumnIndex {
28
+ getId(value: DataColumnSidecar): ColumnIndex {
28
29
  return value.index;
29
30
  }
30
31
 
32
+ encodeValue(value: DataColumnSidecar): Uint8Array {
33
+ if (isGloasDataColumnSidecar(value)) {
34
+ return ssz.gloas.DataColumnSidecar.serialize(value);
35
+ }
36
+ return ssz.fulu.DataColumnSidecar.serialize(value);
37
+ }
38
+
39
+ decodeValue(data: Uint8Array): DataColumnSidecar {
40
+ if (isGloasDataColumnSidecarBytes(data)) {
41
+ return ssz.gloas.DataColumnSidecar.deserialize(data);
42
+ }
43
+ return ssz.fulu.DataColumnSidecar.deserialize(data);
44
+ }
45
+
31
46
  encodeKeyRaw(prefix: BlockRoot, id: ColumnIndex): Uint8Array {
32
47
  return Buffer.concat([prefix, encodeNumberForDbKey(id, COLUMN_INDEX_BYTE_SIZE)]);
33
48
  }
@@ -1,7 +1,8 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {Db, PrefixedRepository, decodeNumberForDbKey, encodeNumberForDbKey} from "@lodestar/db";
3
3
  import {NUMBER_OF_COLUMNS} from "@lodestar/params";
4
- import {ColumnIndex, Slot, fulu, ssz} from "@lodestar/types";
4
+ import {ColumnIndex, DataColumnSidecar, Slot, isGloasDataColumnSidecar, ssz} from "@lodestar/types";
5
+ import {isGloasDataColumnSidecarBytes} from "../../util/multifork.js";
5
6
  import {Bucket, getBucketNameByValue} from "../buckets.js";
6
7
 
7
8
  const COLUMN_INDEX_BYTE_SIZE = 2;
@@ -13,7 +14,7 @@ const SLOT_BYTE_SIZE = 8;
13
14
  *
14
15
  * Indexed data by `slot` + `columnIndex`
15
16
  */
16
- export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot, ColumnIndex, fulu.DataColumnSidecar> {
17
+ export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot, ColumnIndex, DataColumnSidecar> {
17
18
  constructor(config: ChainForkConfig, db: Db) {
18
19
  const bucket = Bucket.fulu_dataColumnSidecarsArchive;
19
20
  super(config, db, bucket, ssz.fulu.DataColumnSidecar, getBucketNameByValue(bucket));
@@ -22,10 +23,24 @@ export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot,
22
23
  /**
23
24
  * Id is hashTreeRoot of unsigned BeaconBlock
24
25
  */
25
- getId(value: fulu.DataColumnSidecar): ColumnIndex {
26
+ getId(value: DataColumnSidecar): ColumnIndex {
26
27
  return value.index;
27
28
  }
28
29
 
30
+ encodeValue(value: DataColumnSidecar): Uint8Array {
31
+ if (isGloasDataColumnSidecar(value)) {
32
+ return ssz.gloas.DataColumnSidecar.serialize(value);
33
+ }
34
+ return ssz.fulu.DataColumnSidecar.serialize(value);
35
+ }
36
+
37
+ decodeValue(data: Uint8Array): DataColumnSidecar {
38
+ if (isGloasDataColumnSidecarBytes(data)) {
39
+ return ssz.gloas.DataColumnSidecar.deserialize(data);
40
+ }
41
+ return ssz.fulu.DataColumnSidecar.deserialize(data);
42
+ }
43
+
29
44
  encodeKeyRaw(prefix: Slot, id: ColumnIndex): Uint8Array {
30
45
  return Buffer.concat([
31
46
  encodeNumberForDbKey(prefix, SLOT_BYTE_SIZE),
@@ -0,0 +1,26 @@
1
+ import {ChainForkConfig} from "@lodestar/config";
2
+ import {Db, Repository} from "@lodestar/db";
3
+ import {Root, gloas, ssz} from "@lodestar/types";
4
+ import {Bucket, getBucketNameByValue} from "../buckets.js";
5
+
6
+ type BlockRoot = Root;
7
+
8
+ /**
9
+ * Used to store unfinalized `SignedExecutionPayloadEnvelope`
10
+ *
11
+ * Indexed by beacon block root (root of the beacon block that contains the bid)
12
+ */
13
+ export class ExecutionPayloadEnvelopeRepository extends Repository<BlockRoot, gloas.SignedExecutionPayloadEnvelope> {
14
+ constructor(config: ChainForkConfig, db: Db) {
15
+ const bucket = Bucket.gloas_executionPayloadEnvelope;
16
+ super(config, db, bucket, ssz.gloas.SignedExecutionPayloadEnvelope, getBucketNameByValue(bucket));
17
+ }
18
+
19
+ /**
20
+ * Id is the beacon block root (not execution payload hash)
21
+ * This allows correlation with the block that contains the bid
22
+ */
23
+ getId(value: gloas.SignedExecutionPayloadEnvelope): BlockRoot {
24
+ return value.message.beaconBlockRoot;
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ import {ChainForkConfig} from "@lodestar/config";
2
+ import {BUCKET_LENGTH, Db, Repository, encodeKey as encodeDbKey} from "@lodestar/db";
3
+ import {Slot, gloas, ssz} from "@lodestar/types";
4
+ import {bytesToInt} from "@lodestar/utils";
5
+ import {Bucket, getBucketNameByValue} from "../buckets.js";
6
+
7
+ /**
8
+ * Used to store finalized `SignedExecutionPayloadEnvelope`
9
+ *
10
+ * Indexed by slot for chronological archival
11
+ */
12
+ export class ExecutionPayloadEnvelopeArchiveRepository extends Repository<Slot, gloas.SignedExecutionPayloadEnvelope> {
13
+ constructor(config: ChainForkConfig, db: Db) {
14
+ const bucket = Bucket.gloas_executionPayloadEnvelopeArchive;
15
+ super(config, db, bucket, ssz.gloas.SignedExecutionPayloadEnvelope, getBucketNameByValue(bucket));
16
+ }
17
+
18
+ /**
19
+ * Id is the slot from the envelope
20
+ */
21
+ getId(value: gloas.SignedExecutionPayloadEnvelope): Slot {
22
+ return value.message.slot;
23
+ }
24
+
25
+ encodeKey(id: Slot): Uint8Array {
26
+ return encodeDbKey(this.bucket, id);
27
+ }
28
+
29
+ decodeKey(data: Uint8Array): number {
30
+ return bytesToInt(data.subarray(BUCKET_LENGTH), "be");
31
+ }
32
+ }
@@ -8,6 +8,8 @@ export {BlockArchiveRepository} from "./blockArchive.js";
8
8
  export {BLSToExecutionChangeRepository} from "./blsToExecutionChange.js";
9
9
  export {DataColumnSidecarRepository} from "./dataColumnSidecar.js";
10
10
  export {DataColumnSidecarArchiveRepository} from "./dataColumnSidecarArchive.js";
11
+ export {ExecutionPayloadEnvelopeRepository} from "./executionPayloadEnvelope.js";
12
+ export {ExecutionPayloadEnvelopeArchiveRepository} from "./executionPayloadEnvelopeArchive.js";
11
13
  export {BestLightClientUpdateRepository} from "./lightclientBestUpdate.js";
12
14
  export {CheckpointHeaderRepository} from "./lightclientCheckpointHeader.js";
13
15
  export {SyncCommitteeRepository} from "./lightclientSyncCommittee.js";
@@ -128,6 +128,7 @@ const getClientVersionOpts: ReqOpts = {routeId: "getClientVersion"};
128
128
  */
129
129
  export class ExecutionEngineHttp implements IExecutionEngine {
130
130
  private logger: Logger;
131
+ private metrics: Metrics | null;
131
132
 
132
133
  // The default state is ONLINE, it will be updated to SYNCING once we receive the first payload
133
134
  // This assumption is better than the OFFLINE state, since we can't be sure if the EL is offline and being offline may trigger some notifications
@@ -167,6 +168,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
167
168
  metrics?.engineHttpProcessorQueue
168
169
  );
169
170
  this.logger = logger;
171
+ this.metrics = metrics ?? null;
170
172
 
171
173
  this.rpc.emitter.on(JsonRpcHttpClientEvent.ERROR, ({error}) => {
172
174
  this.updateEngineState(getExecutionEngineState({payloadError: error, oldState: this.state}));
@@ -369,6 +371,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
369
371
  } = await request;
370
372
 
371
373
  this.updateEngineState(getExecutionEngineState({payloadStatus: status, oldState: this.state}));
374
+ this.metrics?.engineNotifyForkchoiceUpdateResult.inc({result: status});
372
375
 
373
376
  switch (status) {
374
377
  case ExecutionPayloadStatus.VALID:
@@ -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
 
@@ -4,6 +4,7 @@ import {PeerIdStr} from "@chainsafe/libp2p-gossipsub/types";
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]: fulu.DataColumnSidecar;
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: fulu.DataColumnSidecar) => Promise<void> | void;
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;
@@ -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:
@@ -19,6 +19,7 @@ import type {Datastore} from "interface-datastore";
19
19
  import {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: fulu.DataColumnSidecar): Promise<number>;
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[]>;
@@ -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: fulu.DataColumnSidecar): Promise<number> {
358
- const epoch = computeEpochAtSlot(dataColumnSidecar.signedBlockHeader.message.slot);
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: fulu.DataColumnSidecar[]): Promise<number[]> => {
786
+ private onPublishDataColumns = (sidecars: DataColumnSidecars): Promise<number[]> => {
769
787
  return promiseAllMaybeAsync(sidecars.map((sidecar) => () => this.publishDataColumnSidecar(sidecar)));
770
788
  };
771
789