@lodestar/beacon-node 1.40.0-dev.c7b6a784da → 1.40.0-dev.cfd894719f

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 (229) hide show
  1. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  2. package/lib/chain/blocks/verifyBlock.js +1 -1
  3. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  4. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  5. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  6. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  7. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  8. package/lib/chain/bls/multithread/index.d.ts +3 -1
  9. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  10. package/lib/chain/bls/multithread/index.js +5 -3
  11. package/lib/chain/bls/multithread/index.js.map +1 -1
  12. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  13. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  14. package/lib/chain/bls/multithread/jobItem.js +2 -2
  15. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  16. package/lib/chain/bls/singleThread.d.ts +4 -2
  17. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  18. package/lib/chain/bls/singleThread.js +4 -2
  19. package/lib/chain/bls/singleThread.js.map +1 -1
  20. package/lib/chain/bls/utils.d.ts +2 -2
  21. package/lib/chain/bls/utils.d.ts.map +1 -1
  22. package/lib/chain/bls/utils.js +9 -6
  23. package/lib/chain/bls/utils.js.map +1 -1
  24. package/lib/chain/chain.d.ts +7 -2
  25. package/lib/chain/chain.d.ts.map +1 -1
  26. package/lib/chain/chain.js +22 -5
  27. package/lib/chain/chain.js.map +1 -1
  28. package/lib/chain/errors/attestationError.d.ts +14 -1
  29. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  30. package/lib/chain/errors/attestationError.js +8 -0
  31. package/lib/chain/errors/attestationError.js.map +1 -1
  32. package/lib/chain/errors/executionPayloadBid.d.ts +48 -0
  33. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -0
  34. package/lib/chain/errors/executionPayloadBid.js +15 -0
  35. package/lib/chain/errors/executionPayloadBid.js.map +1 -0
  36. package/lib/chain/errors/executionPayloadEnvelope.d.ts +48 -0
  37. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -0
  38. package/lib/chain/errors/executionPayloadEnvelope.js +16 -0
  39. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -0
  40. package/lib/chain/errors/index.d.ts +3 -0
  41. package/lib/chain/errors/index.d.ts.map +1 -1
  42. package/lib/chain/errors/index.js +3 -0
  43. package/lib/chain/errors/index.js.map +1 -1
  44. package/lib/chain/errors/payloadAttestation.d.ts +34 -0
  45. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -0
  46. package/lib/chain/errors/payloadAttestation.js +13 -0
  47. package/lib/chain/errors/payloadAttestation.js.map +1 -0
  48. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  49. package/lib/chain/forkChoice/index.js +18 -0
  50. package/lib/chain/forkChoice/index.js.map +1 -1
  51. package/lib/chain/interface.d.ts +7 -2
  52. package/lib/chain/interface.d.ts.map +1 -1
  53. package/lib/chain/interface.js.map +1 -1
  54. package/lib/chain/opPools/executionPayloadBidPool.d.ts +21 -0
  55. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -0
  56. package/lib/chain/opPools/executionPayloadBidPool.js +57 -0
  57. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -0
  58. package/lib/chain/opPools/index.d.ts +2 -0
  59. package/lib/chain/opPools/index.d.ts.map +1 -1
  60. package/lib/chain/opPools/index.js +2 -0
  61. package/lib/chain/opPools/index.js.map +1 -1
  62. package/lib/chain/opPools/payloadAttestationPool.d.ts +24 -0
  63. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -0
  64. package/lib/chain/opPools/payloadAttestationPool.js +109 -0
  65. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -0
  66. package/lib/chain/regen/interface.d.ts +1 -0
  67. package/lib/chain/regen/interface.d.ts.map +1 -1
  68. package/lib/chain/regen/interface.js +1 -0
  69. package/lib/chain/regen/interface.js.map +1 -1
  70. package/lib/chain/seenCache/index.d.ts +3 -1
  71. package/lib/chain/seenCache/index.d.ts.map +1 -1
  72. package/lib/chain/seenCache/index.js +3 -1
  73. package/lib/chain/seenCache/index.js.map +1 -1
  74. package/lib/chain/seenCache/seenAttesters.d.ts +5 -0
  75. package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
  76. package/lib/chain/seenCache/seenAttesters.js +5 -0
  77. package/lib/chain/seenCache/seenAttesters.js.map +1 -1
  78. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts +12 -0
  79. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts.map +1 -0
  80. package/lib/chain/seenCache/seenExecutionPayloadBids.js +30 -0
  81. package/lib/chain/seenCache/seenExecutionPayloadBids.js.map +1 -0
  82. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +15 -0
  83. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +1 -0
  84. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +28 -0
  85. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +1 -0
  86. package/lib/chain/validation/aggregateAndProof.js +35 -14
  87. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  88. package/lib/chain/validation/attestation.d.ts +2 -2
  89. package/lib/chain/validation/attestation.d.ts.map +1 -1
  90. package/lib/chain/validation/attestation.js +27 -8
  91. package/lib/chain/validation/attestation.js.map +1 -1
  92. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  93. package/lib/chain/validation/attesterSlashing.js +1 -1
  94. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  95. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  96. package/lib/chain/validation/blobSidecar.js +2 -2
  97. package/lib/chain/validation/blobSidecar.js.map +1 -1
  98. package/lib/chain/validation/block.d.ts.map +1 -1
  99. package/lib/chain/validation/block.js +5 -4
  100. package/lib/chain/validation/block.js.map +1 -1
  101. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  102. package/lib/chain/validation/dataColumnSidecar.js +2 -2
  103. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  104. package/lib/chain/validation/executionPayloadBid.d.ts +5 -0
  105. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -0
  106. package/lib/chain/validation/executionPayloadBid.js +103 -0
  107. package/lib/chain/validation/executionPayloadBid.js.map +1 -0
  108. package/lib/chain/validation/executionPayloadEnvelope.d.ts +5 -0
  109. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -0
  110. package/lib/chain/validation/executionPayloadEnvelope.js +89 -0
  111. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -0
  112. package/lib/chain/validation/payloadAttestationMessage.d.ts +9 -0
  113. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -0
  114. package/lib/chain/validation/payloadAttestationMessage.js +72 -0
  115. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -0
  116. package/lib/chain/validation/proposerSlashing.js +1 -1
  117. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  118. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
  119. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
  120. package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
  121. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  122. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  123. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  124. package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
  125. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  126. package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
  127. package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
  128. package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
  129. package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
  130. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  131. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  132. package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
  133. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  134. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  135. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  136. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  137. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  138. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  139. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  140. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  141. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  142. package/lib/chain/validation/syncCommittee.js +1 -1
  143. package/lib/chain/validation/syncCommittee.js.map +1 -1
  144. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  145. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
  146. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  147. package/lib/chain/validation/voluntaryExit.js +1 -1
  148. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  149. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  150. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  151. package/lib/metrics/metrics/lodestar.js +40 -0
  152. package/lib/metrics/metrics/lodestar.js.map +1 -1
  153. package/lib/network/gossip/interface.d.ts +20 -2
  154. package/lib/network/gossip/interface.d.ts.map +1 -1
  155. package/lib/network/gossip/interface.js +3 -0
  156. package/lib/network/gossip/interface.js.map +1 -1
  157. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  158. package/lib/network/gossip/scoringParameters.js +38 -2
  159. package/lib/network/gossip/scoringParameters.js.map +1 -1
  160. package/lib/network/gossip/topic.d.ts +77 -1
  161. package/lib/network/gossip/topic.d.ts.map +1 -1
  162. package/lib/network/gossip/topic.js +20 -0
  163. package/lib/network/gossip/topic.js.map +1 -1
  164. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  165. package/lib/network/processor/gossipHandlers.js +34 -0
  166. package/lib/network/processor/gossipHandlers.js.map +1 -1
  167. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  168. package/lib/network/processor/gossipQueues/index.js +16 -0
  169. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  170. package/lib/network/processor/index.d.ts.map +1 -1
  171. package/lib/network/processor/index.js +3 -0
  172. package/lib/network/processor/index.js.map +1 -1
  173. package/lib/sync/backfill/backfill.js +2 -2
  174. package/lib/sync/backfill/backfill.js.map +1 -1
  175. package/lib/sync/backfill/verify.d.ts +1 -2
  176. package/lib/sync/backfill/verify.d.ts.map +1 -1
  177. package/lib/sync/backfill/verify.js +2 -2
  178. package/lib/sync/backfill/verify.js.map +1 -1
  179. package/package.json +15 -15
  180. package/src/chain/blocks/verifyBlock.ts +0 -1
  181. package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
  182. package/src/chain/bls/multithread/index.ts +7 -4
  183. package/src/chain/bls/multithread/jobItem.ts +7 -3
  184. package/src/chain/bls/singleThread.ts +5 -3
  185. package/src/chain/bls/utils.ts +15 -7
  186. package/src/chain/chain.ts +25 -3
  187. package/src/chain/errors/attestationError.ts +11 -1
  188. package/src/chain/errors/executionPayloadBid.ts +35 -0
  189. package/src/chain/errors/executionPayloadEnvelope.ts +34 -0
  190. package/src/chain/errors/index.ts +3 -0
  191. package/src/chain/errors/payloadAttestation.ts +25 -0
  192. package/src/chain/forkChoice/index.ts +19 -0
  193. package/src/chain/interface.ts +16 -1
  194. package/src/chain/opPools/executionPayloadBidPool.ts +77 -0
  195. package/src/chain/opPools/index.ts +2 -0
  196. package/src/chain/opPools/payloadAttestationPool.ts +157 -0
  197. package/src/chain/regen/interface.ts +1 -0
  198. package/src/chain/seenCache/index.ts +3 -1
  199. package/src/chain/seenCache/seenAttesters.ts +5 -0
  200. package/src/chain/seenCache/seenExecutionPayloadBids.ts +35 -0
  201. package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +34 -0
  202. package/src/chain/validation/aggregateAndProof.ts +36 -14
  203. package/src/chain/validation/attestation.ts +33 -16
  204. package/src/chain/validation/attesterSlashing.ts +1 -6
  205. package/src/chain/validation/blobSidecar.ts +1 -6
  206. package/src/chain/validation/block.ts +5 -4
  207. package/src/chain/validation/dataColumnSidecar.ts +1 -6
  208. package/src/chain/validation/executionPayloadBid.ts +140 -0
  209. package/src/chain/validation/executionPayloadEnvelope.ts +122 -0
  210. package/src/chain/validation/payloadAttestationMessage.ts +109 -0
  211. package/src/chain/validation/proposerSlashing.ts +1 -6
  212. package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
  213. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
  214. package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
  215. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
  216. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
  217. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
  218. package/src/chain/validation/syncCommittee.ts +1 -1
  219. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
  220. package/src/chain/validation/voluntaryExit.ts +1 -1
  221. package/src/metrics/metrics/lodestar.ts +40 -0
  222. package/src/network/gossip/interface.ts +17 -0
  223. package/src/network/gossip/scoringParameters.ts +44 -2
  224. package/src/network/gossip/topic.ts +21 -0
  225. package/src/network/processor/gossipHandlers.ts +48 -0
  226. package/src/network/processor/gossipQueues/index.ts +16 -0
  227. package/src/network/processor/index.ts +3 -0
  228. package/src/sync/backfill/backfill.ts +2 -2
  229. package/src/sync/backfill/verify.ts +2 -3
