@lodestar/state-transition 1.43.0-dev.0bc48d3b54 → 1.43.0-dev.1213f9c92d
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.
- package/lib/block/index.d.ts +2 -2
- package/lib/block/index.d.ts.map +1 -1
- package/lib/block/index.js +11 -4
- package/lib/block/index.js.map +1 -1
- package/lib/block/processParentExecutionPayload.d.ts +20 -0
- package/lib/block/processParentExecutionPayload.d.ts.map +1 -0
- package/lib/block/processParentExecutionPayload.js +100 -0
- package/lib/block/processParentExecutionPayload.js.map +1 -0
- package/lib/block/processWithdrawals.d.ts.map +1 -1
- package/lib/block/processWithdrawals.js +13 -5
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/signatureSets/executionPayloadEnvelope.js +1 -1
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
- package/lib/signatureSets/index.d.ts +1 -0
- package/lib/signatureSets/index.d.ts.map +1 -1
- package/lib/signatureSets/index.js +1 -0
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/signatureSets/proposerPreferences.d.ts +4 -0
- package/lib/signatureSets/proposerPreferences.d.ts.map +1 -0
- package/lib/signatureSets/proposerPreferences.js +8 -0
- package/lib/signatureSets/proposerPreferences.js.map +1 -0
- package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
- package/lib/slot/upgradeStateToGloas.js +1 -0
- package/lib/slot/upgradeStateToGloas.js.map +1 -1
- package/lib/stateView/beaconStateView.d.ts +9 -3
- package/lib/stateView/beaconStateView.d.ts.map +1 -1
- package/lib/stateView/beaconStateView.js +32 -8
- package/lib/stateView/beaconStateView.js.map +1 -1
- package/lib/stateView/interface.d.ts +8 -2
- package/lib/stateView/interface.d.ts.map +1 -1
- package/lib/stateView/interface.js.map +1 -1
- package/lib/util/computeAnchorCheckpoint.d.ts +1 -1
- package/lib/util/computeAnchorCheckpoint.d.ts.map +1 -1
- package/lib/util/computeAnchorCheckpoint.js +6 -19
- package/lib/util/computeAnchorCheckpoint.js.map +1 -1
- package/lib/util/gloas.d.ts +0 -1
- package/lib/util/gloas.d.ts.map +1 -1
- package/lib/util/gloas.js +0 -3
- package/lib/util/gloas.js.map +1 -1
- package/package.json +7 -7
- package/src/block/index.ts +12 -4
- package/src/block/processParentExecutionPayload.ts +116 -0
- package/src/block/processWithdrawals.ts +15 -5
- package/src/signatureSets/executionPayloadEnvelope.ts +1 -1
- package/src/signatureSets/index.ts +1 -0
- package/src/signatureSets/proposerPreferences.ts +12 -0
- package/src/slot/upgradeStateToGloas.ts +3 -0
- package/src/stateView/beaconStateView.ts +36 -17
- package/src/stateView/interface.ts +8 -5
- package/src/util/computeAnchorCheckpoint.ts +6 -19
- package/src/util/gloas.ts +0 -4
- package/lib/block/processExecutionPayloadEnvelope.d.ts +0 -9
- package/lib/block/processExecutionPayloadEnvelope.d.ts.map +0 -1
- package/lib/block/processExecutionPayloadEnvelope.js +0 -106
- package/lib/block/processExecutionPayloadEnvelope.js.map +0 -1
- package/src/block/processExecutionPayloadEnvelope.ts +0 -175
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {CompactMultiProof, ProofType, Tree, createProof} from "@chainsafe/persistent-merkle-tree";
|
|
2
2
|
import {BitArray, ByteViews} from "@chainsafe/ssz";
|
|
3
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
|
-
import {ForkName, ForkSeq, SLOTS_PER_HISTORICAL_ROOT
|
|
4
|
+
import {ForkName, ForkSeq, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
6
|
BeaconBlock,
|
|
7
7
|
BeaconState,
|
|
@@ -28,8 +28,7 @@ import {
|
|
|
28
28
|
rewards,
|
|
29
29
|
} from "@lodestar/types";
|
|
30
30
|
import {Checkpoint, Fork} from "@lodestar/types/phase0";
|
|
31
|
-
import {
|
|
32
|
-
import {ProcessExecutionPayloadEnvelopeOpts} from "../block/processExecutionPayloadEnvelope.js";
|
|
31
|
+
import {applyParentExecutionPayload} from "../block/processParentExecutionPayload.js";
|
|
33
32
|
import {VoluntaryExitValidity, getVoluntaryExitValidity} from "../block/processVoluntaryExit.js";
|
|
34
33
|
import {getExpectedWithdrawals} from "../block/processWithdrawals.js";
|
|
35
34
|
import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
|
|
@@ -69,7 +68,7 @@ import {canBuilderCoverBid} from "../util/gloas.js";
|
|
|
69
68
|
import {loadState} from "../util/loadState/loadState.js";
|
|
70
69
|
import {getRandaoMix} from "../util/seed.js";
|
|
71
70
|
import {getLatestWeakSubjectivityCheckpointEpoch} from "../util/weakSubjectivity.js";
|
|
72
|
-
import {IBeaconStateView, IBeaconStateViewLatestFork} from "./interface.js";
|
|
71
|
+
import {IBeaconStateView, IBeaconStateViewGloas, IBeaconStateViewLatestFork, isStatePostGloas} from "./interface.js";
|
|
73
72
|
|
|
74
73
|
export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
75
74
|
private readonly config: BeaconConfig;
|
|
@@ -406,6 +405,23 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
406
405
|
return canBuilderCoverBid(this.cachedState as CachedBeaconStateGloas, builderIndex, bidAmount);
|
|
407
406
|
}
|
|
408
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Return the PTCs for an epoch
|
|
410
|
+
*/
|
|
411
|
+
getEpochPTCs(epoch: Epoch): Uint32Array[] {
|
|
412
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
413
|
+
throw new Error("PTC committees are not supported before Gloas");
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const epochCtx = (this.cachedState as CachedBeaconStateGloas).epochCtx;
|
|
417
|
+
if (epoch === epochCtx.epoch) {
|
|
418
|
+
return epochCtx.payloadTimelinessCommittees;
|
|
419
|
+
}
|
|
420
|
+
if (epoch === epochCtx.nextEpoch) {
|
|
421
|
+
return epochCtx.nextPayloadTimelinessCommittees;
|
|
422
|
+
}
|
|
423
|
+
throw new Error(`PTC committees are not available for epoch=${epoch}`);
|
|
424
|
+
}
|
|
409
425
|
/**
|
|
410
426
|
* Return the index of the validator in the PTC committee for the given slot.
|
|
411
427
|
* return -1 if validator is not in the PTC committee for the given slot.
|
|
@@ -784,19 +800,22 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
|
784
800
|
return new BeaconStateView(newState);
|
|
785
801
|
}
|
|
786
802
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
):
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
throw Error(`processExecutionPayloadEnvelope is only available for gloas+ forks, got fork=${fork}`);
|
|
803
|
+
/**
|
|
804
|
+
* Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/validator.md#executionpayload
|
|
805
|
+
*/
|
|
806
|
+
withParentPayloadApplied(executionRequests: electra.ExecutionRequests): IBeaconStateViewGloas {
|
|
807
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
808
|
+
throw new Error("withParentPayloadApplied is not available before Gloas");
|
|
794
809
|
}
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
);
|
|
800
|
-
|
|
810
|
+
const stateCopy = this.cachedState.clone(true) as CachedBeaconStateGloas;
|
|
811
|
+
|
|
812
|
+
applyParentExecutionPayload(stateCopy, executionRequests);
|
|
813
|
+
|
|
814
|
+
const stateView = new BeaconStateView(stateCopy);
|
|
815
|
+
if (!isStatePostGloas(stateView)) {
|
|
816
|
+
throw new Error("Expected gloas state after clone");
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
return stateView;
|
|
801
820
|
}
|
|
802
821
|
}
|
|
@@ -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";
|
|
@@ -253,11 +252,15 @@ export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
|
|
|
253
252
|
payloadExpectedWithdrawals: capella.Withdrawal[];
|
|
254
253
|
getBuilder(index: BuilderIndex): gloas.Builder;
|
|
255
254
|
canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean;
|
|
255
|
+
getEpochPTCs(epoch: Epoch): Uint32Array[];
|
|
256
256
|
getIndexInPayloadTimelinessCommittee(validatorIndex: ValidatorIndex, slot: Slot): number;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
257
|
+
/**
|
|
258
|
+
* Clone the state and apply parent execution payload effects.
|
|
259
|
+
* Used during block production and prepareNextSlot so that withdrawals and
|
|
260
|
+
* operation selection (e.g. voluntary exits) see the same post-apply state that the block
|
|
261
|
+
* processor will see at import.
|
|
262
|
+
*/
|
|
263
|
+
withParentPayloadApplied(executionRequests: electra.ExecutionRequests): IBeaconStateViewGloas;
|
|
261
264
|
}
|
|
262
265
|
|
|
263
266
|
/**
|
|
@@ -1,34 +1,21 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {
|
|
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
|
-
|
|
8
|
+
_config: ChainForkConfig,
|
|
10
9
|
anchorState: BeaconStateAllForks
|
|
11
10
|
): {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader} {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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,10 +172,6 @@ export function isAttestationSameSlotRootCache(rootCache: RootCache, data: Attes
|
|
|
172
172
|
return isMatchingBlockRoot && isCurrentBlockRoot;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
export function isParentBlockFull(state: CachedBeaconStateGloas): boolean {
|
|
176
|
-
return byteArrayEquals(state.latestExecutionPayloadBid.blockHash, state.latestBlockHash);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
175
|
export function initializePtcWindow(state: CachedBeaconStateFulu): Uint32Array[] {
|
|
180
176
|
const ptcWindow: Uint32Array[] = Array.from({length: SLOTS_PER_EPOCH}, () => new Uint32Array(PTC_SIZE));
|
|
181
177
|
const currentEpoch = state.epochCtx.epoch;
|
|
@@ -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
|
-
}
|