@lodestar/state-transition 1.43.0-dev.e5b13221e5 → 1.43.0-dev.ff409c46ce
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/processConsolidationRequest.d.ts.map +1 -1
- package/lib/block/processConsolidationRequest.js +2 -1
- package/lib/block/processConsolidationRequest.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 +10 -4
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/cache/epochCache.js +3 -3
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/epoch/processPendingDeposits.d.ts.map +1 -1
- package/lib/epoch/processPendingDeposits.js +4 -2
- package/lib/epoch/processPendingDeposits.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/upgradeStateToElectra.d.ts.map +1 -1
- package/lib/slot/upgradeStateToElectra.js +2 -2
- package/lib/slot/upgradeStateToElectra.js.map +1 -1
- 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/epoch.d.ts.map +1 -1
- package/lib/util/epoch.js +6 -4
- package/lib/util/epoch.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 -4
- package/lib/util/gloas.js.map +1 -1
- package/lib/util/loadState/loadState.js +4 -4
- package/lib/util/loadState/loadState.js.map +1 -1
- package/lib/util/validator.d.ts +14 -2
- package/lib/util/validator.d.ts.map +1 -1
- package/lib/util/validator.js +24 -2
- package/lib/util/validator.js.map +1 -1
- package/package.json +7 -7
- package/src/block/index.ts +12 -4
- package/src/block/processConsolidationRequest.ts +2 -1
- package/src/block/processParentExecutionPayload.ts +116 -0
- package/src/block/processWithdrawals.ts +12 -4
- package/src/cache/epochCache.ts +3 -3
- package/src/epoch/processPendingDeposits.ts +5 -2
- package/src/signatureSets/index.ts +1 -0
- package/src/signatureSets/proposerPreferences.ts +12 -0
- package/src/slot/upgradeStateToElectra.ts +4 -2
- 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/epoch.ts +13 -4
- package/src/util/gloas.ts +0 -5
- package/src/util/loadState/loadState.ts +4 -4
- package/src/util/validator.ts +42 -2
- package/lib/block/processExecutionPayloadEnvelope.d.ts +0 -9
- package/lib/block/processExecutionPayloadEnvelope.d.ts.map +0 -1
- package/lib/block/processExecutionPayloadEnvelope.js +0 -103
- package/lib/block/processExecutionPayloadEnvelope.js.map +0 -1
- package/src/block/processExecutionPayloadEnvelope.ts +0 -169
|
@@ -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/epoch.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
EPOCHS_PER_SYNC_COMMITTEE_PERIOD,
|
|
3
|
+
ForkSeq,
|
|
4
|
+
GENESIS_EPOCH,
|
|
5
|
+
MAX_SEED_LOOKAHEAD,
|
|
6
|
+
SLOTS_PER_EPOCH,
|
|
7
|
+
} from "@lodestar/params";
|
|
2
8
|
import {BeaconState, Epoch, Gwei, Slot, SyncPeriod} from "@lodestar/types";
|
|
3
9
|
import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
4
|
-
import {getActivationExitChurnLimit, getConsolidationChurnLimit} from "./validator.js";
|
|
10
|
+
import {getActivationExitChurnLimit, getConsolidationChurnLimit, getExitChurnLimit} from "./validator.js";
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
13
|
* Return the epoch number at the given slot.
|
|
@@ -45,8 +51,10 @@ export function computeExitEpochAndUpdateChurn(
|
|
|
45
51
|
state: CachedBeaconStateElectra | CachedBeaconStateGloas,
|
|
46
52
|
exitBalance: Gwei
|
|
47
53
|
): number {
|
|
54
|
+
const fork = state.config.getForkSeq(state.slot);
|
|
48
55
|
let earliestExitEpoch = Math.max(state.earliestExitEpoch, computeActivationExitEpoch(state.epochCtx.epoch));
|
|
49
|
-
const perEpochChurn =
|
|
56
|
+
const perEpochChurn =
|
|
57
|
+
fork >= ForkSeq.gloas ? getExitChurnLimit(state.epochCtx) : getActivationExitChurnLimit(state.epochCtx);
|
|
50
58
|
|
|
51
59
|
// New epoch for exits.
|
|
52
60
|
let exitBalanceToConsume =
|
|
@@ -71,11 +79,12 @@ export function computeConsolidationEpochAndUpdateChurn(
|
|
|
71
79
|
state: CachedBeaconStateElectra | CachedBeaconStateGloas,
|
|
72
80
|
consolidationBalance: Gwei
|
|
73
81
|
): number {
|
|
82
|
+
const fork = state.config.getForkSeq(state.slot);
|
|
74
83
|
let earliestConsolidationEpoch = Math.max(
|
|
75
84
|
state.earliestConsolidationEpoch,
|
|
76
85
|
computeActivationExitEpoch(state.epochCtx.epoch)
|
|
77
86
|
);
|
|
78
|
-
const perEpochConsolidationChurn = getConsolidationChurnLimit(state.epochCtx);
|
|
87
|
+
const perEpochConsolidationChurn = getConsolidationChurnLimit(fork, state.epochCtx);
|
|
79
88
|
|
|
80
89
|
// New epoch for consolidations
|
|
81
90
|
let consolidationBalanceToConsume =
|
package/src/util/gloas.ts
CHANGED
|
@@ -172,11 +172,6 @@ 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
|
|
176
|
-
export function isParentBlockFull(state: CachedBeaconStateGloas): boolean {
|
|
177
|
-
return byteArrayEquals(state.latestExecutionPayloadBid.blockHash, state.latestBlockHash);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
175
|
export function initializePtcWindow(state: CachedBeaconStateFulu): Uint32Array[] {
|
|
181
176
|
const ptcWindow: Uint32Array[] = Array.from({length: SLOTS_PER_EPOCH}, () => new Uint32Array(PTC_SIZE));
|
|
182
177
|
const currentEpoch = state.epochCtx.epoch;
|
|
@@ -110,8 +110,8 @@ function loadInactivityScores(
|
|
|
110
110
|
seedState: BeaconStateAltair,
|
|
111
111
|
inactivityScoresBytes: Uint8Array
|
|
112
112
|
): void {
|
|
113
|
-
//
|
|
114
|
-
migratedState.inactivityScores = seedState.inactivityScores.clone();
|
|
113
|
+
// true = do not transfer cache
|
|
114
|
+
migratedState.inactivityScores = seedState.inactivityScores.clone(true);
|
|
115
115
|
const oldValidator = migratedState.inactivityScores.length;
|
|
116
116
|
// UintNum64 = 8 bytes
|
|
117
117
|
const newValidator = inactivityScoresBytes.length / 8;
|
|
@@ -187,8 +187,8 @@ function loadValidators(
|
|
|
187
187
|
const newValidatorCount = Math.floor(newValidatorsBytes.length / VALIDATOR_BYTES_SIZE);
|
|
188
188
|
const isMoreValidator = newValidatorCount >= seedValidatorCount;
|
|
189
189
|
const minValidatorCount = Math.min(seedValidatorCount, newValidatorCount);
|
|
190
|
-
//
|
|
191
|
-
migratedState.validators = seedState.validators.clone();
|
|
190
|
+
// true = do not transfer cache
|
|
191
|
+
migratedState.validators = seedState.validators.clone(true);
|
|
192
192
|
// 80% of validators serialization time comes from memory allocation
|
|
193
193
|
// seedStateValidatorsBytes is an optimization at beacon-node side to avoid memory allocation here
|
|
194
194
|
const seedValidatorsBytes = seedStateValidatorsBytes ?? seedState.validators.serialize();
|
package/src/util/validator.ts
CHANGED
|
@@ -44,7 +44,12 @@ export function getActiveValidatorIndices(state: BeaconStateAllForks, epoch: Epo
|
|
|
44
44
|
return new Uint32Array(indices);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
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
|
-
|
|
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,CAoDxB"}
|
|
@@ -1,103 +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 } = opts ?? {};
|
|
16
|
-
const envelope = signedEnvelope.message;
|
|
17
|
-
const payload = envelope.payload;
|
|
18
|
-
const fork = state.config.getForkSeq(payload.slotNumber);
|
|
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
|
-
return postState;
|
|
52
|
-
}
|
|
53
|
-
function validateExecutionPayloadEnvelope(state, envelope) {
|
|
54
|
-
const payload = envelope.payload;
|
|
55
|
-
// Cache latest block header state root
|
|
56
|
-
if (byteArrayEquals(state.latestBlockHeader.stateRoot, ssz.Root.defaultValue())) {
|
|
57
|
-
const previousStateRoot = state.hashTreeRoot();
|
|
58
|
-
state.latestBlockHeader.stateRoot = previousStateRoot;
|
|
59
|
-
}
|
|
60
|
-
// Verify consistency with the beacon block
|
|
61
|
-
if (!byteArrayEquals(envelope.beaconBlockRoot, state.latestBlockHeader.hashTreeRoot())) {
|
|
62
|
-
throw new Error(`Envelope's block is not the latest block header envelope=${toRootHex(envelope.beaconBlockRoot)} latestBlockHeader=${toRootHex(state.latestBlockHeader.hashTreeRoot())}`);
|
|
63
|
-
}
|
|
64
|
-
if (payload.slotNumber !== state.slot) {
|
|
65
|
-
throw new Error(`Slot mismatch between payload and state payload=${payload.slotNumber} state=${state.slot}`);
|
|
66
|
-
}
|
|
67
|
-
// Verify consistency with the committed bid
|
|
68
|
-
const committedBid = state.latestExecutionPayloadBid;
|
|
69
|
-
if (envelope.builderIndex !== committedBid.builderIndex) {
|
|
70
|
-
throw new Error(`Builder index mismatch between envelope and committed bid envelope=${envelope.builderIndex} committedBid=${committedBid.builderIndex}`);
|
|
71
|
-
}
|
|
72
|
-
if (!byteArrayEquals(committedBid.prevRandao, payload.prevRandao)) {
|
|
73
|
-
throw new Error(`Prev randao mismatch between committed bid and payload committedBid=${toHex(committedBid.prevRandao)} payload=${toHex(payload.prevRandao)}`);
|
|
74
|
-
}
|
|
75
|
-
// Verify consistency with expected withdrawals
|
|
76
|
-
const payloadWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
|
|
77
|
-
const expectedWithdrawalsRoot = state.payloadExpectedWithdrawals.hashTreeRoot();
|
|
78
|
-
if (!byteArrayEquals(payloadWithdrawalsRoot, expectedWithdrawalsRoot)) {
|
|
79
|
-
throw new Error(`Withdrawals mismatch between payload and expected withdrawals payload=${toRootHex(payloadWithdrawalsRoot)} expected=${toRootHex(expectedWithdrawalsRoot)}`);
|
|
80
|
-
}
|
|
81
|
-
// Verify the gas_limit
|
|
82
|
-
if (Number(committedBid.gasLimit) !== payload.gasLimit) {
|
|
83
|
-
throw new Error(`Gas limit mismatch between envelope's payload and committed bid envelope=${payload.gasLimit} committedBid=${Number(committedBid.gasLimit)}`);
|
|
84
|
-
}
|
|
85
|
-
// Verify the block hash
|
|
86
|
-
if (!byteArrayEquals(committedBid.blockHash, payload.blockHash)) {
|
|
87
|
-
throw new Error(`Block hash mismatch between envelope's payload and committed bid envelope=${toRootHex(payload.blockHash)} committedBid=${toRootHex(committedBid.blockHash)}`);
|
|
88
|
-
}
|
|
89
|
-
// Verify consistency of the parent hash with respect to the previous execution payload
|
|
90
|
-
if (!byteArrayEquals(payload.parentHash, state.latestBlockHash)) {
|
|
91
|
-
throw new Error(`Parent hash mismatch between envelope's payload and state envelope=${toRootHex(payload.parentHash)} state=${toRootHex(state.latestBlockHash)}`);
|
|
92
|
-
}
|
|
93
|
-
// Verify timestamp
|
|
94
|
-
if (payload.timestamp !== computeTimeAtSlot(state.config, state.slot, state.genesisTime)) {
|
|
95
|
-
throw new Error(`Timestamp mismatch between envelope's payload and state envelope=${payload.timestamp} state=${computeTimeAtSlot(state.config, state.slot, state.genesisTime)}`);
|
|
96
|
-
}
|
|
97
|
-
// Skipped: Verify the execution payload is valid
|
|
98
|
-
}
|
|
99
|
-
function verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope) {
|
|
100
|
-
const signatureSet = getExecutionPayloadEnvelopeSignatureSet(state.config, state.epochCtx.pubkeyCache, new BeaconStateView(state), signedEnvelope, state.latestBlockHeader.proposerIndex);
|
|
101
|
-
return verifySignatureSet(signatureSet);
|
|
102
|
-
}
|
|
103
|
-
//# 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,169 +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} = opts ?? {};
|
|
28
|
-
const envelope = signedEnvelope.message;
|
|
29
|
-
const payload = envelope.payload;
|
|
30
|
-
const fork = state.config.getForkSeq(payload.slotNumber);
|
|
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
|
-
return postState;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function validateExecutionPayloadEnvelope(
|
|
81
|
-
state: CachedBeaconStateGloas,
|
|
82
|
-
envelope: gloas.ExecutionPayloadEnvelope
|
|
83
|
-
): void {
|
|
84
|
-
const payload = envelope.payload;
|
|
85
|
-
|
|
86
|
-
// Cache latest block header state root
|
|
87
|
-
if (byteArrayEquals(state.latestBlockHeader.stateRoot, ssz.Root.defaultValue())) {
|
|
88
|
-
const previousStateRoot = state.hashTreeRoot();
|
|
89
|
-
state.latestBlockHeader.stateRoot = previousStateRoot;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Verify consistency with the beacon block
|
|
93
|
-
if (!byteArrayEquals(envelope.beaconBlockRoot, state.latestBlockHeader.hashTreeRoot())) {
|
|
94
|
-
throw new Error(
|
|
95
|
-
`Envelope's block is not the latest block header envelope=${toRootHex(envelope.beaconBlockRoot)} latestBlockHeader=${toRootHex(state.latestBlockHeader.hashTreeRoot())}`
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (payload.slotNumber !== state.slot) {
|
|
100
|
-
throw new Error(`Slot mismatch between payload and state payload=${payload.slotNumber} state=${state.slot}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Verify consistency with the committed bid
|
|
104
|
-
const committedBid = state.latestExecutionPayloadBid;
|
|
105
|
-
if (envelope.builderIndex !== committedBid.builderIndex) {
|
|
106
|
-
throw new Error(
|
|
107
|
-
`Builder index mismatch between envelope and committed bid envelope=${envelope.builderIndex} committedBid=${committedBid.builderIndex}`
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (!byteArrayEquals(committedBid.prevRandao, payload.prevRandao)) {
|
|
112
|
-
throw new Error(
|
|
113
|
-
`Prev randao mismatch between committed bid and payload committedBid=${toHex(committedBid.prevRandao)} payload=${toHex(payload.prevRandao)}`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Verify consistency with expected withdrawals
|
|
118
|
-
const payloadWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
|
|
119
|
-
const expectedWithdrawalsRoot = state.payloadExpectedWithdrawals.hashTreeRoot();
|
|
120
|
-
if (!byteArrayEquals(payloadWithdrawalsRoot, expectedWithdrawalsRoot)) {
|
|
121
|
-
throw new Error(
|
|
122
|
-
`Withdrawals mismatch between payload and expected withdrawals payload=${toRootHex(payloadWithdrawalsRoot)} expected=${toRootHex(expectedWithdrawalsRoot)}`
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Verify the gas_limit
|
|
127
|
-
if (Number(committedBid.gasLimit) !== payload.gasLimit) {
|
|
128
|
-
throw new Error(
|
|
129
|
-
`Gas limit mismatch between envelope's payload and committed bid envelope=${payload.gasLimit} committedBid=${Number(committedBid.gasLimit)}`
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Verify the block hash
|
|
134
|
-
if (!byteArrayEquals(committedBid.blockHash, payload.blockHash)) {
|
|
135
|
-
throw new Error(
|
|
136
|
-
`Block hash mismatch between envelope's payload and committed bid envelope=${toRootHex(payload.blockHash)} committedBid=${toRootHex(committedBid.blockHash)}`
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Verify consistency of the parent hash with respect to the previous execution payload
|
|
141
|
-
if (!byteArrayEquals(payload.parentHash, state.latestBlockHash)) {
|
|
142
|
-
throw new Error(
|
|
143
|
-
`Parent hash mismatch between envelope's payload and state envelope=${toRootHex(payload.parentHash)} state=${toRootHex(state.latestBlockHash)}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Verify timestamp
|
|
148
|
-
if (payload.timestamp !== computeTimeAtSlot(state.config, state.slot, state.genesisTime)) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`Timestamp mismatch between envelope's payload and state envelope=${payload.timestamp} state=${computeTimeAtSlot(state.config, state.slot, state.genesisTime)}`
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Skipped: Verify the execution payload is valid
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function verifyExecutionPayloadEnvelopeSignature(
|
|
158
|
-
state: CachedBeaconStateGloas,
|
|
159
|
-
signedEnvelope: gloas.SignedExecutionPayloadEnvelope
|
|
160
|
-
): boolean {
|
|
161
|
-
const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
|
|
162
|
-
state.config,
|
|
163
|
-
state.epochCtx.pubkeyCache,
|
|
164
|
-
new BeaconStateView(state),
|
|
165
|
-
signedEnvelope,
|
|
166
|
-
state.latestBlockHeader.proposerIndex
|
|
167
|
-
);
|
|
168
|
-
return verifySignatureSet(signatureSet);
|
|
169
|
-
}
|