@lodestar/state-transition 1.43.0-dev.9c8becae00 → 1.43.0-dev.a140dd987e

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 (45) 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/processParentExecutionPayload.d.ts +20 -0
  6. package/lib/block/processParentExecutionPayload.d.ts.map +1 -0
  7. package/lib/block/processParentExecutionPayload.js +100 -0
  8. package/lib/block/processParentExecutionPayload.js.map +1 -0
  9. package/lib/block/processWithdrawals.d.ts.map +1 -1
  10. package/lib/block/processWithdrawals.js +12 -4
  11. package/lib/block/processWithdrawals.js.map +1 -1
  12. package/lib/signatureSets/executionPayloadEnvelope.js +1 -1
  13. package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
  14. package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
  15. package/lib/slot/upgradeStateToGloas.js +1 -0
  16. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  17. package/lib/stateView/beaconStateView.d.ts +7 -3
  18. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  19. package/lib/stateView/beaconStateView.js +20 -13
  20. package/lib/stateView/beaconStateView.js.map +1 -1
  21. package/lib/stateView/interface.d.ts +11 -3
  22. package/lib/stateView/interface.d.ts.map +1 -1
  23. package/lib/stateView/interface.js.map +1 -1
  24. package/lib/util/computeAnchorCheckpoint.d.ts +1 -1
  25. package/lib/util/computeAnchorCheckpoint.d.ts.map +1 -1
  26. package/lib/util/computeAnchorCheckpoint.js +6 -19
  27. package/lib/util/computeAnchorCheckpoint.js.map +1 -1
  28. package/lib/util/gloas.d.ts.map +1 -1
  29. package/lib/util/gloas.js +1 -0
  30. package/lib/util/gloas.js.map +1 -1
  31. package/package.json +7 -7
  32. package/src/block/index.ts +12 -4
  33. package/src/block/processParentExecutionPayload.ts +116 -0
  34. package/src/block/processWithdrawals.ts +12 -4
  35. package/src/signatureSets/executionPayloadEnvelope.ts +1 -1
  36. package/src/slot/upgradeStateToGloas.ts +3 -0
  37. package/src/stateView/beaconStateView.ts +24 -20
  38. package/src/stateView/interface.ts +13 -6
  39. package/src/util/computeAnchorCheckpoint.ts +6 -19
  40. package/src/util/gloas.ts +1 -0
  41. package/lib/block/processExecutionPayloadEnvelope.d.ts +0 -9
  42. package/lib/block/processExecutionPayloadEnvelope.d.ts.map +0 -1
  43. package/lib/block/processExecutionPayloadEnvelope.js +0 -106
  44. package/lib/block/processExecutionPayloadEnvelope.js.map +0 -1
  45. package/src/block/processExecutionPayloadEnvelope.ts +0 -175
@@ -41,7 +41,6 @@ import {
41
41
  rewards,
42
42
  } from "@lodestar/types";
43
43
  import {Checkpoint, Fork} from "@lodestar/types/phase0";
44
- import {ProcessExecutionPayloadEnvelopeOpts} from "../block/processExecutionPayloadEnvelope.js";
45
44
  import {VoluntaryExitValidity} from "../block/processVoluntaryExit.js";
46
45
  import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
47
46
  import {EpochTransitionCacheOpts} from "../cache/epochTransitionCache.js";
