Skip to content

Commit 551b8b0

Browse files
nflaigensi321
andauthored
feat: upgrade to v1.7.0-alpha.11 spec (#9541)
implements the following spec changes required to pass `v1.7.0-alpha.11` spec tests - ethereum/consensus-specs#5359 - ethereum/consensus-specs#5377 - ethereum/consensus-specs#5373 - ethereum/consensus-specs#5365 - ethereum/consensus-specs#5364 - ethereum/consensus-specs#5368 --------- Co-authored-by: NC <17676176+ensi321@users.noreply.github.com>
1 parent 848b014 commit 551b8b0

45 files changed

Lines changed: 1451 additions & 545 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/beacon-node/src/api/impl/config/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
BASE_REWARDS_PER_EPOCH,
66
BLOB_TX_TYPE,
77
BLS_WITHDRAWAL_PREFIX,
8+
BUILDER_DEPOSIT_REQUEST_TYPE,
9+
BUILDER_EXIT_REQUEST_TYPE,
810
BUILDER_INDEX_FLAG,
911
BUILDER_INDEX_SELF_BUILD,
1012
BUILDER_PAYMENT_THRESHOLD_DENOMINATOR,
@@ -21,6 +23,7 @@ import {
2123
DOMAIN_BEACON_BUILDER,
2224
DOMAIN_BEACON_PROPOSER,
2325
DOMAIN_BLS_TO_EXECUTION_CHANGE,
26+
DOMAIN_BUILDER_DEPOSIT,
2427
DOMAIN_CONTRIBUTION_AND_PROOF,
2528
DOMAIN_DEPOSIT,
2629
DOMAIN_PROPOSER_PREFERENCES,
@@ -38,6 +41,7 @@ import {
3841
JUSTIFICATION_BITS_LENGTH,
3942
MAX_CONCURRENT_REQUESTS,
4043
NODE_ID_BITS,
44+
PAYLOAD_BUILDER_VERSION,
4145
PROPOSER_WEIGHT,
4246
SYNC_COMMITTEE_SUBNET_COUNT,
4347
SYNC_REWARD_WEIGHT,
@@ -140,6 +144,10 @@ export const specConstants = {
140144
BUILDER_INDEX_SELF_BUILD,
141145
BUILDER_PAYMENT_THRESHOLD_NUMERATOR,
142146
BUILDER_PAYMENT_THRESHOLD_DENOMINATOR,
147+
PAYLOAD_BUILDER_VERSION,
148+
DOMAIN_BUILDER_DEPOSIT,
149+
BUILDER_DEPOSIT_REQUEST_TYPE: toHexByte(BUILDER_DEPOSIT_REQUEST_TYPE),
150+
BUILDER_EXIT_REQUEST_TYPE: toHexByte(BUILDER_EXIT_REQUEST_TYPE),
143151
};
144152

145153
/** Convert single-byte numbers to hex strings for API spec compliance */

packages/beacon-node/src/chain/blocks/verifyExecutionPayloadEnvelope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function verifyExecutionPayloadEnvelope(
7272
// Verify execution_requests_root matches bid commitment.
7373
// Can be skipped if already verified during gossip validation.
7474
if (verifyExecutionRequestsRoot) {
75-
const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
75+
const requestsRoot = ssz.gloas.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
7676
if (!byteArrayEquals(requestsRoot, bid.executionRequestsRoot)) {
7777
throw new Error(
7878
`Execution requests root mismatch envelope=${toRootHex(requestsRoot)} bid=${toRootHex(bid.executionRequestsRoot)}`

packages/beacon-node/src/chain/chain.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import {
4040
ValidatorIndex,
4141
Wei,
4242
deneb,
43-
electra,
4443
gloas,
4544
isBlindedBeaconBlock,
4645
phase0,
@@ -925,10 +924,10 @@ export class BeaconChain implements IBeaconChain {
925924
async getParentExecutionRequests(
926925
parentBlockSlot: Slot,
927926
parentBlockRootHex: RootHex
928-
): Promise<electra.ExecutionRequests> {
927+
): Promise<gloas.ExecutionRequests> {
929928
// at the fork boundary, parent is pre-gloas
930929
if (!isForkPostGloas(this.config.getForkName(parentBlockSlot))) {
931-
return ssz.electra.ExecutionRequests.defaultValue();
930+
return ssz.gloas.ExecutionRequests.defaultValue();
932931
}
933932
const envelope = await this.getExecutionPayloadEnvelope(parentBlockSlot, parentBlockRootHex);
934933
if (envelope === null) {

packages/beacon-node/src/chain/errors/executionPayloadBid.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {GossipActionError} from "./gossipValidation.js";
33

44
export enum ExecutionPayloadBidErrorCode {
55
BUILDER_NOT_ELIGIBLE = "EXECUTION_PAYLOAD_BID_ERROR_BUILDER_NOT_ELIGIBLE",
6+
INVALID_BUILDER_VERSION = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_BUILDER_VERSION",
67
NON_ZERO_EXECUTION_PAYMENT = "EXECUTION_PAYLOAD_BID_ERROR_NON_ZERO_EXECUTION_PAYMENT",
78
BID_ALREADY_KNOWN = "EXECUTION_PAYLOAD_BID_ERROR_BID_ALREADY_KNOWN",
89
BID_TOO_LOW = "EXECUTION_PAYLOAD_BID_ERROR_BID_TOO_LOW",
@@ -21,6 +22,12 @@ export enum ExecutionPayloadBidErrorCode {
2122

2223
export type ExecutionPayloadBidErrorType =
2324
| {code: ExecutionPayloadBidErrorCode.BUILDER_NOT_ELIGIBLE; builderIndex: BuilderIndex}
25+
| {
26+
code: ExecutionPayloadBidErrorCode.INVALID_BUILDER_VERSION;
27+
builderIndex: BuilderIndex;
28+
version: number;
29+
expectedVersion: number;
30+
}
2431
| {
2532
code: ExecutionPayloadBidErrorCode.NON_ZERO_EXECUTION_PAYMENT;
2633
builderIndex: BuilderIndex;

packages/beacon-node/src/chain/interface.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
altair,
1919
capella,
2020
deneb,
21-
electra,
2221
gloas,
2322
phase0,
2423
rewards,
@@ -236,7 +235,7 @@ export interface IBeaconChain {
236235
blockSlot: Slot,
237236
blockRootHex: string
238237
): Promise<gloas.SignedExecutionPayloadEnvelope | null>;
239-
getParentExecutionRequests(parentBlockSlot: Slot, parentBlockRootHex: RootHex): Promise<electra.ExecutionRequests>;
238+
getParentExecutionRequests(parentBlockSlot: Slot, parentBlockRootHex: RootHex): Promise<gloas.ExecutionRequests>;
240239

241240
produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody>;
242241
produceBlock(blockAttributes: BlockAttributes & {commonBlockBodyPromise: Promise<CommonBlockBody>}): Promise<{

packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export type ProduceFullGloas = {
108108
type: BlockType.Full;
109109
fork: ForkPostGloas;
110110
executionPayload: ExecutionPayload<ForkPostGloas>;
111-
executionRequests: electra.ExecutionRequests;
111+
executionRequests: gloas.ExecutionRequests;
112112
blobsBundle: BlobsBundle<ForkPostGloas>;
113113
cells: fulu.Cell[][];
114114
parentBlockRoot: Root;
@@ -228,7 +228,7 @@ export async function produceBlockBody<T extends BlockType>(
228228
);
229229
const parentExecutionRequests = isExtendingPayload
230230
? await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot)
231-
: ssz.electra.ExecutionRequests.defaultValue();
231+
: ssz.gloas.ExecutionRequests.defaultValue();
232232
executionPayloadValue = BigInt(builderBid.message.value) * GWEI_TO_WEI;
233233

234234
const commonBlockBody = await commonBlockBodyPromise;
@@ -272,7 +272,7 @@ export async function produceBlockBody<T extends BlockType>(
272272

273273
// Get execution payload from EL
274274
let parentBlockHash: Bytes32;
275-
let parentExecutionRequests: electra.ExecutionRequests;
275+
let parentExecutionRequests: gloas.ExecutionRequests;
276276
// Apply parent payload once here as it's reused by EL prep and voluntary exit filtering below
277277
let stateAfterParentPayload: IBeaconStateViewBellatrix = currentState;
278278
// Spec: should_build_on_full(store, head). `parentBlock` is the proposer's head
@@ -285,7 +285,7 @@ export async function produceBlockBody<T extends BlockType>(
285285
stateAfterParentPayload = currentState.withParentPayloadApplied(parentExecutionRequests);
286286
} else {
287287
parentBlockHash = currentState.latestExecutionPayloadBid.parentBlockHash;
288-
parentExecutionRequests = ssz.electra.ExecutionRequests.defaultValue();
288+
parentExecutionRequests = ssz.gloas.ExecutionRequests.defaultValue();
289289
}
290290
const prepareRes = await prepareExecutionPayload(
291291
this,
@@ -350,7 +350,7 @@ export async function produceBlockBody<T extends BlockType>(
350350
value: 0,
351351
executionPayment: 0,
352352
blobKzgCommitments: blobsBundle.commitments,
353-
executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
353+
executionRequestsRoot: ssz.gloas.ExecutionRequests.hashTreeRoot(executionRequests as gloas.ExecutionRequests),
354354
};
355355
const signedBid: gloas.SignedExecutionPayloadBid = {
356356
message: bid,
@@ -375,7 +375,7 @@ export async function produceBlockBody<T extends BlockType>(
375375
// Store execution payload data required to construct execution payload envelope later
376376
const gloasResult = produceResult as ProduceFullGloas;
377377
gloasResult.executionPayload = executionPayload as ExecutionPayload<ForkPostGloas>;
378-
gloasResult.executionRequests = executionRequests;
378+
gloasResult.executionRequests = executionRequests as gloas.ExecutionRequests;
379379
gloasResult.blobsBundle = blobsBundle;
380380
gloasResult.cells = cells;
381381
gloasResult.parentBlockRoot = fromHex(parentBlock.blockRoot);

packages/beacon-node/src/chain/validation/executionPayloadBid.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {PublicKey} from "@chainsafe/blst";
2+
import {PAYLOAD_BUILDER_VERSION} from "@lodestar/params";
23
import {
34
computeEpochAtSlot,
45
createSingleSignatureSetFromComponents,
@@ -139,6 +140,17 @@ async function validateExecutionPayloadBid(
139140
});
140141
}
141142

143+
// [REJECT] The builder version is `PAYLOAD_BUILDER_VERSION` -- i.e.
144+
// `state.builders[bid.builder_index].version == PAYLOAD_BUILDER_VERSION`.
145+
if (builder.version !== PAYLOAD_BUILDER_VERSION) {
146+
throw new ExecutionPayloadBidError(GossipAction.REJECT, {
147+
code: ExecutionPayloadBidErrorCode.INVALID_BUILDER_VERSION,
148+
builderIndex: bid.builderIndex,
149+
version: builder.version,
150+
expectedVersion: PAYLOAD_BUILDER_VERSION,
151+
});
152+
}
153+
142154
// [REJECT] `bid.execution_payment` is zero.
143155
if (bid.executionPayment !== 0) {
144156
throw new ExecutionPayloadBidError(GossipAction.REJECT, {

packages/beacon-node/src/chain/validation/executionPayloadEnvelope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ async function validateExecutionPayloadEnvelope(
106106
}
107107

108108
// [REJECT] `hash_tree_root(envelope.execution_requests) == bid.execution_requests_root`
109-
const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
109+
const requestsRoot = ssz.gloas.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
110110
if (!byteArrayEquals(requestsRoot, payloadInput.getBid().executionRequestsRoot)) {
111111
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
112112
code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_ROOT_MISMATCH,

packages/beacon-node/src/execution/engine/http.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
244244
if (executionRequests === undefined) {
245245
throw Error(`executionRequests required in notifyNewPayload for fork=${fork}`);
246246
}
247-
const serializedExecutionRequests = serializeExecutionRequests(executionRequests);
247+
const serializedExecutionRequests = serializeExecutionRequests(fork, executionRequests);
248248
engineRequest = {
249249
method: ForkSeq[fork] >= ForkSeq.gloas ? "engine_newPayloadV5" : "engine_newPayloadV4",
250250
params: [

packages/beacon-node/src/execution/engine/interface.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {routes} from "@lodestar/api";
22
import {
3+
BUILDER_DEPOSIT_REQUEST_TYPE,
4+
BUILDER_EXIT_REQUEST_TYPE,
35
CONSOLIDATION_REQUEST_TYPE,
46
DEPOSIT_REQUEST_TYPE,
57
ForkName,
@@ -51,10 +53,18 @@ export enum ExecutionEngineState {
5153
export type ExecutionRequestType =
5254
| typeof DEPOSIT_REQUEST_TYPE
5355
| typeof WITHDRAWAL_REQUEST_TYPE
54-
| typeof CONSOLIDATION_REQUEST_TYPE;
56+
| typeof CONSOLIDATION_REQUEST_TYPE
57+
| typeof BUILDER_DEPOSIT_REQUEST_TYPE
58+
| typeof BUILDER_EXIT_REQUEST_TYPE;
5559

5660
export function isExecutionRequestType(type: number): type is ExecutionRequestType {
57-
return type === DEPOSIT_REQUEST_TYPE || type === WITHDRAWAL_REQUEST_TYPE || type === CONSOLIDATION_REQUEST_TYPE;
61+
return (
62+
type === DEPOSIT_REQUEST_TYPE ||
63+
type === WITHDRAWAL_REQUEST_TYPE ||
64+
type === CONSOLIDATION_REQUEST_TYPE ||
65+
type === BUILDER_DEPOSIT_REQUEST_TYPE ||
66+
type === BUILDER_EXIT_REQUEST_TYPE
67+
);
5868
}
5969

6070
export type ExecutePayloadResponse =

0 commit comments

Comments
 (0)