@lodestar/state-transition 1.43.0-dev.4fb05c546d → 1.43.0-dev.4fe6b362c9

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 (138) hide show
  1. package/lib/block/index.d.ts +2 -2
  2. package/lib/block/index.d.ts.map +1 -1
  3. package/lib/block/index.js +11 -4
  4. package/lib/block/index.js.map +1 -1
  5. package/lib/block/processConsolidationRequest.d.ts.map +1 -1
  6. package/lib/block/processConsolidationRequest.js +2 -1
  7. package/lib/block/processConsolidationRequest.js.map +1 -1
  8. package/lib/block/processDepositRequest.d.ts +3 -11
  9. package/lib/block/processDepositRequest.d.ts.map +1 -1
  10. package/lib/block/processDepositRequest.js +27 -35
  11. package/lib/block/processDepositRequest.js.map +1 -1
  12. package/lib/block/processParentExecutionPayload.d.ts +20 -0
  13. package/lib/block/processParentExecutionPayload.d.ts.map +1 -0
  14. package/lib/block/processParentExecutionPayload.js +101 -0
  15. package/lib/block/processParentExecutionPayload.js.map +1 -0
  16. package/lib/block/processWithdrawals.d.ts.map +1 -1
  17. package/lib/block/processWithdrawals.js +10 -4
  18. package/lib/block/processWithdrawals.js.map +1 -1
  19. package/lib/cache/epochCache.js +3 -3
  20. package/lib/cache/epochCache.js.map +1 -1
  21. package/lib/epoch/processPendingDeposits.d.ts.map +1 -1
  22. package/lib/epoch/processPendingDeposits.js +4 -2
  23. package/lib/epoch/processPendingDeposits.js.map +1 -1
  24. package/lib/lightClient/spec/index.d.ts +22 -0
  25. package/lib/lightClient/spec/index.d.ts.map +1 -0
  26. package/lib/lightClient/spec/index.js +58 -0
  27. package/lib/lightClient/spec/index.js.map +1 -0
  28. package/lib/lightClient/spec/isBetterUpdate.d.ts +23 -0
  29. package/lib/lightClient/spec/isBetterUpdate.d.ts.map +1 -0
  30. package/lib/lightClient/spec/isBetterUpdate.js +66 -0
  31. package/lib/lightClient/spec/isBetterUpdate.js.map +1 -0
  32. package/lib/lightClient/spec/processLightClientUpdate.d.ts +12 -0
  33. package/lib/lightClient/spec/processLightClientUpdate.d.ts.map +1 -0
  34. package/lib/lightClient/spec/processLightClientUpdate.js +80 -0
  35. package/lib/lightClient/spec/processLightClientUpdate.js.map +1 -0
  36. package/lib/lightClient/spec/store.d.ts +45 -0
  37. package/lib/lightClient/spec/store.d.ts.map +1 -0
  38. package/lib/lightClient/spec/store.js +56 -0
  39. package/lib/lightClient/spec/store.js.map +1 -0
  40. package/lib/lightClient/spec/utils.d.ts +47 -0
  41. package/lib/lightClient/spec/utils.d.ts.map +1 -0
  42. package/lib/lightClient/spec/utils.js +197 -0
  43. package/lib/lightClient/spec/utils.js.map +1 -0
  44. package/lib/lightClient/spec/validateLightClientBootstrap.d.ts +4 -0
  45. package/lib/lightClient/spec/validateLightClientBootstrap.d.ts.map +1 -0
  46. package/lib/lightClient/spec/validateLightClientBootstrap.js +22 -0
  47. package/lib/lightClient/spec/validateLightClientBootstrap.js.map +1 -0
  48. package/lib/lightClient/spec/validateLightClientUpdate.d.ts +5 -0
  49. package/lib/lightClient/spec/validateLightClientUpdate.d.ts.map +1 -0
  50. package/lib/lightClient/spec/validateLightClientUpdate.js +88 -0
  51. package/lib/lightClient/spec/validateLightClientUpdate.js.map +1 -0
  52. package/lib/signatureSets/executionPayloadEnvelope.js +1 -1
  53. package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
  54. package/lib/signatureSets/index.d.ts +1 -0
  55. package/lib/signatureSets/index.d.ts.map +1 -1
  56. package/lib/signatureSets/index.js +1 -0
  57. package/lib/signatureSets/index.js.map +1 -1
  58. package/lib/signatureSets/proposerPreferences.d.ts +4 -0
  59. package/lib/signatureSets/proposerPreferences.d.ts.map +1 -0
  60. package/lib/signatureSets/proposerPreferences.js +8 -0
  61. package/lib/signatureSets/proposerPreferences.js.map +1 -0
  62. package/lib/slot/upgradeStateToElectra.d.ts.map +1 -1
  63. package/lib/slot/upgradeStateToElectra.js +2 -2
  64. package/lib/slot/upgradeStateToElectra.js.map +1 -1
  65. package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
  66. package/lib/slot/upgradeStateToGloas.js +34 -28
  67. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  68. package/lib/stateView/beaconStateView.d.ts +20 -7
  69. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  70. package/lib/stateView/beaconStateView.js +52 -16
  71. package/lib/stateView/beaconStateView.js.map +1 -1
  72. package/lib/stateView/interface.d.ts +14 -4
  73. package/lib/stateView/interface.d.ts.map +1 -1
  74. package/lib/stateView/interface.js.map +1 -1
  75. package/lib/util/computeAnchorCheckpoint.d.ts +1 -1
  76. package/lib/util/computeAnchorCheckpoint.d.ts.map +1 -1
  77. package/lib/util/computeAnchorCheckpoint.js +6 -19
  78. package/lib/util/computeAnchorCheckpoint.js.map +1 -1
  79. package/lib/util/epoch.d.ts.map +1 -1
  80. package/lib/util/epoch.js +6 -4
  81. package/lib/util/epoch.js.map +1 -1
  82. package/lib/util/gloas.d.ts +0 -1
  83. package/lib/util/gloas.d.ts.map +1 -1
  84. package/lib/util/gloas.js +0 -3
  85. package/lib/util/gloas.js.map +1 -1
  86. package/lib/util/index.d.ts +1 -0
  87. package/lib/util/index.d.ts.map +1 -1
  88. package/lib/util/index.js +1 -0
  89. package/lib/util/index.js.map +1 -1
  90. package/lib/util/loadState/loadState.js +4 -4
  91. package/lib/util/loadState/loadState.js.map +1 -1
  92. package/lib/util/pendingDepositsLookup.d.ts +40 -0
  93. package/lib/util/pendingDepositsLookup.d.ts.map +1 -0
  94. package/lib/util/pendingDepositsLookup.js +84 -0
  95. package/lib/util/pendingDepositsLookup.js.map +1 -0
  96. package/lib/util/shuffling.d.ts +6 -5
  97. package/lib/util/shuffling.d.ts.map +1 -1
  98. package/lib/util/shuffling.js +13 -15
  99. package/lib/util/shuffling.js.map +1 -1
  100. package/lib/util/validator.d.ts +14 -2
  101. package/lib/util/validator.d.ts.map +1 -1
  102. package/lib/util/validator.js +24 -2
  103. package/lib/util/validator.js.map +1 -1
  104. package/package.json +13 -8
  105. package/src/block/index.ts +12 -4
  106. package/src/block/processConsolidationRequest.ts +2 -1
  107. package/src/block/processDepositRequest.ts +29 -47
  108. package/src/block/processParentExecutionPayload.ts +117 -0
  109. package/src/block/processWithdrawals.ts +12 -4
  110. package/src/cache/epochCache.ts +3 -3
  111. package/src/epoch/processPendingDeposits.ts +5 -2
  112. package/src/lightClient/spec/index.ts +101 -0
  113. package/src/lightClient/spec/isBetterUpdate.ts +94 -0
  114. package/src/lightClient/spec/processLightClientUpdate.ts +119 -0
  115. package/src/lightClient/spec/store.ts +106 -0
  116. package/src/lightClient/spec/utils.ts +317 -0
  117. package/src/lightClient/spec/validateLightClientBootstrap.ts +39 -0
  118. package/src/lightClient/spec/validateLightClientUpdate.ts +145 -0
  119. package/src/signatureSets/executionPayloadEnvelope.ts +1 -1
  120. package/src/signatureSets/index.ts +1 -0
  121. package/src/signatureSets/proposerPreferences.ts +12 -0
  122. package/src/slot/upgradeStateToElectra.ts +4 -2
  123. package/src/slot/upgradeStateToGloas.ts +44 -44
  124. package/src/stateView/beaconStateView.ts +60 -25
  125. package/src/stateView/interface.ts +16 -7
  126. package/src/util/computeAnchorCheckpoint.ts +6 -19
  127. package/src/util/epoch.ts +13 -4
  128. package/src/util/gloas.ts +0 -4
  129. package/src/util/index.ts +1 -0
  130. package/src/util/loadState/loadState.ts +4 -4
  131. package/src/util/pendingDepositsLookup.ts +105 -0
  132. package/src/util/shuffling.ts +17 -15
  133. package/src/util/validator.ts +42 -2
  134. package/lib/block/processExecutionPayloadEnvelope.d.ts +0 -9
  135. package/lib/block/processExecutionPayloadEnvelope.d.ts.map +0 -1
  136. package/lib/block/processExecutionPayloadEnvelope.js +0 -106
  137. package/lib/block/processExecutionPayloadEnvelope.js.map +0 -1
  138. package/src/block/processExecutionPayloadEnvelope.ts +0 -175