@@ -138,7 +137,13 @@ export interface IBeaconStateView {
138
137
  isStateValidatorsNodesPopulated(): boolean;
139
138
 
140
139
  // Serialization
141
- loadOtherState(stateBytes: Uint8Array, seedValidatorsBytes?: Uint8Array): IBeaconStateView;
140
+ /** Set `preloadValidatorsAndBalances` only when the whole state will be consumed
141
+ * immediately (e.g. CP reload before block replay). */
142
+ loadOtherState(
143
+ stateBytes: Uint8Array,
144
+ seedValidatorsBytes?: Uint8Array,
145
+ opts?: {preloadValidatorsAndBalances?: boolean}
146
+ ): IBeaconStateView;
142
147
  toValue(): BeaconState;
143
148
  serialize(): Uint8Array;
144
149
  serializedSize(): number;
@@ -248,10 +253,12 @@ export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
248
253
  getBuilder(index: BuilderIndex): gloas.Builder;
249
254
  canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean;
250
255
  getIndexInPayloadTimelinessCommittee(validatorIndex: ValidatorIndex, slot: Slot): number;
251
- processExecutionPayloadEnvelope(
252
- signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
253
- opts?: ProcessExecutionPayloadEnvelopeOpts
254
- ): IBeaconStateView;
256
+ /**
257
+ * Compute expected withdrawals as if the parent was FULL.
258
+ * Clones the state, applies parent payload effects, then computes withdrawals.
259
+ * Used by prepare_execution_payload when building on FULL parent.
260
+ */
261
+ getExpectedWithdrawalsForFullParent(executionRequests: electra.ExecutionRequests): capella.Withdrawal[];
255
262
  }
256
263
 
257
264
  /**
@@ -1,34 +1,21 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {GENESIS_SLOT, ZERO_HASH} from "@lodestar/params";
2
+ import {ZERO_HASH} from "@lodestar/params";
3
3
  import {phase0, ssz} from "@lodestar/types";
4
4
  import {BeaconStateAllForks} from "../types.js";
5
- import {blockToHeader} from "./blockRoot.js";
6
5
  import {computeCheckpointEpochAtStateSlot} from "./epoch.js";
7
6
 
8
7
  export function computeAnchorCheckpoint(
9
- config: ChainForkConfig,
8
+ _config: ChainForkConfig,
10
9
  anchorState: BeaconStateAllForks
11
10
  ): {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader} {
12
- let blockHeader: phase0.BeaconBlockHeader;
13
- let root: Uint8Array;
14
- const blockTypes = config.getForkTypes(anchorState.latestBlockHeader.slot);
15
-
16
- if (anchorState.latestBlockHeader.slot === GENESIS_SLOT) {
17
- const block = blockTypes.BeaconBlock.defaultValue();
18
- block.stateRoot = anchorState.hashTreeRoot();
19
- blockHeader = blockToHeader(config, block);
20
- root = ssz.phase0.BeaconBlockHeader.hashTreeRoot(blockHeader);
21
- } else {
22
- blockHeader = ssz.phase0.BeaconBlockHeader.clone(anchorState.latestBlockHeader);
23
- if (ssz.Root.equals(blockHeader.stateRoot, ZERO_HASH)) {
24
- blockHeader.stateRoot = anchorState.hashTreeRoot();
25
- }
26
- root = ssz.phase0.BeaconBlockHeader.hashTreeRoot(blockHeader);
11
+ const blockHeader = ssz.phase0.BeaconBlockHeader.clone(anchorState.latestBlockHeader);
12
+ if (ssz.Root.equals(blockHeader.stateRoot, ZERO_HASH)) {
13
+ blockHeader.stateRoot = anchorState.hashTreeRoot();
27
14
  }
28
15
 
29
16
  return {
30
17
  checkpoint: {
31
- root,
18
+ root: ssz.phase0.BeaconBlockHeader.hashTreeRoot(blockHeader),
32
19
  // the checkpoint epoch = computeEpochAtSlot(anchorState.slot) + 1 if slot is not at epoch boundary
33
20
  // this is similar to a process_slots() call
34
21
  epoch: computeCheckpointEpochAtStateSlot(anchorState.slot),
package/src/util/gloas.ts CHANGED
@@ -172,6 +172,7 @@ export function isAttestationSameSlotRootCache(rootCache: RootCache, data: Attes
172
172
  return isMatchingBlockRoot && isCurrentBlockRoot;
173
173
  }
174
174
 
175
+ // TODO GLOAS: This function no longer exists in v1.7.0-alpha.5 specs. Remove it when appropriate to do so
175
176
  export function isParentBlockFull(state: CachedBeaconStateGloas): boolean {
176
177
  return byteArrayEquals(state.latestExecutionPayloadBid.blockHash, state.latestBlockHash);
177
178
  }
@@ -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
- }