@@ -0,0 +1,109 @@
1
+ import {
2
+ CachedBeaconStateGloas,
3
+ computeEpochAtSlot,
4
+ createSingleSignatureSetFromComponents,
5
+ getPayloadAttestationDataSigningRoot,
6
+ } from "@lodestar/state-transition";
7
+ import {RootHex, gloas, ssz} from "@lodestar/types";
8
+ import {toRootHex} from "@lodestar/utils";
9
+ import {GossipAction, PayloadAttestationError, PayloadAttestationErrorCode} from "../errors/index.js";
10
+ import {IBeaconChain} from "../index.js";
11
+
12
+ export type PayloadAttestationValidationResult = {
13
+ attDataRootHex: RootHex;
14
+ validatorCommitteeIndex: number;
15
+ };
16
+
17
+ export async function validateApiPayloadAttestationMessage(
18
+ chain: IBeaconChain,
19
+ payloadAttestationMessage: gloas.PayloadAttestationMessage
20
+ ): Promise<PayloadAttestationValidationResult> {
21
+ return validatePayloadAttestationMessage(chain, payloadAttestationMessage);
22
+ }
23
+
24
+ export async function validateGossipPayloadAttestationMessage(
25
+ chain: IBeaconChain,
26
+ payloadAttestationMessage: gloas.PayloadAttestationMessage
27
+ ): Promise<PayloadAttestationValidationResult> {
28
+ return validatePayloadAttestationMessage(chain, payloadAttestationMessage);
29
+ }
30
+
31
+ async function validatePayloadAttestationMessage(
32
+ chain: IBeaconChain,
33
+ payloadAttestationMessage: gloas.PayloadAttestationMessage
34
+ ): Promise<PayloadAttestationValidationResult> {
35
+ const {data, validatorIndex} = payloadAttestationMessage;
36
+ const epoch = computeEpochAtSlot(data.slot);
37
+
38
+ // [IGNORE] The message's slot is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e. `data.slot == current_slot`.
39
+ if (!chain.clock.isCurrentSlotGivenGossipDisparity(data.slot)) {
40
+ throw new PayloadAttestationError(GossipAction.IGNORE, {
41
+ code: PayloadAttestationErrorCode.NOT_CURRENT_SLOT,
42
+ currentSlot: chain.clock.currentSlot,
43
+ slot: data.slot,
44
+ });
45
+ }
46
+
47
+ // [IGNORE] The `payload_attestation_message` is the first valid message received
48
+ // from the validator with index `payload_attestation_message.validator_index`.
49
+ // A single validator can participate PTC at most once per epoch
50
+ if (chain.seenPayloadAttesters.isKnown(epoch, validatorIndex)) {
51
+ throw new PayloadAttestationError(GossipAction.IGNORE, {
52
+ code: PayloadAttestationErrorCode.PAYLOAD_ATTESTATION_ALREADY_KNOWN,
53
+ validatorIndex,
54
+ slot: data.slot,
55
+ blockRoot: toRootHex(data.beaconBlockRoot),
56
+ });
57
+ }
58
+
59
+ // [IGNORE] The message's block `data.beacon_block_root` has been seen (via
60
+ // gossip or non-gossip sources) (a client MAY queue attestation for processing
61
+ // once the block is retrieved. Note a client might want to request payload after).
62
+ const block = chain.forkChoice.getBlock(data.beaconBlockRoot);
63
+ if (block === null) {
64
+ throw new PayloadAttestationError(GossipAction.IGNORE, {
65
+ code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT,
66
+ blockRoot: toRootHex(data.beaconBlockRoot),
67
+ });
68
+ }
69
+
70
+ const state = chain.getHeadState() as CachedBeaconStateGloas;
71
+
72
+ // [REJECT] The message's block `data.beacon_block_root` passes validation.
73
+ // TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice,
74
+ // it is possible that the block didn't pass the validation
75
+
76
+ // [REJECT] The message's validator index is within the payload committee in
77
+ // `get_ptc(state, data.slot)`. The `state` is the head state corresponding to
78
+ // processing the block up to the current slot as determined by the fork choice.
79
+ const ptc = state.epochCtx.getPayloadTimelinessCommittee(data.slot);
80
+ const validatorCommitteeIndex = ptc.indexOf(validatorIndex);
81
+
82
+ if (validatorCommitteeIndex === -1) {
83
+ throw new PayloadAttestationError(GossipAction.REJECT, {
84
+ code: PayloadAttestationErrorCode.INVALID_ATTESTER,
85
+ attesterIndex: validatorIndex,
86
+ });
87
+ }
88
+
89
+ // [REJECT] `payload_attestation_message.signature` is valid with respect to the validator's public key.
90
+ const signatureSet = createSingleSignatureSetFromComponents(
91
+ chain.index2pubkey[validatorIndex],
92
+ getPayloadAttestationDataSigningRoot(state, data),
93
+ payloadAttestationMessage.signature
94
+ );
95
+
96
+ if (!(await chain.bls.verifySignatureSets([signatureSet]))) {
97
+ throw new PayloadAttestationError(GossipAction.REJECT, {
98
+ code: PayloadAttestationErrorCode.INVALID_SIGNATURE,
99
+ });
100
+ }
101
+
102
+ // Valid
103
+ chain.seenPayloadAttesters.add(epoch, validatorIndex);
104
+
105
+ return {
106
+ attDataRootHex: toRootHex(ssz.gloas.PayloadAttestationData.hashTreeRoot(data)),
107
+ validatorCommitteeIndex,
108
+ };
109
+ }
@@ -45,12 +45,7 @@ async function validateProposerSlashing(
45
45
  });