@@ -0,0 +1,105 @@
1
+ import {BeaconConfig} from "@lodestar/config";
2
+ import {PubkeyHex, electra} from "@lodestar/types";
3
+ import {toPubkeyHex} from "@lodestar/utils";
4
+ import {isValidDepositSignature} from "../block/processDeposit.js";
5
+ import {CachedBeaconStateGloas} from "../types.js";
6
+
7
+ type PendingDepositsValidation = {
8
+ hasValidSignature: boolean;
9
+ validatedCount: number;
10
+ };
11
+
12
+ /**
13
+ * Mutable lookup for the pending-deposit sequence used by builder-routing logic.
14
+ *
15
+ * This is to implement the spec's `is_pending_validator(pending_deposits, pubkey)` lazily:
16
+ * deposits are grouped by pubkey without verifying signatures, and BLS verification is
17
+ * deferred until a builder deposit needs to know whether the same pubkey already has a
18
+ * valid pending validator deposit.
19
+ *
20
+ * Call `add()` whenever a deposit is appended to the represented sequence. A cached `true`
21
+ * result short-circuits all subsequent checks for that pubkey; a cached `false` records
22
+ * how many deposits were already verified, so appending a new deposit only verifies the
23
+ * newly-appended tail rather than re-running BLS on previously-invalid entries.
24
+ */
25
+ export class PendingDepositsLookup {
26
+ private constructor(
27
+ private readonly depositsByPubkey: Map<PubkeyHex, electra.PendingDeposit[]>,
28
+ private readonly validationCache: Map<PubkeyHex, PendingDepositsValidation>
29
+ ) {}
30
+
31
+ /** Build an empty lookup for a sequence that will be populated incrementally. */
32
+ static buildEmpty(): PendingDepositsLookup {
33
+ return new PendingDepositsLookup(new Map(), new Map());
34
+ }
35
+
36
+ /**
37
+ * Build a pubkey -> pending-deposits lookup from `state.pendingDeposits`.
38
+ * No BLS work is done here; signature verification happens lazily in `hasPendingValidator`.
39
+ */
40
+ static build(state: CachedBeaconStateGloas): PendingDepositsLookup {
41
+ const lookup = PendingDepositsLookup.buildEmpty();
42
+ for (const pendingDeposit of state.pendingDeposits.getAllReadonly()) {
43
+ lookup.add(pendingDeposit);
44
+ }
45
+ return lookup;
46
+ }
47
+
48
+ /**
49
+ * Append a pending deposit to the represented sequence.
50
+ * Pass `pubkeyHex` if the caller has already computed it.
51
+ */
52
+ add(pendingDeposit: electra.PendingDeposit, pubkeyHex?: PubkeyHex): void {
53
+ const key = pubkeyHex ?? toPubkeyHex(pendingDeposit.pubkey);
54
+ const existing = this.depositsByPubkey.get(key);
55
+ if (existing) {
56
+ existing.push(pendingDeposit);
57
+ } else {
58
+ this.depositsByPubkey.set(key, [pendingDeposit]);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Returns true if any pending deposit for `pubkeyHex` has a valid BLS deposit signature.
64
+ * Memoizes the result in `validationCache` so repeated checks for the same pubkey
65
+ * within a block only verify deposits that have not already been checked.
66
+ */
67
+ hasPendingValidator(config: BeaconConfig, pubkeyHex: PubkeyHex): boolean {
68
+ const validation = this.validationCache.get(pubkeyHex);
69
+ if (validation?.hasValidSignature === true) {
70
+ return true;
71
+ }
72
+
73
+ const deposits = this.depositsByPubkey.get(pubkeyHex);
74
+ if (deposits === undefined) {
75
+ return false;
76
+ }
77
+
78
+ // hasValidSignature is false or undefined; resume from the last validatedCount so
79
+ // previously-checked invalid deposits are not re-verified.
80
+ const startIndex = validation?.validatedCount ?? 0;
81
+ if (startIndex === deposits.length) {
82
+ // Nothing new to check; the cached false result still holds.
83
+ return false;
84
+ }
85
+
86
+ for (let i = startIndex; i < deposits.length; i++) {
87
+ const deposit = deposits[i];
88
+ if (
89
+ isValidDepositSignature(
90
+ config,
91
+ deposit.pubkey,
92
+ deposit.withdrawalCredentials,
93
+ deposit.amount,
94
+ deposit.signature
95
+ )
96
+ ) {
97
+ this.validationCache.set(pubkeyHex, {hasValidSignature: true, validatedCount: i + 1});
98
+ return true;
99
+ }
100
+ }
101
+
102
+ this.validationCache.set(pubkeyHex, {hasValidSignature: false, validatedCount: deposits.length});
103
+ return false;
104
+ }
105
+ }
@@ -17,29 +17,31 @@ import {computeStartSlotAtEpoch} from "./epoch.js";
17
17
  import {EpochShuffling} from "./epochShuffling.js";
18
18
 
19
19
  /**
20
- * Returns the block root which decided the proposer shuffling for the current epoch. This root
21
- * can be used to key this proposer shuffling.
20
+ * Block root that decided the proposer shuffling for `proposalEpoch` (keys that shuffling).
21
+ * Computed for the requested epoch, not `state.epoch`, so it is correct when `state` is one
22
+ * epoch off the requested epoch (e.g. serving next-epoch duties from the current state).
22
23
  *
23
- * Returns `null` on the one-off scenario where the genesis block decides its own shuffling.
24
- * It should be set to the latest block applied to this `state` or the genesis block root.
24
+ * Returns `null` when the genesis block decides its own shuffling (caller falls back to the
25
+ * genesis block root).
25
26
  */
26
- export function proposerShufflingDecisionRoot(fork: ForkName, state: IBeaconStateView): Root | null {
27
- const decisionSlot = proposerShufflingDecisionSlot(fork, state);
27
+ export function proposerShufflingDecisionRoot(
28
+ fork: ForkName,
29
+ state: IBeaconStateView,
30
+ proposalEpoch: Epoch
31
+ ): Root | null {
32
+ const decisionSlot = proposerShufflingDecisionSlot(fork, proposalEpoch);
28
33
  if (state.slot === decisionSlot) {
29
34
  return null;
30
35
  }
31
36
  return state.getBlockRootAtSlot(decisionSlot);
32
37
  }
33
38
 
34
- /**
35
- * Returns the slot at which the proposer shuffling was decided. The block root at this slot
36
- * can be used to key the proposer shuffling for the current epoch.
37
- */
38
- function proposerShufflingDecisionSlot(fork: ForkName, state: IBeaconStateView): Slot {
39
- // After fulu, the decision slot is in previous epoch due to deterministic proposer lookahead
40
- const epoch = isForkPostFulu(fork) ? state.epoch - 1 : state.epoch;
41
- const startSlot = computeStartSlotAtEpoch(epoch);
42
- return Math.max(startSlot - 1, 0);
39
+ /** Slot whose block root keys the proposer shuffling for `proposalEpoch`. */
40
+ function proposerShufflingDecisionSlot(fork: ForkName, proposalEpoch: Epoch): Slot {
41
+ // Post-Fulu the shuffling is decided one epoch earlier (deterministic proposer lookahead,
42
+ // MIN_SEED_LOOKAHEAD = 1); pre-Fulu it is the last block before `proposalEpoch`.
43
+ const decisionEpoch = isForkPostFulu(fork) ? proposalEpoch - 1 : proposalEpoch;
44
+ return Math.max(computeStartSlotAtEpoch(decisionEpoch) - 1, 0);
43
45
  }
44
46
 
45
47
  /**
@@ -44,7 +44,12 @@ export function getActiveValidatorIndices(state: BeaconStateAllForks, epoch: Epo
44
44
  return new Uint32Array(indices);
45
45
  }
46
46
 
47
- export function getActivationChurnLimit(config: ChainForkConfig, fork: ForkSeq, activeValidatorCount: number): number {
47
+ // Deneb fork upgrade only
48
+ export function getValidatorActivationChurnLimit(
49
+ config: ChainForkConfig,
50
+ fork: ForkSeq,
51
+ activeValidatorCount: number
52
+ ): number {
48
53
  if (fork >= ForkSeq.deneb) {
49
54
  return Math.min(config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT, getChurnLimit(config, activeValidatorCount));
50
55
  }
@@ -84,7 +89,42 @@ export function getActivationExitChurnLimit(epochCtx: EpochCache): number {
84
89
  return Math.min(epochCtx.config.MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT, getBalanceChurnLimitFromCache(epochCtx));
85
90
  }
86
91
 
87
- export function getConsolidationChurnLimit(epochCtx: EpochCache): number {
92
+ /**
93
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.6/specs/gloas/beacon-chain.md#new-get_activation_churn_limit
94
+ */
95
+ export function getActivationChurnLimit(epochCtx: EpochCache): number {
96
+ const churn = getBalanceChurnLimit(
97
+ epochCtx.totalActiveBalanceIncrements,
98
+ epochCtx.config.CHURN_LIMIT_QUOTIENT_GLOAS,
99
+ epochCtx.config.MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA
100
+ );
101
+ return Math.min(epochCtx.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT_GLOAS, churn);
102
+ }
103
+
104
+ /**
105
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.6/specs/gloas/beacon-chain.md#new-get_exit_churn_limit
106
+ */
107
+ export function getExitChurnLimit(epochCtx: EpochCache): number {
108
+ return getBalanceChurnLimit(
109
+ epochCtx.totalActiveBalanceIncrements,
110
+ epochCtx.config.CHURN_LIMIT_QUOTIENT_GLOAS,
111
+ epochCtx.config.MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA
112
+ );
113
+ }
114
+
115
+ /**
116
+ * Spec (electra): get_consolidation_churn_limit (uses combined balance churn minus activation+exit churn)
117
+ * Spec (gloas): get_consolidation_churn_limit (independent quotient, no MIN floor)
118
+ */
119
+ export function getConsolidationChurnLimit(fork: ForkSeq, epochCtx: EpochCache): number {
120
+ if (fork >= ForkSeq.gloas) {
121
+ // No MIN floor — pass 0 so getBalanceChurnLimit's max(churn, min) is a no-op.
122
+ return getBalanceChurnLimit(
123
+ epochCtx.totalActiveBalanceIncrements,
124
+ epochCtx.config.CONSOLIDATION_CHURN_LIMIT_QUOTIENT,
125
+ 0
126
+ );
127
+ }
88
128
  return getBalanceChurnLimitFromCache(epochCtx) - getActivationExitChurnLimit(epochCtx);
89
129
  }
90
130
 
@@ -1,9 +0,0 @@
1
- import { gloas } from "@lodestar/types";
2
- import { CachedBeaconStateGloas } from "../types.js";
3
- export type ProcessExecutionPayloadEnvelopeOpts = {
4
- verifySignature?: boolean;
5
- verifyStateRoot?: boolean;
6
- dontTransferCache?: boolean;
7
- };
8
- export declare function processExecutionPayloadEnvelope(state: CachedBeaconStateGloas, signedEnvelope: gloas.SignedExecutionPayloadEnvelope, opts?: ProcessExecutionPayloadEnvelopeOpts): CachedBeaconStateGloas;
9
- //# sourceMappingURL=processExecutionPayloadEnvelope.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"processExecutionPayloadEnvelope.d.ts","sourceRoot":"","sources":["../../src/block/processExecutionPayloadEnvelope.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAM,MAAM,iBAAiB,CAAC;AAI3C,OAAO,EAAC,sBAAsB,EAAC,MAAM,aAAa,CAAC;AAOnD,MAAM,MAAM,mCAAmC,GAAG;IAChD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAKF,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,sBAAsB,EAC7B,cAAc,EAAE,KAAK,CAAC,8BAA8B,EACpD,IAAI,CAAC,EAAE,mCAAmC,GACzC,sBAAsB,CA0DxB"}
@@ -1,106 +0,0 @@
1
- import { SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT } from "@lodestar/params";
2
- import { ssz } from "@lodestar/types";
3
- import { byteArrayEquals, toHex, toRootHex } from "@lodestar/utils";
4
- import { getExecutionPayloadEnvelopeSignatureSet } from "../signatureSets/executionPayloadEnvelope.js";
5
- import { BeaconStateView } from "../stateView/beaconStateView.js";
6
- import { computeTimeAtSlot } from "../util/index.js";
7
- import { verifySignatureSet } from "../util/signatureSets.js";
8
- import { processConsolidationRequest } from "./processConsolidationRequest.js";
9
- import { getPendingValidatorPubkeys, processDepositRequest } from "./processDepositRequest.js";
10
- import { processWithdrawalRequest } from "./processWithdrawalRequest.js";
11
- // Unlike other block processing functions which mutate state in-place, this function
12
- // clones the state and returns the post-state, similar to stateTransition().
13
- // This function does not call execution engine to verify payload. Need to call it from other place.
14
- export function processExecutionPayloadEnvelope(state, signedEnvelope, opts) {
15
- const { verifySignature = true, verifyStateRoot = true } = opts ?? {};
16
- const envelope = signedEnvelope.message;
17
- const payload = envelope.payload;
18
- const fork = state.config.getForkSeq(envelope.slot);
19
- if (verifySignature && !verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope)) {
20
- throw Error(`Execution payload envelope has invalid signature builderIndex=${envelope.builderIndex}`);
21
- }
22
- // .clone() before mutating state, similar to stateTransition()
23
- const postState = state.clone(opts?.dontTransferCache);
24
- validateExecutionPayloadEnvelope(postState, envelope);
25
- const requests = envelope.executionRequests;
26
- if (requests.deposits.length > 0) {
27
- // Build cache of pending validator pubkeys once, shared across all deposit requests
28
- const pendingValidatorPubkeys = getPendingValidatorPubkeys(postState.config, postState);
29
- for (const deposit of requests.deposits) {
30
- processDepositRequest(fork, postState, deposit, pendingValidatorPubkeys);
31
- }
32
- }
33
- for (const withdrawal of requests.withdrawals) {
34
- processWithdrawalRequest(fork, postState, withdrawal);
35
- }
36
- for (const consolidation of requests.consolidations) {
37
- processConsolidationRequest(postState, consolidation);
38
- }
39
- // Queue the builder payment
40
- const paymentIndex = SLOTS_PER_EPOCH + (postState.slot % SLOTS_PER_EPOCH);
41
- const payment = postState.builderPendingPayments.get(paymentIndex).clone();
42
- const amount = payment.withdrawal.amount;
43
- if (amount > 0) {
44
- postState.builderPendingWithdrawals.push(payment.withdrawal);
45
- }
46
- postState.builderPendingPayments.set(paymentIndex, ssz.gloas.BuilderPendingPayment.defaultViewDU());
47
- // Cache the execution payload hash
48
- postState.executionPayloadAvailability.set(postState.slot % SLOTS_PER_HISTORICAL_ROOT, true);
49
- postState.latestBlockHash = payload.blockHash;
50
- postState.commit();
51
- if (verifyStateRoot && !byteArrayEquals(envelope.stateRoot, postState.hashTreeRoot())) {
52
- throw new Error(`Envelope's state root does not match state envelope=${toRootHex(envelope.stateRoot)} state=${toRootHex(postState.hashTreeRoot())}`);
53
- }
54
- return postState;
55
- }
56
- function validateExecutionPayloadEnvelope(state, envelope) {
57
- const payload = envelope.payload;
58
- // Cache latest block header state root
59
- if (byteArrayEquals(state.latestBlockHeader.stateRoot, ssz.Root.defaultValue())) {
60
- const previousStateRoot = state.hashTreeRoot();
61
- state.latestBlockHeader.stateRoot = previousStateRoot;
62
- }
63
- // Verify consistency with the beacon block
64
- if (!byteArrayEquals(envelope.beaconBlockRoot, state.latestBlockHeader.hashTreeRoot())) {
65
- throw new Error(`Envelope's block is not the latest block header envelope=${toRootHex(envelope.beaconBlockRoot)} latestBlockHeader=${toRootHex(state.latestBlockHeader.hashTreeRoot())}`);
66
- }
67
- if (envelope.slot !== state.slot) {
68
- throw new Error(`Slot mismatch between envelope and state envelope=${envelope.slot} state=${state.slot}`);
69
- }
70
- // Verify consistency with the committed bid
71
- const committedBid = state.latestExecutionPayloadBid;
72
- if (envelope.builderIndex !== committedBid.builderIndex) {
73
- throw new Error(`Builder index mismatch between envelope and committed bid envelope=${envelope.builderIndex} committedBid=${committedBid.builderIndex}`);
74
- }
75
- if (!byteArrayEquals(committedBid.prevRandao, payload.prevRandao)) {
76
- throw new Error(`Prev randao mismatch between committed bid and payload committedBid=${toHex(committedBid.prevRandao)} payload=${toHex(payload.prevRandao)}`);
77
- }
78
- // Verify consistency with expected withdrawals
79
- const payloadWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
80
- const expectedWithdrawalsRoot = state.payloadExpectedWithdrawals.hashTreeRoot();
81
- if (!byteArrayEquals(payloadWithdrawalsRoot, expectedWithdrawalsRoot)) {
82
- throw new Error(`Withdrawals mismatch between payload and expected withdrawals payload=${toRootHex(payloadWithdrawalsRoot)} expected=${toRootHex(expectedWithdrawalsRoot)}`);
83
- }
84
- // Verify the gas_limit
85
- if (Number(committedBid.gasLimit) !== payload.gasLimit) {
86
- throw new Error(`Gas limit mismatch between envelope's payload and committed bid envelope=${payload.gasLimit} committedBid=${Number(committedBid.gasLimit)}`);
87
- }
88
- // Verify the block hash
89
- if (!byteArrayEquals(committedBid.blockHash, payload.blockHash)) {
90
- throw new Error(`Block hash mismatch between envelope's payload and committed bid envelope=${toRootHex(payload.blockHash)} committedBid=${toRootHex(committedBid.blockHash)}`);
91
- }
92
- // Verify consistency of the parent hash with respect to the previous execution payload
93
- if (!byteArrayEquals(payload.parentHash, state.latestBlockHash)) {
94
- throw new Error(`Parent hash mismatch between envelope's payload and state envelope=${toRootHex(payload.parentHash)} state=${toRootHex(state.latestBlockHash)}`);
95
- }
96
- // Verify timestamp
97
- if (payload.timestamp !== computeTimeAtSlot(state.config, state.slot, state.genesisTime)) {
98
- throw new Error(`Timestamp mismatch between envelope's payload and state envelope=${payload.timestamp} state=${computeTimeAtSlot(state.config, state.slot, state.genesisTime)}`);
99
- }
100
- // Skipped: Verify the execution payload is valid
101
- }
102
- function verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope) {
103
- const signatureSet = getExecutionPayloadEnvelopeSignatureSet(state.config, state.epochCtx.pubkeyCache, new BeaconStateView(state), signedEnvelope, state.latestBlockHeader.proposerIndex);
104
- return verifySignatureSet(signatureSet);
105
- }
106
- //# sourceMappingURL=processExecutionPayloadEnvelope.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"processExecutionPayloadEnvelope.js","sourceRoot":"","sources":["../../src/block/processExecutionPayloadEnvelope.ts"],"names":[],"mappings":"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"}
@@ -1,175 +0,0 @@
1
- import {SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
2
- import {gloas, ssz} from "@lodestar/types";
3
- import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
4
- import {getExecutionPayloadEnvelopeSignatureSet} from "../signatureSets/executionPayloadEnvelope.js";
5
- import {BeaconStateView} from "../stateView/beaconStateView.js";
6
- import {CachedBeaconStateGloas} from "../types.js";
7
- import {computeTimeAtSlot} from "../util/index.js";
8
- import {verifySignatureSet} from "../util/signatureSets.js";
9
- import {processConsolidationRequest} from "./processConsolidationRequest.js";
10
- import {getPendingValidatorPubkeys, processDepositRequest} from "./processDepositRequest.js";
11
- import {processWithdrawalRequest} from "./processWithdrawalRequest.js";
12
-
13
- export type ProcessExecutionPayloadEnvelopeOpts = {
14
- verifySignature?: boolean;
15
- verifyStateRoot?: boolean;
16
- dontTransferCache?: boolean;
17
- };
18
-
19
- // Unlike other block processing functions which mutate state in-place, this function
20
- // clones the state and returns the post-state, similar to stateTransition().
21
- // This function does not call execution engine to verify payload. Need to call it from other place.
22
- export function processExecutionPayloadEnvelope(
23
- state: CachedBeaconStateGloas,
24
- signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
25
- opts?: ProcessExecutionPayloadEnvelopeOpts
26
- ): CachedBeaconStateGloas {
27
- const {verifySignature = true, verifyStateRoot = true} = opts ?? {};
28
- const envelope = signedEnvelope.message;
29
- const payload = envelope.payload;
30
- const fork = state.config.getForkSeq(envelope.slot);
31
-
32
- if (verifySignature && !verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope)) {
33
- throw Error(`Execution payload envelope has invalid signature builderIndex=${envelope.builderIndex}`);
34
- }
35
-
36
- // .clone() before mutating state, similar to stateTransition()
37
- const postState = state.clone(opts?.dontTransferCache) as CachedBeaconStateGloas;
38
-
39
- validateExecutionPayloadEnvelope(postState, envelope);
40
-
41
- const requests = envelope.executionRequests;
42
-
43
- if (requests.deposits.length > 0) {
44
- // Build cache of pending validator pubkeys once, shared across all deposit requests
45
- const pendingValidatorPubkeys = getPendingValidatorPubkeys(postState.config, postState);
46
-
47
- for (const deposit of requests.deposits) {
48
- processDepositRequest(fork, postState, deposit, pendingValidatorPubkeys);
49
- }
50
- }
51
-
52
- for (const withdrawal of requests.withdrawals) {
53
- processWithdrawalRequest(fork, postState, withdrawal);
54
- }
55
-
56
- for (const consolidation of requests.consolidations) {
57
- processConsolidationRequest(postState, consolidation);
58
- }
59
-
60
- // Queue the builder payment
61
- const paymentIndex = SLOTS_PER_EPOCH + (postState.slot % SLOTS_PER_EPOCH);
62
- const payment = postState.builderPendingPayments.get(paymentIndex).clone();
63
- const amount = payment.withdrawal.amount;
64
-
65
- if (amount > 0) {
66
- postState.builderPendingWithdrawals.push(payment.withdrawal);
67
- }
68
-
69
- postState.builderPendingPayments.set(paymentIndex, ssz.gloas.BuilderPendingPayment.defaultViewDU());
70
-
71
- // Cache the execution payload hash
72
- postState.executionPayloadAvailability.set(postState.slot % SLOTS_PER_HISTORICAL_ROOT, true);
73
- postState.latestBlockHash = payload.blockHash;
74
-
75
- postState.commit();
76
-
77
- if (verifyStateRoot && !byteArrayEquals(envelope.stateRoot, postState.hashTreeRoot())) {
78
- throw new Error(
79
- `Envelope's state root does not match state envelope=${toRootHex(envelope.stateRoot)} state=${toRootHex(postState.hashTreeRoot())}`
80
- );
81
- }
82
-
83
- return postState;
84
- }
85
-
86
- function validateExecutionPayloadEnvelope(
87
- state: CachedBeaconStateGloas,
88
- envelope: gloas.ExecutionPayloadEnvelope
89
- ): void {
90
- const payload = envelope.payload;
91
-
92
- // Cache latest block header state root
93
- if (byteArrayEquals(state.latestBlockHeader.stateRoot, ssz.Root.defaultValue())) {
94
- const previousStateRoot = state.hashTreeRoot();
95
- state.latestBlockHeader.stateRoot = previousStateRoot;
96
- }
97
-
98
- // Verify consistency with the beacon block
99
- if (!byteArrayEquals(envelope.beaconBlockRoot, state.latestBlockHeader.hashTreeRoot())) {
100
- throw new Error(
101
- `Envelope's block is not the latest block header envelope=${toRootHex(envelope.beaconBlockRoot)} latestBlockHeader=${toRootHex(state.latestBlockHeader.hashTreeRoot())}`
102
- );
103
- }
104
-
105
- if (envelope.slot !== state.slot) {
106
- throw new Error(`Slot mismatch between envelope and state envelope=${envelope.slot} state=${state.slot}`);
107
- }
108
-
109
- // Verify consistency with the committed bid
110
- const committedBid = state.latestExecutionPayloadBid;
111
- if (envelope.builderIndex !== committedBid.builderIndex) {
112
- throw new Error(
113
- `Builder index mismatch between envelope and committed bid envelope=${envelope.builderIndex} committedBid=${committedBid.builderIndex}`
114
- );
115
- }
116
-
117
- if (!byteArrayEquals(committedBid.prevRandao, payload.prevRandao)) {
118
- throw new Error(
119
- `Prev randao mismatch between committed bid and payload committedBid=${toHex(committedBid.prevRandao)} payload=${toHex(payload.prevRandao)}`
120
- );
121
- }
122
-
123
- // Verify consistency with expected withdrawals
124
- const payloadWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
125
- const expectedWithdrawalsRoot = state.payloadExpectedWithdrawals.hashTreeRoot();
126
- if (!byteArrayEquals(payloadWithdrawalsRoot, expectedWithdrawalsRoot)) {
127
- throw new Error(
128
- `Withdrawals mismatch between payload and expected withdrawals payload=${toRootHex(payloadWithdrawalsRoot)} expected=${toRootHex(expectedWithdrawalsRoot)}`
129
- );
130
- }
131
-
132
- // Verify the gas_limit
133
- if (Number(committedBid.gasLimit) !== payload.gasLimit) {
134
- throw new Error(
135
- `Gas limit mismatch between envelope's payload and committed bid envelope=${payload.gasLimit} committedBid=${Number(committedBid.gasLimit)}`
136
- );
137
- }
138
-
139
- // Verify the block hash
140
- if (!byteArrayEquals(committedBid.blockHash, payload.blockHash)) {
141
- throw new Error(
142
- `Block hash mismatch between envelope's payload and committed bid envelope=${toRootHex(payload.blockHash)} committedBid=${toRootHex(committedBid.blockHash)}`
143
- );
144
- }
145
-
146
- // Verify consistency of the parent hash with respect to the previous execution payload
147
- if (!byteArrayEquals(payload.parentHash, state.latestBlockHash)) {
148
- throw new Error(
149
- `Parent hash mismatch between envelope's payload and state envelope=${toRootHex(payload.parentHash)} state=${toRootHex(state.latestBlockHash)}`
150
- );
151
- }
152
-
153
- // Verify timestamp
154
- if (payload.timestamp !== computeTimeAtSlot(state.config, state.slot, state.genesisTime)) {
155
- throw new Error(
156
- `Timestamp mismatch between envelope's payload and state envelope=${payload.timestamp} state=${computeTimeAtSlot(state.config, state.slot, state.genesisTime)}`
157
- );
158
- }
159
-
160
- // Skipped: Verify the execution payload is valid
161
- }
162
-
163
- function verifyExecutionPayloadEnvelopeSignature(
164
- state: CachedBeaconStateGloas,
165
- signedEnvelope: gloas.SignedExecutionPayloadEnvelope
166
- ): boolean {
167
- const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
168
- state.config,
169
- state.epochCtx.pubkeyCache,
170
- new BeaconStateView(state),
171
- signedEnvelope,
172
- state.latestBlockHeader.proposerIndex
173
- );
174
- return verifySignatureSet(signatureSet);
175
- }