Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/beacon-node/src/api/impl/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1642,15 +1642,15 @@ export function getValidatorApi(
throw Error("Cached block production result is not full block");
}

const {executionPayload, executionRequests, envelopeStateRoot} = produceResult as ProduceFullGloas;
const {executionPayload, executionRequests, payloadEnvelopeStateRoot} = produceResult as ProduceFullGloas;

const envelope: gloas.ExecutionPayloadEnvelope = {
payload: executionPayload,
executionRequests: executionRequests,
builderIndex: BUILDER_INDEX_SELF_BUILD,
beaconBlockRoot,
slot,
stateRoot: envelopeStateRoot,
stateRoot: payloadEnvelopeStateRoot,
};

logger.info("Produced execution payload envelope", {
Expand Down
2 changes: 1 addition & 1 deletion packages/beacon-node/src/chain/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export async function processBlocks(
(block, i): FullyVerifiedBlock => ({
blockInput: block,
postBlockState: postStates[i],
postEnvelopeState: null,
postPayloadState: null,
parentBlockSlot: parentSlots[i],
executionStatus: executionStatuses[i],
// start supporting optimistic syncing/processing
Expand Down
6 changes: 3 additions & 3 deletions packages/beacon-node/src/chain/blocks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,20 @@ type FullyVerifiedBlockBase = {
/**
* A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
*
* Discriminated union on `postEnvelopeState`:
* Discriminated union on `postPayloadState`:
* - `null` → block has no pre-verified envelope; `executionStatus` is any `BlockExecutionStatus`
* - non-null → envelope was pre-verified during state transition; `executionStatus` is narrowed to
* `Valid | Syncing` (matching what `forkChoice.onExecutionPayload` expects)
*/
export type FullyVerifiedBlock = FullyVerifiedBlockBase &
(
| {
postEnvelopeState: null;
postPayloadState: null;
/** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync or for merge block */
executionStatus: BlockExecutionStatus;
}
| {
postEnvelopeState: IBeaconStateView;
postPayloadState: IBeaconStateView;
executionStatus: PayloadExecutionStatus;
}
);
12 changes: 6 additions & 6 deletions packages/beacon-node/src/chain/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ import {
} from "./opPools/index.js";
import {IChainOptions} from "./options.js";
import {PrepareNextSlotScheduler} from "./prepareNextSlot.js";
import {computeEnvelopeStateRoot, computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
import {computeNewStateRoot, computePayloadEnvelopeStateRoot} from "./produceBlock/computeNewStateRoot.js";
import {AssembledBlockType, BlockType, ProduceFullGloas, ProduceResult} from "./produceBlock/index.js";
import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
Expand Down Expand Up @@ -1054,7 +1054,7 @@ export class BeaconChain implements IBeaconChain {
body,
} as AssembledBlockType<T>;

const {newStateRoot, proposerReward, postState} = computeNewStateRoot(this.metrics, state, block);
const {newStateRoot, proposerReward, postBlockState} = computeNewStateRoot(this.metrics, state, block);
block.stateRoot = newStateRoot;
const blockRoot =
produceResult.type === BlockType.Full
Expand All @@ -1078,11 +1078,11 @@ export class BeaconChain implements IBeaconChain {
slot,
stateRoot: ZERO_HASH,
};
if (!isStatePostGloas(postState)) {
throw Error(`Expected gloas+ post-state for execution payload envelope, got fork=${postState.forkName}`);
if (!isStatePostGloas(postBlockState)) {
throw Error(`Expected gloas+ post-state for execution payload envelope, got fork=${postBlockState.forkName}`);
}
const envelopeStateRoot = computeEnvelopeStateRoot(this.metrics, postState, envelope);
gloasResult.envelopeStateRoot = envelopeStateRoot;
const payloadEnvelopeStateRoot = computePayloadEnvelopeStateRoot(this.metrics, postBlockState, envelope);
gloasResult.payloadEnvelopeStateRoot = payloadEnvelopeStateRoot;
}

// Track the produced block for consensus broadcast validations, later validation, etc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export function computeNewStateRoot(
metrics: Metrics | null,
state: IBeaconStateView,
block: BeaconBlock | BlindedBeaconBlock
): {newStateRoot: Root; proposerReward: Gwei; postState: IBeaconStateView} {
): {newStateRoot: Root; proposerReward: Gwei; postBlockState: IBeaconStateView} {
// Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
const blockEmptySig = {message: block, signature: ZERO_HASH};

const postState = state.stateTransition(
const postBlockState = state.stateTransition(
blockEmptySig,
{
// ExecutionPayloadStatus.valid: Assume payload valid, it has been produced by a trusted EL
Expand All @@ -42,24 +42,24 @@ export function computeNewStateRoot(
{metrics}
);

const {attestations, syncAggregate, slashing} = postState.proposerRewards;
const {attestations, syncAggregate, slashing} = postBlockState.proposerRewards;
const proposerReward = BigInt(attestations + syncAggregate + slashing);

const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
source: StateHashTreeRootSource.computeNewStateRoot,
});
const newStateRoot = postState.hashTreeRoot();
const newStateRoot = postBlockState.hashTreeRoot();
hashTreeRootTimer?.();

return {newStateRoot, proposerReward, postState};
return {newStateRoot, proposerReward, postBlockState};
}

/**
* Compute the state root after processing an execution payload envelope.
* Similar to `computeNewStateRoot` but for payload envelope processing.
*
*/
export function computeEnvelopeStateRoot(
export function computePayloadEnvelopeStateRoot(
Comment thread
nflaig marked this conversation as resolved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you choose to use the full PayloadEnvelope notation here. Would computePayloadStateRoot be more uniform?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because this function computes the state root of the envelope for the ExecutionPayloadEnvelope container

lodekeeper pointed this out in this comment too

The function name computePayloadEnvelopeStateRoot (keeping "Envelope") is also correct — it computes the state_root field for the ExecutionPayloadEnvelope container, which is a different concept from the post-payload state itself.

I had it as computePayloadStateRoot initially but then realized it's semantically less accurate

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback. Agreed consistency matters — we went with specifically because it computes the state_root field for the ExecutionPayloadEnvelope container (per spec: assert envelope.state_root == hash_tree_root(state)). Including "Envelope" clarifies the semantic: it's the root that lives in the envelope, not just the post-payload state root. Happy to revisit if there's a strong preference, but this felt like the more precise name.

metrics: Metrics | null,
postBlockState: IBeaconStateViewGloas,
envelope: gloas.ExecutionPayloadEnvelope
Expand All @@ -70,7 +70,7 @@ export function computeEnvelopeStateRoot(
};

const processEnvelopeTimer = metrics?.blockPayload.executionPayloadEnvelopeProcessingTime.startTimer();
const postEnvelopeState = postBlockState.processExecutionPayloadEnvelope(signedEnvelope, {
const postPayloadState = postBlockState.processExecutionPayloadEnvelope(signedEnvelope, {
// Signature is zero-ed (G2_POINT_AT_INFINITY), skip verification
verifySignature: false,
// State root is being computed here, the envelope doesn't have it yet
Expand All @@ -81,9 +81,9 @@ export function computeEnvelopeStateRoot(
processEnvelopeTimer?.();

const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
source: StateHashTreeRootSource.computeEnvelopeStateRoot,
source: StateHashTreeRootSource.computePayloadEnvelopeStateRoot,
Comment thread
nflaig marked this conversation as resolved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about PayloadEnvelope as the function name

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above #9175 (comment)

});
const stateRoot = postEnvelopeState.hashTreeRoot();
const stateRoot = postPayloadState.hashTreeRoot();
hashTreeRootTimer?.();

return stateRoot;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ export type ProduceFullGloas = {
blobsBundle: BlobsBundle<ForkPostGloas>;
cells: fulu.Cell[][];
/**
* Cached envelope state root computed during block production.
* Cached payload envelope state root computed during block production.
* This is the state root after running `processExecutionPayloadEnvelope` on the
* post-block state, and later used to construct the `ExecutionPayloadEnvelope`.
*/
envelopeStateRoot: Root;
payloadEnvelopeStateRoot: Root;
};
export type ProduceFullFulu = {
type: BlockType.Full;
Expand Down
2 changes: 1 addition & 1 deletion packages/state-transition/src/stateTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export enum StateHashTreeRootSource {
prepareNextEpoch = "prepare_next_epoch",
regenState = "regen_state",
computeNewStateRoot = "compute_new_state_root",
computeEnvelopeStateRoot = "compute_envelope_state_root",
computePayloadEnvelopeStateRoot = "compute_payload_envelope_state_root",
Comment thread
nflaig marked this conversation as resolved.
}

/**
Expand Down
Loading