@lodestar/beacon-node 1.38.0 → 1.39.0-dev.d4a47659a5

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 (152) hide show
  1. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/state/index.js +4 -5
  3. package/lib/api/impl/beacon/state/index.js.map +1 -1
  4. package/lib/api/impl/validator/index.js +1 -1
  5. package/lib/api/impl/validator/index.js.map +1 -1
  6. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  7. package/lib/chain/blocks/verifyBlock.js +1 -21
  8. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  9. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +1 -6
  10. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  11. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +10 -131
  12. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  13. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  14. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  15. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  16. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  17. package/lib/chain/chain.d.ts.map +1 -1
  18. package/lib/chain/chain.js +4 -14
  19. package/lib/chain/chain.js.map +1 -1
  20. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  21. package/lib/chain/forkChoice/index.js +3 -3
  22. package/lib/chain/forkChoice/index.js.map +1 -1
  23. package/lib/chain/options.d.ts +0 -4
  24. package/lib/chain/options.d.ts.map +1 -1
  25. package/lib/chain/options.js +0 -2
  26. package/lib/chain/options.js.map +1 -1
  27. package/lib/chain/prepareNextSlot.js +1 -1
  28. package/lib/chain/prepareNextSlot.js.map +1 -1
  29. package/lib/chain/produceBlock/produceBlockBody.d.ts +2 -21
  30. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  31. package/lib/chain/produceBlock/produceBlockBody.js +24 -87
  32. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  33. package/lib/chain/rewards/attestationsRewards.d.ts +3 -3
  34. package/lib/chain/rewards/attestationsRewards.d.ts.map +1 -1
  35. package/lib/chain/rewards/attestationsRewards.js +4 -4
  36. package/lib/chain/rewards/attestationsRewards.js.map +1 -1
  37. package/lib/chain/rewards/syncCommitteeRewards.d.ts +2 -2
  38. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +1 -1
  39. package/lib/chain/rewards/syncCommitteeRewards.js +1 -2
  40. package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
  41. package/lib/chain/validation/attesterSlashing.js +2 -2
  42. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  43. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  44. package/lib/chain/validation/blobSidecar.js +2 -2
  45. package/lib/chain/validation/blobSidecar.js.map +1 -1
  46. package/lib/chain/validation/block.d.ts.map +1 -1
  47. package/lib/chain/validation/block.js +3 -3
  48. package/lib/chain/validation/block.js.map +1 -1
  49. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  50. package/lib/chain/validation/dataColumnSidecar.js +2 -2
  51. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  52. package/lib/chain/validation/proposerSlashing.js +1 -1
  53. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  54. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  55. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  56. package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -3
  57. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  58. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  59. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  60. package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
  61. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  62. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  63. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  64. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  65. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  66. package/lib/chain/validation/syncCommittee.js +1 -1
  67. package/lib/chain/validation/syncCommittee.js.map +1 -1
  68. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  69. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -3
  70. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  71. package/lib/chain/validation/voluntaryExit.js +1 -1
  72. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  73. package/lib/eth1/index.d.ts +2 -17
  74. package/lib/eth1/index.d.ts.map +1 -1
  75. package/lib/eth1/index.js +0 -50
  76. package/lib/eth1/index.js.map +1 -1
  77. package/lib/eth1/interface.d.ts +1 -39
  78. package/lib/eth1/interface.d.ts.map +1 -1
  79. package/lib/execution/engine/http.d.ts +4 -12
  80. package/lib/execution/engine/http.d.ts.map +1 -1
  81. package/lib/execution/engine/http.js +4 -12
  82. package/lib/execution/engine/http.js.map +1 -1
  83. package/lib/execution/engine/mock.d.ts +2 -6
  84. package/lib/execution/engine/mock.d.ts.map +1 -1
  85. package/lib/execution/engine/mock.js +3 -14
  86. package/lib/execution/engine/mock.js.map +1 -1
  87. package/lib/metrics/metrics/lodestar.d.ts +0 -14
  88. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  89. package/lib/metrics/metrics/lodestar.js +0 -44
  90. package/lib/metrics/metrics/lodestar.js.map +1 -1
  91. package/lib/network/core/events.d.ts +1 -1
  92. package/lib/network/core/events.d.ts.map +1 -1
  93. package/lib/network/core/events.js +1 -1
  94. package/lib/network/core/events.js.map +1 -1
  95. package/lib/network/events.d.ts +6 -1
  96. package/lib/network/events.d.ts.map +1 -1
  97. package/lib/network/events.js +7 -1
  98. package/lib/network/events.js.map +1 -1
  99. package/lib/node/notifier.d.ts.map +1 -1
  100. package/lib/node/notifier.js +6 -22
  101. package/lib/node/notifier.js.map +1 -1
  102. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  103. package/lib/sync/backfill/backfill.js +4 -2
  104. package/lib/sync/backfill/backfill.js.map +1 -1
  105. package/lib/sync/backfill/verify.d.ts +2 -2
  106. package/lib/sync/backfill/verify.d.ts.map +1 -1
  107. package/lib/sync/backfill/verify.js +3 -3
  108. package/lib/sync/backfill/verify.js.map +1 -1
  109. package/lib/util/workerEvents.d.ts +1 -6
  110. package/lib/util/workerEvents.d.ts.map +1 -1
  111. package/lib/util/workerEvents.js +8 -8
  112. package/lib/util/workerEvents.js.map +1 -1
  113. package/package.json +14 -15
  114. package/src/api/impl/beacon/state/index.ts +4 -5
  115. package/src/api/impl/validator/index.ts +1 -1
  116. package/src/chain/blocks/verifyBlock.ts +2 -24
  117. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +11 -170
  118. package/src/chain/blocks/verifyBlocksSignatures.ts +3 -2
  119. package/src/chain/chain.ts +4 -15
  120. package/src/chain/forkChoice/index.ts +2 -3
  121. package/src/chain/options.ts +0 -6
  122. package/src/chain/prepareNextSlot.ts +1 -1
  123. package/src/chain/produceBlock/produceBlockBody.ts +25 -120
  124. package/src/chain/rewards/attestationsRewards.ts +6 -5
  125. package/src/chain/rewards/syncCommitteeRewards.ts +2 -2
  126. package/src/chain/validation/attesterSlashing.ts +2 -2
  127. package/src/chain/validation/blobSidecar.ts +10 -2
  128. package/src/chain/validation/block.ts +2 -3
  129. package/src/chain/validation/dataColumnSidecar.ts +6 -1
  130. package/src/chain/validation/proposerSlashing.ts +1 -1
  131. package/src/chain/validation/signatureSets/contributionAndProof.ts +3 -2
  132. package/src/chain/validation/signatureSets/syncCommittee.ts +3 -1
  133. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +4 -2
  134. package/src/chain/validation/syncCommittee.ts +1 -1
  135. package/src/chain/validation/syncCommitteeContributionAndProof.ts +4 -5
  136. package/src/chain/validation/voluntaryExit.ts +1 -1
  137. package/src/eth1/index.ts +2 -65
  138. package/src/eth1/interface.ts +1 -45
  139. package/src/execution/engine/http.ts +4 -12
  140. package/src/execution/engine/mock.ts +3 -15
  141. package/src/metrics/metrics/lodestar.ts +0 -52
  142. package/src/network/core/events.ts +1 -1
  143. package/src/network/events.ts +7 -1
  144. package/src/node/notifier.ts +7 -29
  145. package/src/sync/backfill/backfill.ts +9 -2
  146. package/src/sync/backfill/verify.ts +8 -2
  147. package/src/util/workerEvents.ts +9 -8
  148. package/lib/eth1/eth1MergeBlockTracker.d.ts +0 -65
  149. package/lib/eth1/eth1MergeBlockTracker.d.ts.map +0 -1
  150. package/lib/eth1/eth1MergeBlockTracker.js +0 -262
  151. package/lib/eth1/eth1MergeBlockTracker.js.map +0 -1
  152. package/src/eth1/eth1MergeBlockTracker.ts +0 -328