46
46
  }
47
47
 
48
- const signatureSets = getProposerSlashingSignatureSets(
49
- chain.config,
50
- chain.index2pubkey,
51
- state.slot,
52
- proposerSlashing
53
- );
48
+ const signatureSets = getProposerSlashingSignatureSets(chain.config, state.slot, proposerSlashing);
54
49
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
55
50
  throw new ProposerSlashingError(GossipAction.REJECT, {
56
51
  code: ProposerSlashingErrorCode.INVALID,
@@ -1,13 +1,7 @@
1
- import {PublicKey} from "@chainsafe/blst";
2
1
  import {BeaconConfig} from "@lodestar/config";
3
2
  import {DOMAIN_AGGREGATE_AND_PROOF, ForkSeq} from "@lodestar/params";
4
- import {
5
- ISignatureSet,
6
- computeSigningRoot,
7
- computeStartSlotAtEpoch,
8
- createSingleSignatureSetFromComponents,
9
- } from "@lodestar/state-transition";
10
- import {Epoch, SignedAggregateAndProof, ssz} from "@lodestar/types";
3
+ import {ISignatureSet, SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
4
+ import {Epoch, SignedAggregateAndProof, ValidatorIndex, ssz} from "@lodestar/types";
11
5
 
12
6
  export function getAggregateAndProofSigningRoot(
13
7
  config: BeaconConfig,
@@ -27,12 +21,13 @@ export function getAggregateAndProofSigningRoot(
27
21
  export function getAggregateAndProofSignatureSet(
28
22
  config: BeaconConfig,
29
23
  epoch: Epoch,
30
- aggregator: PublicKey,
24
+ aggregatorIndex: ValidatorIndex,
31
25
  aggregateAndProof: SignedAggregateAndProof
32
26
  ): ISignatureSet {
33
- return createSingleSignatureSetFromComponents(
34
- aggregator,
35
- getAggregateAndProofSigningRoot(config, epoch, aggregateAndProof),
36
- aggregateAndProof.signature
37
- );
27
+ return {
28
+ type: SignatureSetType.indexed,
29
+ index: aggregatorIndex,
30
+ signingRoot: getAggregateAndProofSigningRoot(config, epoch, aggregateAndProof),
31
+ signature: aggregateAndProof.signature,
32
+ };
38
33
  }
@@ -3,7 +3,6 @@ import {DOMAIN_CONTRIBUTION_AND_PROOF} from "@lodestar/params";
3
3
  import {
4
4
  CachedBeaconStateAllForks,
5
5
  ISignatureSet,
6
- Index2PubkeyCache,
7
6
  SignatureSetType,
8
7
  computeSigningRoot,
9
8
  } from "@lodestar/state-transition";
@@ -11,7 +10,6 @@ import {altair, ssz} from "@lodestar/types";
11
10
 
12
11
  export function getContributionAndProofSignatureSet(
13
12
  config: BeaconConfig,
14
- index2pubkey: Index2PubkeyCache,
15
13
  state: CachedBeaconStateAllForks,
16
14
  signedContributionAndProof: altair.SignedContributionAndProof
17
15
  ): ISignatureSet {
@@ -22,8 +20,8 @@ export function getContributionAndProofSignatureSet(
22
20
  );
23
21
  const signingData = signedContributionAndProof.message;
24
22
  return {
25
- type: SignatureSetType.single,
26
- pubkey: index2pubkey[signedContributionAndProof.message.aggregatorIndex],
23
+ type: SignatureSetType.indexed,
24
+ index: signedContributionAndProof.message.aggregatorIndex,
27
25
  signingRoot: computeSigningRoot(ssz.altair.ContributionAndProof, signingData, domain),
28
26
  signature: signedContributionAndProof.signature,
29
27
  };
@@ -1,8 +1,7 @@
1
- import {PublicKey} from "@chainsafe/blst";
2
1
  import {BeaconConfig} from "@lodestar/config";
3
2
  import {DOMAIN_SELECTION_PROOF} from "@lodestar/params";
4
- import {ISignatureSet, computeSigningRoot, createSingleSignatureSetFromComponents} from "@lodestar/state-transition";
5
- import {Slot, phase0, ssz} from "@lodestar/types";
3
+ import {ISignatureSet, SignatureSetType, computeSigningRoot} from "@lodestar/state-transition";
4
+ import {Slot, ValidatorIndex, phase0, ssz} from "@lodestar/types";
6
5
 
7
6
  export function getSelectionProofSigningRoot(config: BeaconConfig, slot: Slot): Uint8Array {
8
7
  // previously, we call `const selectionProofDomain = config.getDomain(state.slot, DOMAIN_SELECTION_PROOF, slot)`
@@ -16,12 +15,13 @@ export function getSelectionProofSigningRoot(config: BeaconConfig, slot: Slot):
16
15
  export function getSelectionProofSignatureSet(
17
16
  config: BeaconConfig,
18
17
  slot: Slot,
19
- aggregator: PublicKey,
18
+ aggregatorIndex: ValidatorIndex,
20
19
  aggregateAndProof: phase0.SignedAggregateAndProof
21
20
  ): ISignatureSet {
22
- return createSingleSignatureSetFromComponents(
23
- aggregator,
24
- getSelectionProofSigningRoot(config, slot),
25
- aggregateAndProof.message.selectionProof
26
- );
21
+ return {
22
+ type: SignatureSetType.indexed,
23
+ index: aggregatorIndex,
24
+ signingRoot: getSelectionProofSigningRoot(config, slot),
25
+ signature: aggregateAndProof.message.selectionProof,
26
+ };
27
27
  }
@@ -3,7 +3,6 @@ import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
3
3
  import {
4
4
  CachedBeaconStateAllForks,
5
5
  ISignatureSet,
6
- Index2PubkeyCache,
7
6
  SignatureSetType,
8
7
  computeSigningRoot,
9
8
  } from "@lodestar/state-transition";
@@ -11,15 +10,14 @@ import {altair, ssz} from "@lodestar/types";
11
10
 
12
11
  export function getSyncCommitteeSignatureSet(
13
12
  config: BeaconConfig,
14
- index2pubkey: Index2PubkeyCache,
15
13
  state: CachedBeaconStateAllForks,
16
14
  syncCommittee: altair.SyncCommitteeMessage
17
15
  ): ISignatureSet {
18
16
  const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, syncCommittee.slot);
19
17
 
20
18
  return {
21
- type: SignatureSetType.single,
22
- pubkey: index2pubkey[syncCommittee.validatorIndex],
19
+ type: SignatureSetType.indexed,
20
+ index: syncCommittee.validatorIndex,
23
21
  signingRoot: computeSigningRoot(ssz.Root, syncCommittee.beaconBlockRoot, domain),
24
22
  signature: syncCommittee.signature,
25
23
  };
@@ -1,4 +1,3 @@
1
- import {PublicKey} from "@chainsafe/blst";
2
1
  import {BeaconConfig} from "@lodestar/config";
3
2
  import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
4
3
  import {CachedBeaconStateAltair, ISignatureSet, SignatureSetType, computeSigningRoot} from "@lodestar/state-transition";
@@ -8,12 +7,12 @@ export function getSyncCommitteeContributionSignatureSet(
8
7
  config: BeaconConfig,
9
8
  state: CachedBeaconStateAltair,
10
9
  contribution: altair.SyncCommitteeContribution,
11
- pubkeys: PublicKey[]
10
+ participantIndices: number[]
12
11
  ): ISignatureSet {
13
12
  const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, contribution.slot);
14
13
  return {
15
14
  type: SignatureSetType.aggregate,
16
- pubkeys,
15
+ indices: participantIndices,
17
16
  signingRoot: computeSigningRoot(ssz.Root, contribution.beaconBlockRoot, domain),
18
17
  signature: contribution.signature,
19
18
  };
@@ -3,7 +3,6 @@ import {DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF} from "@lodestar/params";
3
3
  import {
4
4
  CachedBeaconStateAllForks,
5
5
  ISignatureSet,
6
- Index2PubkeyCache,
7
6
  SignatureSetType,
8
7
  computeSigningRoot,
9
8
  } from "@lodestar/state-transition";
@@ -11,7 +10,6 @@ import {altair, ssz} from "@lodestar/types";
11
10
 
12
11
  export function getSyncCommitteeSelectionProofSignatureSet(
13
12
  config: BeaconConfig,
14
- index2pubkey: Index2PubkeyCache,
15
13
  state: CachedBeaconStateAllForks,
16
14
  contributionAndProof: altair.ContributionAndProof
17
15
  ): ISignatureSet {
@@ -22,8 +20,8 @@ export function getSyncCommitteeSelectionProofSignatureSet(
22
20
  subcommitteeIndex: contributionAndProof.contribution.subcommitteeIndex,
23
21
  };
24
22
  return {
25
- type: SignatureSetType.single,
26
- pubkey: index2pubkey[contributionAndProof.aggregatorIndex],
23
+ type: SignatureSetType.indexed,
24
+ index: contributionAndProof.aggregatorIndex,
27
25
  signingRoot: computeSigningRoot(ssz.altair.SyncAggregatorSelectionData, signingData, domain),
28
26
  signature: contributionAndProof.selectionProof,
29
27
  };
@@ -89,7 +89,7 @@ async function validateSyncCommitteeSigOnly(
89
89
  syncCommittee: altair.SyncCommitteeMessage,
90
90
  prioritizeBls = false
91
91
  ): Promise<void> {
92
- const signatureSet = getSyncCommitteeSignatureSet(chain.config, chain.index2pubkey, headState, syncCommittee);
92
+ const signatureSet = getSyncCommitteeSignatureSet(chain.config, headState, syncCommittee);
93
93
  if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
94
94
  throw new SyncCommitteeError(GossipAction.REJECT, {
95
95
  code: SyncCommitteeErrorCode.INVALID_SIGNATURE,
@@ -21,7 +21,6 @@ export async function validateSyncCommitteeGossipContributionAndProof(
21
21
  const contributionAndProof = signedContributionAndProof.message;
22
22
  const {contribution, aggregatorIndex} = contributionAndProof;
23
23
  const {subcommitteeIndex, slot} = contribution;
24
- const {index2pubkey} = chain;
25
24
 
26
25
  const headState = chain.getHeadState();
27
26
  validateGossipSyncCommitteeExceptSig(chain, headState, subcommitteeIndex, {
@@ -74,14 +73,13 @@ export async function validateSyncCommitteeGossipContributionAndProof(
74
73
  // i.e. state.validators[contribution_and_proof.aggregator_index].pubkey in get_sync_subcommittee_pubkeys(state, contribution.subcommittee_index).
75
74
  // > Checked in validateGossipSyncCommitteeExceptSig()
76
75
 
77
- const participantPubkeys = syncCommitteeParticipantIndices.map((validatorIndex) => index2pubkey[validatorIndex]);
78
76
  const signatureSets = [
79
77
  // [REJECT] The contribution_and_proof.selection_proof is a valid signature of the SyncAggregatorSelectionData
80
78
  // derived from the contribution by the validator with index contribution_and_proof.aggregator_index.
81
- getSyncCommitteeSelectionProofSignatureSet(chain.config, index2pubkey, headState, contributionAndProof),
79
+ getSyncCommitteeSelectionProofSignatureSet(chain.config, headState, contributionAndProof),
82
80
 
83
81
  // [REJECT] The aggregator signature, signed_contribution_and_proof.signature, is valid.
84
- getContributionAndProofSignatureSet(chain.config, index2pubkey, headState, signedContributionAndProof),
82
+ getContributionAndProofSignatureSet(chain.config, headState, signedContributionAndProof),
85
83
 
86
84
  // [REJECT] The aggregate signature is valid for the message beacon_block_root and aggregate pubkey derived from
87
85
  // the participation info in aggregation_bits for the subcommittee specified by the contribution.subcommittee_index.
@@ -89,7 +87,7 @@ export async function validateSyncCommitteeGossipContributionAndProof(
89
87
  chain.config,
90
88
  headState as CachedBeaconStateAltair,
91
89
  contribution,
92
- participantPubkeys
90
+ syncCommitteeParticipantIndices
93
91
  ),
94
92
  ];
95
93
 
@@ -59,7 +59,7 @@ async function validateVoluntaryExit(
59
59
  });
60
60
  }
61
61
 
62
- const signatureSet = getVoluntaryExitSignatureSet(chain.config, chain.index2pubkey, state.slot, voluntaryExit);
62
+ const signatureSet = getVoluntaryExitSignatureSet(chain.config, state.slot, voluntaryExit);
63
63
  if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
64
64
  throw new VoluntaryExitError(GossipAction.REJECT, {
65
65
  code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
@@ -1141,6 +1141,46 @@ export function createLodestarMetrics(
1141
1141
  help: "Total number of empty returns in SyncContributionAndProofPool.getAggregate(slot, root)",
1142
1142
  }),
1143
1143
  },
1144
+ payloadAttestationPool: {
1145
+ size: register.gauge({
1146
+ name: "lodestar_oppool_payload_attestation_pool_size",
1147
+ help: "Current size of the PayloadAttestationPool = total payload attestations unique by data and slot",
1148
+ }),
1149
+ payloadAttDataPerSlot: register.gauge({
1150
+ name: "lodestar_oppool_payload_attestation_pool_payload_attestation_data_per_slot_total",
1151
+ help: "Total number of payload attestation data per slot in PayloadAttestationPool",
1152
+ }),
1153
+ gossipInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1154
+ name: "lodestar_oppool_payload_attestation_pool_gossip_insert_outcome_total",
1155
+ help: "Total number of InsertOutcome as a result of adding a payload attestation message from gossip to the pool",
1156
+ labelNames: ["insertOutcome"],
1157
+ }),
1158
+ apiInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1159
+ name: "lodestar_oppool_payload_attestation_pool_api_insert_outcome_total",
1160
+ help: "Total number of InsertOutcome as a result of adding a payload attestation message from api to the pool",
1161
+ labelNames: ["insertOutcome"],
1162
+ }),
1163
+ getPayloadAttestationsCacheMisses: register.counter({
1164
+ name: "lodestar_oppool_payload_attestation_pool_get_payload_attestations_cache_misses_total",
1165
+ help: "Total number of getPayloadAttestationsForBlock calls with no aggregate for slot and payload attestation data root",
1166
+ }),
1167
+ },
1168
+ executionPayloadBidPool: {
1169
+ size: register.gauge({
1170
+ name: "lodestar_oppool_execution_payload_bid_pool_size",
1171
+ help: "Current size of the ExecutionPayloadBidPool = total number of bids",
1172
+ }),
1173
+ gossipInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1174
+ name: "lodestar_oppool_execution_payload_bid_pool_gossip_insert_outcome_total",
1175
+ help: "Total number of InsertOutcome as a result of adding an execution payload bid from gossip to the pool",
1176
+ labelNames: ["insertOutcome"],
1177
+ }),
1178
+ apiInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1179
+ name: "lodestar_oppool_execution_payload_bid_pool_api_insert_outcome_total",
1180
+ help: "Total number of InsertOutcome as a result of adding an execution payload bid from api to the pool",
1181
+ labelNames: ["insertOutcome"],
1182
+ }),
1183
+ },
1144
1184
  },
1145
1185
 
1146
1186
  chain: {
@@ -15,6 +15,7 @@ import {
15
15
  capella,
16
16
  deneb,
17
17
  fulu,
18
+ gloas,
18
19
  phase0,
19
20
  } from "@lodestar/types";
20
21
  import {Logger} from "@lodestar/utils";
@@ -37,6 +38,9 @@ export enum GossipType {
37
38
  light_client_finality_update = "light_client_finality_update",
38
39
  light_client_optimistic_update = "light_client_optimistic_update",
39
40
  bls_to_execution_change = "bls_to_execution_change",
41
+ execution_payload = "execution_payload",
42
+ payload_attestation_message = "payload_attestation_message",
43
+ execution_payload_bid = "execution_payload_bid",
40
44
  }
41
45
 
42
46
  export type SequentialGossipType = Exclude<GossipType, GossipType.beacon_attestation>;
@@ -71,6 +75,9 @@ export type GossipTopicTypeMap = {
71
75
  [GossipType.light_client_finality_update]: {type: GossipType.light_client_finality_update};
72
76
  [GossipType.light_client_optimistic_update]: {type: GossipType.light_client_optimistic_update};
73
77
  [GossipType.bls_to_execution_change]: {type: GossipType.bls_to_execution_change};
78
+ [GossipType.execution_payload]: {type: GossipType.execution_payload};
79
+ [GossipType.payload_attestation_message]: {type: GossipType.payload_attestation_message};
80
+ [GossipType.execution_payload_bid]: {type: GossipType.execution_payload_bid};
74
81
  };
75
82
 
76
83
  export type GossipTopicMap = {
@@ -100,6 +107,9 @@ export type GossipTypeMap = {
100
107
  [GossipType.light_client_finality_update]: LightClientFinalityUpdate;
101
108
  [GossipType.light_client_optimistic_update]: LightClientOptimisticUpdate;
102
109
  [GossipType.bls_to_execution_change]: capella.SignedBLSToExecutionChange;
110
+ [GossipType.execution_payload]: gloas.SignedExecutionPayloadEnvelope;
111
+ [GossipType.payload_attestation_message]: gloas.PayloadAttestationMessage;
112
+ [GossipType.execution_payload_bid]: gloas.SignedExecutionPayloadBid;
103
113
  };
104
114
 
105
115
  export type GossipFnByType = {
@@ -124,6 +134,13 @@ export type GossipFnByType = {
124
134
  [GossipType.bls_to_execution_change]: (
125
135
  blsToExecutionChange: capella.SignedBLSToExecutionChange
126
136
  ) => Promise<void> | void;
137
+ [GossipType.execution_payload]: (
138
+ executionPayloadEnvelope: gloas.SignedExecutionPayloadEnvelope
139
+ ) => Promise<void> | void;
140
+ [GossipType.payload_attestation_message]: (
141
+ payloadAttestationMessage: gloas.PayloadAttestationMessage
142
+ ) => Promise<void> | void;
143
+ [GossipType.execution_payload_bid]: (executionPayloadBid: gloas.SignedExecutionPayloadBid) => Promise<void> | void;
127
144
  };
128
145
 
129
146
  export type GossipFn = GossipFnByType[keyof GossipFnByType];
@@ -5,7 +5,7 @@ import {
5
5
  defaultTopicScoreParams,
6
6
  } from "@chainsafe/libp2p-gossipsub/score";
7
7
  import {BeaconConfig} from "@lodestar/config";
8
- import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, TARGET_AGGREGATORS_PER_COMMITTEE} from "@lodestar/params";
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";
10
10
  import {getActiveForkBoundaries} from "../forks.js";
11
11
  import {Eth2Context} from "./gossipsub.js";
@@ -24,6 +24,9 @@ const VOLUNTARY_EXIT_WEIGHT = 0.05;
24
24
  const PROPOSER_SLASHING_WEIGHT = 0.05;
25
25
  const ATTESTER_SLASHING_WEIGHT = 0.05;
26
26
  const BLS_TO_EXECUTION_CHANGE_WEIGHT = 0.05;
27
+ const EXECUTION_PAYLOAD_WEIGHT = 0.5;
28
+ const PAYLOAD_ATTESTATION_WEIGHT = 0.05;
29
+ const EXECUTION_PAYLOAD_BID_WEIGHT = 0.05;
27
30
 
28
31
  const beaconAttestationSubnetWeight = 1 / ATTESTATION_SUBNET_COUNT;
29
32
  const maxPositiveScore =
@@ -34,7 +37,10 @@ const maxPositiveScore =
34
37
  VOLUNTARY_EXIT_WEIGHT +
35
38
  PROPOSER_SLASHING_WEIGHT +
36
39
  ATTESTER_SLASHING_WEIGHT +
37
- BLS_TO_EXECUTION_CHANGE_WEIGHT);
40
+ BLS_TO_EXECUTION_CHANGE_WEIGHT +
41
+ EXECUTION_PAYLOAD_WEIGHT +
42
+ PAYLOAD_ATTESTATION_WEIGHT +
43
+ EXECUTION_PAYLOAD_BID_WEIGHT);
38
44
 
39
45
  /**
40
46
  * The following params is implemented by Lighthouse at
@@ -172,6 +178,26 @@ function getAllTopicsScoreParams(
172
178
  expectedMessageRate: 1 / 5 / SLOTS_PER_EPOCH,
173
179
  firstMessageDecayTime: epochDurationMs * 100,
174
180
  });
181
+ topicsParams[
182
+ stringifyGossipTopic(config, {
183
+ type: GossipType.payload_attestation_message,
184
+ boundary,
185
+ })
186
+ ] = getTopicScoreParams(config, precomputedParams, {
187
+ topicWeight: PAYLOAD_ATTESTATION_WEIGHT,
188
+ expectedMessageRate: PTC_SIZE,
189
+ firstMessageDecayTime: epochDurationMs * 100,
190
+ });
191
+ topicsParams[
192
+ stringifyGossipTopic(config, {
193
+ type: GossipType.execution_payload_bid,
194
+ boundary,
195
+ })
196
+ ] = getTopicScoreParams(config, precomputedParams, {
197
+ topicWeight: EXECUTION_PAYLOAD_BID_WEIGHT,
198
+ expectedMessageRate: 1024, // TODO GLOAS: Need an estimate for this
199
+ firstMessageDecayTime: epochDurationMs * 100,
200
+ });
175
201
 
176
202
  // other topics
177
203
  topicsParams[
@@ -190,6 +216,22 @@ function getAllTopicsScoreParams(
190
216
  currentSlot: eth2Context.currentSlot,
191
217
  },
192
218
  });
219
+ topicsParams[
220
+ stringifyGossipTopic(config, {
221
+ type: GossipType.execution_payload,
222
+ boundary,
223
+ })
224
+ ] = getTopicScoreParams(config, precomputedParams, {
225
+ topicWeight: EXECUTION_PAYLOAD_WEIGHT,
226
+ expectedMessageRate: 1,
227
+ firstMessageDecayTime: epochDurationMs * 20,
228
+ meshMessageInfo: {
229
+ decaySlots: SLOTS_PER_EPOCH * 5,
230
+ capFactor: 3,
231
+ activationWindow: epochDurationMs,
232
+ currentSlot: eth2Context.currentSlot,
233
+ },
234
+ });
193
235
 
194
236
  const activeValidatorCount = eth2Context.activeValidatorCount;
195
237
  const {aggregatorsPerslot, committeesPerSlot} = expectedAggregatorCountPerSlot(activeValidatorCount);
@@ -69,6 +69,9 @@ function stringifyGossipTopicType(topic: GossipTopic): string {
69
69
  case GossipType.light_client_finality_update:
70
70
  case GossipType.light_client_optimistic_update:
71
71
  case GossipType.bls_to_execution_change:
72
+ case GossipType.execution_payload:
73
+ case GossipType.payload_attestation_message:
74
+ case GossipType.execution_payload_bid:
72
75
  return topic.type;
73
76
  case GossipType.beacon_attestation:
74
77
  case GossipType.sync_committee:
@@ -114,6 +117,12 @@ export function getGossipSSZType(topic: GossipTopic) {
114
117
  : ssz.altair.LightClientFinalityUpdate;
115
118
  case GossipType.bls_to_execution_change:
116
119
  return ssz.capella.SignedBLSToExecutionChange;
120
+ case GossipType.execution_payload:
121
+ return ssz.gloas.SignedExecutionPayloadEnvelope;
122
+ case GossipType.payload_attestation_message:
123
+ return ssz.gloas.PayloadAttestationMessage;
124
+ case GossipType.execution_payload_bid:
125
+ return ssz.gloas.SignedExecutionPayloadBid;
117
126
  }
118
127
  }
119
128
 
@@ -190,6 +199,9 @@ export function parseGossipTopic(forkDigestContext: ForkDigestContext, topicStr:
190
199
  case GossipType.light_client_finality_update:
191
200
  case GossipType.light_client_optimistic_update:
192
201
  case GossipType.bls_to_execution_change:
202
+ case GossipType.execution_payload:
203
+ case GossipType.payload_attestation_message:
204
+ case GossipType.execution_payload_bid:
193
205
  return {type: gossipTypeStr, boundary, encoding};
194
206
  }
195
207
 
@@ -240,6 +252,12 @@ export function getCoreTopicsAtFork(
240
252
  {type: GossipType.attester_slashing},
241
253
  ];
242
254
 
255
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
256
+ topics.push({type: GossipType.execution_payload});
257
+ topics.push({type: GossipType.payload_attestation_message});
258
+ topics.push({type: GossipType.execution_payload_bid});
259
+ }
260
+
243
261
  // After fulu also track data_column_sidecar_{index}
244
262
  if (ForkSeq[fork] >= ForkSeq.fulu) {
245
263
  topics.push(...getDataColumnSidecarTopics(networkConfig));
@@ -329,4 +347,7 @@ export const gossipTopicIgnoreDuplicatePublishError: Record<GossipType, boolean>
329
347
  [GossipType.light_client_finality_update]: false,
330
348
  [GossipType.light_client_optimistic_update]: false,
331
349
  [GossipType.bls_to_execution_change]: true,
350
+ [GossipType.execution_payload]: true,
351
+ [GossipType.payload_attestation_message]: true,
352
+ [GossipType.execution_payload_bid]: true,
332
353
  };
@@ -48,6 +48,8 @@ import {
48
48
  import {IBeaconChain} from "../../chain/interface.js";
49
49
  import {validateGossipBlobSidecar} from "../../chain/validation/blobSidecar.js";
50
50
  import {validateGossipDataColumnSidecar} from "../../chain/validation/dataColumnSidecar.js";
51
+ import {validateGossipExecutionPayloadBid} from "../../chain/validation/executionPayloadBid.js";
52
+ import {validateGossipExecutionPayloadEnvelope} from "../../chain/validation/executionPayloadEnvelope.js";
51
53
  import {
52
54
  AggregateAndProofValidationResult,
53
55
  GossipAttestation,
@@ -64,6 +66,7 @@ import {
64
66
  } from "../../chain/validation/index.js";
65
67
  import {validateLightClientFinalityUpdate} from "../../chain/validation/lightClientFinalityUpdate.js";
66
68
  import {validateLightClientOptimisticUpdate} from "../../chain/validation/lightClientOptimisticUpdate.js";
69
+ import {validateGossipPayloadAttestationMessage} from "../../chain/validation/payloadAttestationMessage.js";
67
70
  import {OpSource} from "../../chain/validatorMonitor.js";
68
71
  import {Metrics} from "../../metrics/index.js";
69
72
  import {kzgCommitmentToVersionedHash} from "../../util/blobs.js";
@@ -815,6 +818,51 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
815
818
 
816
819
  chain.emitter.emit(routes.events.EventType.blsToExecutionChange, blsToExecutionChange);
817
820
  },
821
+ [GossipType.execution_payload]: async ({
822
+ gossipData,
823
+ topic,
824
+ }: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
825
+ const {serializedData} = gossipData;
826
+ const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
827
+ await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
828
+
829
+ // TODO GLOAS: Handle valid envelope. Need an import flow that calls `processExecutionPayloadEnvelope` and fork choice
830
+ },
831
+ [GossipType.payload_attestation_message]: async ({
832
+ gossipData,
833
+ topic,
834
+ }: GossipHandlerParamGeneric<GossipType.payload_attestation_message>) => {
835
+ const {serializedData} = gossipData;
836
+ const payloadAttestationMessage = sszDeserialize(topic, serializedData);
837
+ const validationResult = await validateGossipPayloadAttestationMessage(chain, payloadAttestationMessage);
838
+
839
+ try {
840
+ const insertOutcome = chain.payloadAttestationPool.add(
841
+ payloadAttestationMessage,
842
+ validationResult.attDataRootHex,
843
+ validationResult.validatorCommitteeIndex
844
+ );
845
+ metrics?.opPool.payloadAttestationPool.gossipInsertOutcome.inc({insertOutcome});
846
+ } catch (e) {
847
+ logger.error("Error adding to payloadAttestation pool", {}, e as Error);
848
+ }
849
+ },
850
+ [GossipType.execution_payload_bid]: async ({
851
+ gossipData,
852
+ topic,
853
+ }: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
854
+ const {serializedData} = gossipData;
855
+ const executionPayloadBid = sszDeserialize(topic, serializedData);
856
+ await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
857
+
858
+ // Handle valid payload bid by storing in a bid pool
859
+ try {
860
+ const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid.message);
861
+ metrics?.opPool.executionPayloadBidPool.gossipInsertOutcome.inc({insertOutcome});
862
+ } catch (e) {
863
+ logger.error("Error adding to executionPayloadBid pool", {}, e as Error);
864
+ }
865
+ },
818
866
  };
819
867
  }
820
868