@@ -1,5 +1,5 @@
1
1
  import { GENESIS_SLOT } from "@lodestar/params";
2
- import { getBlockProposerSignatureSet } from "@lodestar/state-transition";
2
+ import { getBlockProposerSignatureSet, } from "@lodestar/state-transition";
3
3
  import { ssz } from "@lodestar/types";
4
4
  import { BackfillSyncError, BackfillSyncErrorCode } from "./errors.js";
5
5
  export function verifyBlockSequence(config, blocks, anchorRoot) {
@@ -20,13 +20,13 @@ export function verifyBlockSequence(config, blocks, anchorRoot) {
20
20
  }
21
21
  return { nextAnchor, verifiedBlocks };
22
22
  }
23
- export async function verifyBlockProposerSignature(bls, state, blocks) {
23
+ export async function verifyBlockProposerSignature(index2pubkey, bls, state, blocks) {
24
24
  if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT)
25
25
  return;
26
26
  const signatures = blocks.reduce((sigs, block) => {
27
27
  // genesis block doesn't have valid signature
28
28
  if (block.message.slot !== GENESIS_SLOT)
29
- sigs.push(getBlockProposerSignatureSet(state, block));
29
+ sigs.push(getBlockProposerSignatureSet(index2pubkey, state, block));
30
30
  return sigs;
31
31
  }, []);
32
32
  if (!(await bls.verifySignatureSets(signatures, { batchable: true }))) {
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/sync/backfill/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAA2C,4BAA4B,EAAC,MAAM,4BAA4B,CAAC;AAClH,OAAO,EAAgC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAC,iBAAiB,EAAE,qBAAqB,EAAC,MAAM,aAAa,CAAC;AASrE,MAAM,UAAU,mBAAmB,CACjC,MAAoB,EACpB,MAA2B,EAC3B,UAAgB;IAMhB,IAAI,QAAQ,GAAS,UAAU,CAAC;IAChC,IAAI,UAAU,GAAyB,IAAI,CAAC;IAE5C,MAAM,cAAc,GAAwB,EAAE,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC1C,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,iBAAiB,CAAC,EAAC,IAAI,EAAE,qBAAqB,CAAC,YAAY,EAAC,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,qBAAqB,CAAC,UAAU,EAAC,CAAC;QAC/E,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,UAAU,GAAG,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAC,CAAC;QACtE,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;IACtC,CAAC;IACD,OAAO,EAAC,UAAU,EAAE,cAAc,EAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,GAAiB,EACjB,KAAgC,EAChC,MAA2B;IAE3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO;IAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAqB,EAAE,KAAK,EAAE,EAAE;QAChE,6CAA6C;QAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;YAAE,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,iBAAiB,CAAC,EAAC,IAAI,EAAE,qBAAqB,CAAC,iBAAiB,EAAC,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/sync/backfill/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAIL,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAgC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAC,iBAAiB,EAAE,qBAAqB,EAAC,MAAM,aAAa,CAAC;AASrE,MAAM,UAAU,mBAAmB,CACjC,MAAoB,EACpB,MAA2B,EAC3B,UAAgB;IAMhB,IAAI,QAAQ,GAAS,UAAU,CAAC;IAChC,IAAI,UAAU,GAAyB,IAAI,CAAC;IAE5C,MAAM,cAAc,GAAwB,EAAE,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC1C,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,iBAAiB,CAAC,EAAC,IAAI,EAAE,qBAAqB,CAAC,YAAY,EAAC,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,qBAAqB,CAAC,UAAU,EAAC,CAAC;QAC/E,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,UAAU,GAAG,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAC,CAAC;QACtE,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;IACtC,CAAC;IACD,OAAO,EAAC,UAAU,EAAE,cAAc,EAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,YAA+B,EAC/B,GAAiB,EACjB,KAAgC,EAChC,MAA2B;IAE3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO;IAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAqB,EAAE,KAAK,EAAE,EAAE;QAChE,6CAA6C;QAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;YAAE,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7G,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,iBAAiB,CAAC,EAAC,IAAI,EAAE,qBAAqB,CAAC,iBAAiB,EAAC,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC"}
@@ -3,6 +3,7 @@ import { Thread } from "@chainsafe/threads";
3
3
  import { Logger } from "@lodestar/logger";
4
4
  import { Metrics } from "../metrics/metrics.js";
5
5
  import { NetworkCoreWorkerMetrics } from "../network/core/metrics.js";
6
+ import { EventDirection } from "../network/events.js";
6
7
  import { StrictEventEmitterSingleArg } from "./strictEvents.js";
7
8
  export type WorkerBridgeEvent<EventData> = {
8
9
  type: string;
@@ -10,12 +11,6 @@ export type WorkerBridgeEvent<EventData> = {
10
11
  posted: [number, number];
11
12
  data: EventData[keyof EventData];
12
13
  };
13
- export declare enum EventDirection {
14
- workerToMain = 0,
15
- mainToWorker = 1,
16
- /** Event not emitted through worker boundary */
17
- none = 2
18
- }
19
14
  /**
20
15
  * Bridges events from worker to main thread
21
16
  * Each event can only have one direction:
@@ -1 +1 @@
1
- {"version":3,"file":"workerEvents.d.ts","sourceRoot":"","sources":["../../src/util/workerEvents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAC,2BAA2B,EAAC,MAAM,mBAAmB,CAAC;AAI9D,MAAM,MAAM,iBAAiB,CAAC,SAAS,IAAI;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,SAAS,CAAC;IACvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;CAClC,CAAC;AAEF,oBAAY,cAAc;IACxB,YAAY,IAAA;IACZ,YAAY,IAAA;IACZ,gDAAgD;IAChD,IAAI,IAAA;CACL;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAChD,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,2BAA2B,CAAC,SAAS,CAAC,EAC9C,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,wBAAwB,GAAG,IAAI,EACxC,cAAc,EAAE;KAAE,CAAC,IAAI,MAAM,SAAS,GAAG,cAAc;CAAC,GACvD,IAAI,CAiCN;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAC9C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,2BAA2B,CAAC,SAAS,CAAC,EAC9C,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC,EAC1C,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,cAAc,EAAE;KAAE,CAAC,IAAI,MAAM,SAAS,GAAG,cAAc;CAAC,GACvD,IAAI,CAiCN;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,MAAM,EACN,OAAO,EACP,UAAU,EACV,MAAM,GACP,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhB"}
1
+ {"version":3,"file":"workerEvents.d.ts","sourceRoot":"","sources":["../../src/util/workerEvents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAC,cAAc,EAAe,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAC,2BAA2B,EAAC,MAAM,mBAAmB,CAAC;AAI9D,MAAM,MAAM,iBAAiB,CAAC,SAAS,IAAI;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,SAAS,CAAC;IACvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;CAClC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAChD,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,2BAA2B,CAAC,SAAS,CAAC,EAC9C,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,wBAAwB,GAAG,IAAI,EACxC,cAAc,EAAE;KAAE,CAAC,IAAI,MAAM,SAAS,GAAG,cAAc;CAAC,GACvD,IAAI,CAuCN;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAC9C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,2BAA2B,CAAC,SAAS,CAAC,EAC9C,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC,EAC1C,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,cAAc,EAAE;KAAE,CAAC,IAAI,MAAM,SAAS,GAAG,cAAc;CAAC,GACvD,IAAI,CAiCN;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,MAAM,EACN,OAAO,EACP,UAAU,EACV,MAAM,GACP,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhB"}
@@ -1,13 +1,7 @@
1
1
  import { Thread } from "@chainsafe/threads";
2
2
  import { sleep } from "@lodestar/utils";
3
+ import { EventDirection, NetworkEvent } from "../network/events.js";
3
4
  const NANO_TO_SECOND_CONVERSION = 1e9;
4
- export var EventDirection;
5
- (function (EventDirection) {
6
- EventDirection[EventDirection["workerToMain"] = 0] = "workerToMain";
7
- EventDirection[EventDirection["mainToWorker"] = 1] = "mainToWorker";
8
- /** Event not emitted through worker boundary */
9
- EventDirection[EventDirection["none"] = 2] = "none";
10
- })(EventDirection || (EventDirection = {}));
11
5
  /**
12
6
  * Bridges events from worker to main thread
13
7
  * Each event can only have one direction:
@@ -37,7 +31,13 @@ export function wireEventsOnWorkerThread(mainEventName, events, parentPort, metr
37
31
  posted: process.hrtime(),
38
32
  data,
39
33
  };
40
- parentPort.postMessage(workerEvent);
34
+ let transferList = undefined;
35
+ if (eventName === NetworkEvent.pendingGossipsubMessage) {
36
+ const payload = data;
37
+ // Transfer the underlying ArrayBuffer to avoid copy for PendingGossipsubMessage
38
+ transferList = [payload.msg.data.buffer];
39
+ }
40
+ parentPort.postMessage(workerEvent, transferList);
41
41
  });
42
42
  }
43
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workerEvents.js","sourceRoot":"","sources":["../../src/util/workerEvents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workerEvents.js","sourceRoot":"","sources":["../../src/util/workerEvents.ts"],"names":[],"mappings":"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"}
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.38.0",
14
+ "version": "1.39.0-dev.d4a47659a5",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -103,7 +103,6 @@
103
103
  "test:unit": "vitest run --project unit --project unit-minimal",
104
104
  "test:e2e": "vitest run --project e2e --project e2e-mainnet",
105
105
  "test:sim": "vitest run test/sim/**/*.test.ts",
106
- "test:sim:mergemock": "vitest run test/sim/mergemock.test.ts",
107
106
  "test:sim:blobs": "vitest run test/sim/4844-interop.test.ts",
108
107
  "download-spec-tests": "node --loader=ts-node/esm test/spec/downloadTests.ts",
109
108
  "test:spec:bls": "vitest run --project spec-minimal test/spec/bls/",
@@ -141,18 +140,18 @@
141
140
  "@libp2p/peer-id": "^5.1.0",
142
141
  "@libp2p/prometheus-metrics": "^4.3.15",
143
142
  "@libp2p/tcp": "^10.1.8",
144
- "@lodestar/api": "^1.38.0",
145
- "@lodestar/config": "^1.38.0",
146
- "@lodestar/db": "^1.38.0",
147
- "@lodestar/fork-choice": "^1.38.0",
148
- "@lodestar/light-client": "^1.38.0",
149
- "@lodestar/logger": "^1.38.0",
150
- "@lodestar/params": "^1.38.0",
151
- "@lodestar/reqresp": "^1.38.0",
152
- "@lodestar/state-transition": "^1.38.0",
153
- "@lodestar/types": "^1.38.0",
154
- "@lodestar/utils": "^1.38.0",
155
- "@lodestar/validator": "^1.38.0",
143
+ "@lodestar/api": "1.39.0-dev.d4a47659a5",
144
+ "@lodestar/config": "1.39.0-dev.d4a47659a5",
145
+ "@lodestar/db": "1.39.0-dev.d4a47659a5",
146
+ "@lodestar/fork-choice": "1.39.0-dev.d4a47659a5",
147
+ "@lodestar/light-client": "1.39.0-dev.d4a47659a5",
148
+ "@lodestar/logger": "1.39.0-dev.d4a47659a5",
149
+ "@lodestar/params": "1.39.0-dev.d4a47659a5",
150
+ "@lodestar/reqresp": "1.39.0-dev.d4a47659a5",
151
+ "@lodestar/state-transition": "1.39.0-dev.d4a47659a5",
152
+ "@lodestar/types": "1.39.0-dev.d4a47659a5",
153
+ "@lodestar/utils": "1.39.0-dev.d4a47659a5",
154
+ "@lodestar/validator": "1.39.0-dev.d4a47659a5",
156
155
  "@multiformats/multiaddr": "^12.1.3",
157
156
  "datastore-core": "^10.0.2",
158
157
  "datastore-fs": "^10.0.6",
@@ -187,5 +186,5 @@
187
186
  "beacon",
188
187
  "blockchain"
189
188
  ],
190
- "gitHead": "dbd947813d9c6513b4d56e6ae0376b34f28a1b75"
189
+ "gitHead": "ece402e986e6babc414c33018cbe7337c68ffd67"
191
190
  }
@@ -95,7 +95,7 @@ export function getBeaconStateApi({
95
95
  const {state, executionOptimistic, finalized} = await getState(stateId);
96
96
  const currentEpoch = getCurrentEpoch(state);
97
97
  const {validators, balances} = state; // Get the validators sub tree once for all the loop
98
- const {pubkey2index} = chain.getHeadState().epochCtx;
98
+ const {pubkey2index} = chain;
99
99
 
100
100
  const validatorResponses: routes.beacon.ValidatorResponse[] = [];
101
101
  if (validatorIds.length) {
@@ -154,7 +154,7 @@ export function getBeaconStateApi({
154
154
 
155
155
  async postStateValidatorIdentities({stateId, validatorIds = []}) {
156
156
  const {state, executionOptimistic, finalized} = await getState(stateId);
157
- const {pubkey2index} = chain.getHeadState().epochCtx;
157
+ const {pubkey2index} = chain;
158
158
 
159
159
  let validatorIdentities: routes.beacon.ValidatorIdentities;
160
160
 
@@ -187,7 +187,7 @@ export function getBeaconStateApi({
187
187
 
188
188
  async getStateValidator({stateId, validatorId}) {
189
189
  const {state, executionOptimistic, finalized} = await getState(stateId);
190
- const {pubkey2index} = chain.getHeadState().epochCtx;
190
+ const {pubkey2index} = chain;
191
191
 
192
192
  const resp = getStateValidatorIndex(validatorId, state, pubkey2index);
193
193
  if (!resp.valid) {
@@ -212,10 +212,9 @@ export function getBeaconStateApi({
212
212
  if (validatorIds.length) {
213
213
  assertUniqueItems(validatorIds, "Duplicate validator IDs provided");
214
214
 
215
- const headState = chain.getHeadState();
216
215
  const balances: routes.beacon.ValidatorBalance[] = [];
217
216
  for (const id of validatorIds) {
218
- const resp = getStateValidatorIndex(id, state, headState.epochCtx.pubkey2index);
217
+ const resp = getStateValidatorIndex(id, state, chain.pubkey2index);
219
218
 
220
219
  if (resp.valid) {
221
220
  balances.push({
@@ -1511,7 +1511,7 @@ export function getValidatorApi(
1511
1511
 
1512
1512
  const filteredRegistrations = registrations.filter((registration) => {
1513
1513
  const {pubkey} = registration.message;
1514
- const validatorIndex = headState.epochCtx.pubkey2index.get(pubkey);
1514
+ const validatorIndex = chain.pubkey2index.get(pubkey);
1515
1515
  if (validatorIndex === null) return false;
1516
1516
 
1517
1517
  const validator = headState.validators.getReadonly(validatorIndex);
@@ -1,4 +1,3 @@
1
- import {ChainForkConfig} from "@lodestar/config";
2
1
  import {ExecutionStatus, ProtoBlock} from "@lodestar/fork-choice";
3
2
  import {ForkName, isForkPostFulu} from "@lodestar/params";
4
3
  import {
@@ -7,8 +6,7 @@ import {
7
6
  computeEpochAtSlot,
8
7
  isStateValidatorsNodesPopulated,
9
8
  } from "@lodestar/state-transition";
10
- import {IndexedAttestation, bellatrix, deneb} from "@lodestar/types";
11
- import {Logger, toRootHex} from "@lodestar/utils";
9
+ import {IndexedAttestation, deneb} from "@lodestar/types";
12
10
  import type {BeaconChain} from "../chain.js";
13
11
  import {BlockError, BlockErrorCode} from "../errors/index.js";
14
12
  import {BlockProcessOpts} from "../options.js";
@@ -18,7 +16,6 @@ import {ImportBlockOpts} from "./types.js";
18
16
  import {DENEB_BLOWFISH_BANNER} from "./utils/blowfishBanner.js";
19
17
  import {ELECTRA_GIRAFFE_BANNER} from "./utils/giraffeBanner.js";
20
18
  import {CAPELLA_OWL_BANNER} from "./utils/ownBanner.js";
21
- import {POS_PANDA_MERGE_TRANSITION_BANNER} from "./utils/pandaMergeTransitionBanner.js";
22
19
  import {FULU_ZEBRA_BANNER} from "./utils/zebraBanner.js";
23
20
  import {verifyBlocksDataAvailability} from "./verifyBlocksDataAvailability.js";
24
21
  import {SegmentExecStatus, verifyBlocksExecutionPayload} from "./verifyBlocksExecutionPayloads.js";
@@ -103,7 +100,6 @@ export async function verifyBlocksInEpoch(
103
100
  : Promise.resolve({
104
101
  execAborted: null,
105
102
  executionStatuses: blocks.map((_blk) => ExecutionStatus.Syncing),
106
- mergeBlockFound: null,
107
103
  } as SegmentExecStatus);
108
104
 
109
105
  // Store indexed attestations for each block to avoid recomputing them during import
@@ -143,6 +139,7 @@ export async function verifyBlocksInEpoch(
143
139
  // All signatures at once
144
140
  opts.skipVerifyBlockSignatures !== true
145
141
  ? verifyBlocksSignatures(
142
+ this.index2pubkey,
146
143
  this.bls,
147
144
  this.logger,
148
145
  this.metrics,
@@ -162,12 +159,6 @@ export async function verifyBlocksInEpoch(
162
159
  ]);
163
160
 
164
161
  if (opts.verifyOnly !== true) {
165
- if (segmentExecStatus.execAborted === null && segmentExecStatus.mergeBlockFound !== null) {
166
- // merge block found and is fully valid = state transition + signatures + execution payload.
167
- // TODO: Will this banner be logged during syncing?
168
- logOnPowBlock(this.logger, this.config, segmentExecStatus.mergeBlockFound);
169
- }
170
-
171
162
  const fromForkBoundary = this.config.getForkBoundaryAtEpoch(computeEpochAtSlot(parentBlock.slot));
172
163
  const toForkBoundary = this.config.getForkBoundaryAtEpoch(computeEpochAtSlot(lastBlock.message.slot));
173
164
 
@@ -250,16 +241,3 @@ export async function verifyBlocksInEpoch(
250
241
  abortController.abort();
251
242
  }
252
243
  }
253
-
254
- function logOnPowBlock(logger: Logger, config: ChainForkConfig, mergeBlock: bellatrix.BeaconBlock): void {
255
- const mergeBlockHash = toRootHex(config.getForkTypes(mergeBlock.slot).BeaconBlock.hashTreeRoot(mergeBlock));
256
- const mergeExecutionHash = toRootHex(mergeBlock.body.executionPayload.blockHash);
257
- const mergePowHash = toRootHex(mergeBlock.body.executionPayload.parentHash);
258
- logger.info(POS_PANDA_MERGE_TRANSITION_BANNER);
259
- logger.info("Execution transitioning from PoW to PoS!!!");
260
- logger.info("Importing block referencing terminal PoW block", {
261
- blockHash: mergeBlockHash,
262
- executionHash: mergeExecutionHash,
263
- powHash: mergePowHash,
264
- });
265
- }
@@ -6,19 +6,11 @@ import {
6
6
  LVHValidResponse,
7
7
  MaybeValidExecutionStatus,
8
8
  ProtoBlock,
9
- assertValidTerminalPowBlock,
10
9
  } from "@lodestar/fork-choice";
11
- import {ForkSeq, SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY} from "@lodestar/params";
12
- import {
13
- CachedBeaconStateAllForks,
14
- isExecutionBlockBodyType,
15
- isExecutionEnabled,
16
- isExecutionStateType,
17
- isMergeTransitionBlock as isMergeTransitionBlockFn,
18
- } from "@lodestar/state-transition";
19
- import {Slot, bellatrix, electra} from "@lodestar/types";
10
+ import {ForkSeq} from "@lodestar/params";
11
+ import {CachedBeaconStateAllForks, isExecutionBlockBodyType, isExecutionStateType} from "@lodestar/state-transition";
12
+ import {bellatrix, electra} from "@lodestar/types";
20
13
  import {ErrorAborted, Logger, toRootHex} from "@lodestar/utils";
21
- import {IEth1ForBlockProduction} from "../../eth1/index.js";
22
14
  import {ExecutionPayloadStatus, IExecutionEngine} from "../../execution/engine/interface.js";
23
15
  import {Metrics} from "../../metrics/metrics.js";
24
16
  import {IClock} from "../../util/clock.js";
@@ -29,7 +21,6 @@ import {IBlockInput} from "./blockInput/types.js";
29
21
  import {ImportBlockOpts} from "./types.js";
30
22
 
31
23
  export type VerifyBlockExecutionPayloadModules = {
32
- eth1: IEth1ForBlockProduction;
33
24
  executionEngine: IExecutionEngine;
34
25
  clock: IClock;
35
26
  logger: Logger;
@@ -44,9 +35,8 @@ export type SegmentExecStatus =
44
35
  execAborted: null;
45
36
  executionStatuses: MaybeValidExecutionStatus[];
46
37
  executionTime: number;
47
- mergeBlockFound: bellatrix.BeaconBlock | null;
48
38
  }
49
- | {execAborted: ExecAbortType; invalidSegmentLVH?: LVHInvalidResponse; mergeBlockFound: null};
39
+ | {execAborted: ExecAbortType; invalidSegmentLVH?: LVHInvalidResponse};
50
40
 
51
41
  type VerifyExecutionErrorResponse =
52
42
  | {executionStatus: ExecutionStatus.Invalid; lvhResponse: LVHInvalidResponse; execError: BlockError}
@@ -72,7 +62,6 @@ export async function verifyBlocksExecutionPayload(
72
62
  opts: BlockProcessOpts & ImportBlockOpts
73
63
  ): Promise<SegmentExecStatus> {
74
64
  const executionStatuses: MaybeValidExecutionStatus[] = [];
75
- let mergeBlockFound: bellatrix.BeaconBlock | null = null;
76
65
  const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
77
66
  const lastBlock = blockInputs.at(-1);
78
67
 
@@ -96,57 +85,9 @@ export async function verifyBlocksExecutionPayload(
96
85
  // will either validate or prune invalid blocks
97
86
  //
98
87
  // We need to track and keep updating if its safe to optimistically import these blocks.
99
- // The following is how we determine for a block if its safe:
100
- //
101
- // (but we need to modify this check for this segment of blocks because it checks if the
102
- // parent of any block imported in forkchoice is post-merge and currently we could only
103
- // have blocks[0]'s parent imported in the chain as this is no longer one by one verify +
104
- // import.)
105
- //
106
88
  //
107
89
  // When to import such blocks:
108
90
  // From: https://github.com/ethereum/consensus-specs/pull/2844
109
- // A block MUST NOT be optimistically imported, unless either of the following
110
- // conditions are met:
111
- //
112
- // 1. Parent of the block has execution
113
- //
114
- // Since with the sync optimizations, the previous block might not have been in the
115
- // forkChoice yet, so the below check could fail for safeSlotsToImportOptimistically
116
- //
117
- // Luckily, we can depend on the preState0 to see if we are already post merge w.r.t
118
- // the blocks we are importing.
119
- //
120
- // Or in other words if
121
- // - block status is syncing
122
- // - and we are not in a post merge world and is parent is not optimistically safe
123
- // - and we are syncing close to the chain head i.e. clock slot
124
- // - and parent is optimistically safe
125
- //
126
- // then throw error
127
- //
128
- //
129
- // - if we haven't yet imported a post merge ancestor in forkchoice i.e.
130
- // - and we are syncing close to the clockSlot, i.e. merge Transition could be underway
131
- //
132
- //
133
- // 2. The current slot (as per the system clock) is at least
134
- // SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY ahead of the slot of the block being
135
- // imported.
136
- // This means that the merge transition could be underway and we can't afford to import
137
- // a block which is not fully validated as it could affect liveliness of the network.
138
- //
139
- //
140
- // For this segment of blocks:
141
- // We are optimistically safe with respect to this entire block segment if:
142
- // - all the blocks are way behind the current slot
143
- // - or we have already imported a post-merge parent of first block of this chain in forkchoice
144
- const currentSlot = chain.clock.currentSlot;
145
- const safeSlotsToImportOptimistically = opts.safeSlotsToImportOptimistically ?? SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY;
146
- let isOptimisticallySafe =
147
- parentBlock.executionStatus !== ExecutionStatus.PreMerge ||
148
- lastBlock.slot + safeSlotsToImportOptimistically < currentSlot;
149
-
150
91
  for (let blockIndex = 0; blockIndex < blockInputs.length; blockIndex++) {
151
92
  const blockInput = blockInputs[blockIndex];
152
93
  // If blocks are invalid in consensus the main promise could resolve before this loop ends.
@@ -154,14 +95,7 @@ export async function verifyBlocksExecutionPayload(
154
95
  if (signal.aborted) {
155
96
  throw new ErrorAborted("verifyBlockExecutionPayloads");
156
97
  }
157
- const verifyResponse = await verifyBlockExecutionPayload(
158
- chain,
159
- blockInput,
160
- preState0,
161
- opts,
162
- isOptimisticallySafe,
163
- currentSlot
164
- );
98
+ const verifyResponse = await verifyBlockExecutionPayload(chain, blockInput, preState0);
165
99
 
166
100
  // If execError has happened, then we need to extract the segmentExecStatus and return
167
101
  if (verifyResponse.execError !== null) {
@@ -170,75 +104,7 @@ export async function verifyBlocksExecutionPayload(
170
104
 
171
105
  // If we are here then its because executionStatus is one of MaybeValidExecutionStatus
172
106
  const {executionStatus} = verifyResponse;
173
- // It becomes optimistically safe for following blocks if a post-merge block is deemed fit
174
- // for import. If it would not have been safe verifyBlockExecutionPayload would have
175
- // returned execError and loop would have been aborted
176
- if (executionStatus !== ExecutionStatus.PreMerge) {
177
- isOptimisticallySafe = true;
178
- }
179
107
  executionStatuses.push(executionStatus);
180
-
181
- const blockBody = blockInput.getBlock().message.body;
182
- const isMergeTransitionBlock =
183
- // If the merge block is found, stop the search as the isMergeTransitionBlockFn condition
184
- // will still evaluate to true for the following blocks leading to errors (while syncing)
185
- // as the preState0 still belongs to the pre state of the first block on segment
186
- mergeBlockFound === null &&
187
- isExecutionStateType(preState0) &&
188
- isExecutionBlockBodyType(blockBody) &&
189
- isMergeTransitionBlockFn(preState0, blockBody);
190
-
191
- // If this is a merge transition block, check to ensure if it references
192
- // a valid terminal PoW block.
193
- //
194
- // However specs define this check to be run inside forkChoice's onBlock
195
- // (https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/fork-choice.md#on_block)
196
- // but we perform the check here (as inspired from the lighthouse impl)
197
- //
198
- // Reasons:
199
- // 1. If the block is not valid, we should fail early and not wait till
200
- // forkChoice import.
201
- // 2. It makes logical sense to pair it with the block validations and
202
- // deal it with the external services like eth1 tracker here than
203
- // in import block
204
- if (isMergeTransitionBlock) {
205
- const mergeBlock = blockInput.getBlock().message as bellatrix.BeaconBlock;
206
- const mergeBlockHash = toRootHex(chain.config.getForkTypes(mergeBlock.slot).BeaconBlock.hashTreeRoot(mergeBlock));
207
- const powBlockRootHex = toRootHex(mergeBlock.body.executionPayload.parentHash);
208
- const powBlock = await chain.eth1.getPowBlock(powBlockRootHex).catch((error) => {
209
- // Lets just warn the user here, errors if any will be reported on
210
- // `assertValidTerminalPowBlock` checks
211
- chain.logger.warn(
212
- "Error fetching terminal PoW block referred in the merge transition block",
213
- {powBlockHash: powBlockRootHex, mergeBlockHash},
214
- error
215
- );
216
- return null;
217
- });
218
-
219
- const powBlockParent =
220
- powBlock &&
221
- (await chain.eth1.getPowBlock(powBlock.parentHash).catch((error) => {
222
- // Lets just warn the user here, errors if any will be reported on
223
- // `assertValidTerminalPowBlock` checks
224
- chain.logger.warn(
225
- "Error fetching parent of the terminal PoW block referred in the merge transition block",
226
- {powBlockParentHash: powBlock.parentHash, powBlock: powBlockRootHex, mergeBlockHash},
227
- error
228
- );
229
- return null;
230
- }));
231
-
232
- // executionStatus will never == ExecutionStatus.PreMerge if it's the mergeBlock. But gotta make TS happy =D
233
- if (executionStatus === ExecutionStatus.PreMerge) {
234
- throw Error("Merge block must not have executionStatus == PreMerge");
235
- }
236
-
237
- assertValidTerminalPowBlock(chain.config, mergeBlock, {executionStatus, powBlock, powBlockParent});
238
- // Valid execution payload, but may not be in a valid beacon chain block. Delay printing the POS ACTIVATED banner
239
- // to the end of the verify block routine, which confirms that this block is fully valid.
240
- mergeBlockFound = mergeBlock;
241
- }
242
108
  }
243
109
 
244
110
  const executionTime = Date.now();
@@ -265,7 +131,6 @@ export async function verifyBlocksExecutionPayload(
265
131
  execAborted: null,
266
132
  executionStatuses,
267
133
  executionTime,
268
- mergeBlockFound,
269
134
  };
270
135
  }
271
136
 
@@ -275,28 +140,18 @@ export async function verifyBlocksExecutionPayload(
275
140
  export async function verifyBlockExecutionPayload(
276
141
  chain: VerifyBlockExecutionPayloadModules,
277
142
  blockInput: IBlockInput,
278
- preState0: CachedBeaconStateAllForks,
279
- opts: BlockProcessOpts,
280
- isOptimisticallySafe: boolean,
281
- currentSlot: Slot
143
+ preState0: CachedBeaconStateAllForks
282
144
  ): Promise<VerifyBlockExecutionResponse> {
283
145
  const block = blockInput.getBlock();
284
146
  /** Not null if execution is enabled */
285
147
  const executionPayloadEnabled =
286
- isExecutionStateType(preState0) &&
287
- isExecutionBlockBodyType(block.message.body) &&
288
- // Safe to use with a state previous to block's preState. isMergeComplete can only transition from false to true.
289
- // - If preState0 is after merge block: condition is true, and will always be true
290
- // - If preState0 is before merge block: the block could lie but then state transition function will throw above
291
- // It is kinda safe to send non-trusted payloads to the execution client because at most it can trigger sync.
292
- // TODO: If this becomes a problem, do some basic verification beforehand, like checking the proposer signature.
293
- isExecutionEnabled(preState0, block.message)
148
+ isExecutionStateType(preState0) && isExecutionBlockBodyType(block.message.body)
294
149
  ? block.message.body.executionPayload
295
150
  : null;
296
151
 
297
152
  if (!executionPayloadEnabled) {
298
- // isExecutionEnabled() -> false
299
- return {executionStatus: ExecutionStatus.PreMerge, execError: null} as VerifyBlockExecutionResponse;
153
+ // Pre-merge block, no execution payload to verify
154
+ return {executionStatus: ExecutionStatus.PreMerge, lvhResponse: undefined, execError: null};
300
155
  }
301
156
 
302
157
  // TODO: Handle better notifyNewPayload() returning error is syncing
@@ -343,24 +198,10 @@ export async function verifyBlockExecutionPayload(
343
198
  }
344
199
 
345
200
  // Accepted and Syncing have the same treatment, as final validation of block is pending
201
+ // Post-merge, we're always safe to optimistically import
346
202
  case ExecutionPayloadStatus.ACCEPTED:
347
- case ExecutionPayloadStatus.SYNCING: {
348
- // Check if the entire segment was deemed safe or, this block specifically itself if not in
349
- // the safeSlotsToImportOptimistically window of current slot, then we can import else
350
- // we need to throw and not import his block
351
- const safeSlotsToImportOptimistically =
352
- opts.safeSlotsToImportOptimistically ?? SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY;
353
- if (!isOptimisticallySafe && blockInput.slot + safeSlotsToImportOptimistically >= currentSlot) {
354
- const execError = new BlockError(block, {
355
- code: BlockErrorCode.EXECUTION_ENGINE_ERROR,
356
- execStatus: ExecutionPayloadStatus.UNSAFE_OPTIMISTIC_STATUS,
357
- errorMessage: `not safe to import ${execResult.status} payload within ${opts.safeSlotsToImportOptimistically} of currentSlot`,
358
- });
359
- return {executionStatus: null, execError} as VerifyBlockExecutionResponse;
360
- }
361
-
203
+ case ExecutionPayloadStatus.SYNCING:
362
204
  return {executionStatus: ExecutionStatus.Syncing, execError: null};
363
- }
364
205
 
365
206
  // If the block has is not valid, or it referenced an invalid terminal block then the
366
207
  // block is invalid, however it has no bearing on any forkChoice cleanup
@@ -1,4 +1,4 @@
1
- import {CachedBeaconStateAllForks, getBlockSignatureSets} from "@lodestar/state-transition";
1
+ import {CachedBeaconStateAllForks, Index2PubkeyCache, getBlockSignatureSets} from "@lodestar/state-transition";
2
2
  import {IndexedAttestation, SignedBeaconBlock} from "@lodestar/types";
3
3
  import {Logger} from "@lodestar/utils";
4
4
  import {Metrics} from "../../metrics/metrics.js";
@@ -15,6 +15,7 @@ import {ImportBlockOpts} from "./types.js";
15
15
  * Since all data is known in advance all signatures are verified at once in parallel.
16
16
  */
17
17
  export async function verifyBlocksSignatures(
18
+ index2pubkey: Index2PubkeyCache,
18
19
  bls: IBlsVerifier,
19
20
  logger: Logger,
20
21
  metrics: Metrics | null,
@@ -38,7 +39,7 @@ export async function verifyBlocksSignatures(
38
39
  : //
39
40
  // Verify signatures per block to track which block is invalid
40
41
  bls.verifySignatureSets(
41
- getBlockSignatureSets(preState0, block, indexedAttestationsByBlock[i], {
42
+ getBlockSignatureSets(index2pubkey, preState0, block, indexedAttestationsByBlock[i], {
42
43
  skipProposerSignature: opts.validProposerSignature,
43
44
  })
44
45
  );
@@ -3,7 +3,7 @@ import {PrivateKey} from "@libp2p/interface";
3
3
  import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
4
4
  import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
5
5
  import {BeaconConfig} from "@lodestar/config";
6
- import {CheckpointWithHex, ExecutionStatus, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
6
+ import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
7
7
  import {LoggerNode} from "@lodestar/logger/node";
8
8
  import {EFFECTIVE_BALANCE_INCREMENT, GENESIS_SLOT, SLOTS_PER_EPOCH, isForkPostElectra} from "@lodestar/params";
9
9
  import {
@@ -757,7 +757,7 @@ export class BeaconChain implements IBeaconChain {
757
757
  RegenCaller.produceBlock
758
758
  );
759
759
  const proposerIndex = state.epochCtx.getBeaconProposer(slot);
760
- const proposerPubKey = state.epochCtx.index2pubkey[proposerIndex].toBytes();
760
+ const proposerPubKey = this.index2pubkey[proposerIndex].toBytes();
761
761
 
762
762
  const {body, produceResult, executionPayloadValue, shouldOverrideBuilder} = await produceBlockBody.call(
763
763
  this,
@@ -1177,17 +1177,6 @@ export class BeaconChain implements IBeaconChain {
1177
1177
  this.seenAggregatedAttestations.prune(epoch);
1178
1178
  this.seenBlockAttesters.prune(epoch);
1179
1179
  this.beaconProposerCache.prune(epoch);
1180
-
1181
- // Poll for merge block in the background to speed-up block production. Only if:
1182
- // - after BELLATRIX_FORK_EPOCH
1183
- // - Beacon node synced
1184
- // - head state not isMergeTransitionComplete
1185
- if (this.config.BELLATRIX_FORK_EPOCH - epoch < 1) {
1186
- const head = this.forkChoice.getHead();
1187
- if (epoch - computeEpochAtSlot(head.slot) < 5 && head.executionStatus === ExecutionStatus.PreMerge) {
1188
- this.eth1.startPollingMergeBlock();
1189
- }
1190
- }
1191
1180
  }
1192
1181
 
1193
1182
  protected onNewHead(head: ProtoBlock): void {
@@ -1355,7 +1344,7 @@ export class BeaconChain implements IBeaconChain {
1355
1344
  throw Error(`State is not in cache for slot ${slot}`);
1356
1345
  }
1357
1346
 
1358
- const rewards = await computeAttestationsRewards(epoch, cachedState, this.config, validatorIds);
1347
+ const rewards = await computeAttestationsRewards(this.pubkey2index, cachedState, validatorIds);
1359
1348
 
1360
1349
  return {rewards, executionOptimistic, finalized};
1361
1350
  }
@@ -1372,6 +1361,6 @@ export class BeaconChain implements IBeaconChain {
1372
1361
 
1373
1362
  preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
1374
1363
 
1375
- return computeSyncCommitteeRewards(block, preState.clone(), validatorIds);
1364
+ return computeSyncCommitteeRewards(this.index2pubkey, block, preState.clone(), validatorIds);
1376
1365
  }
1377
1366
  }