Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Minimal ePBS without Max EB and 7002 #2

Open
wants to merge 112 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
5ef39b8
init
potuz Aug 7, 2023
1a49a51
Add engine methods and check IL validity
potuz Aug 8, 2023
0e2267d
add small design notes for ILs
potuz Aug 8, 2023
844381d
check for gas usage after payload insertion
potuz Aug 8, 2023
ee37d4c
Add helpers that change on ePBS
potuz Aug 8, 2023
13d75bc
switch to gas limit instead of usage as pointed by V. Buterin
potuz Aug 9, 2023
f4b566b
Added more changed helpers
potuz Aug 9, 2023
08b881d
change design notes
potuz Aug 22, 2023
d339dfc
minor changes
potuz Aug 25, 2023
ff1eff7
First forkchoice changes.
potuz Aug 25, 2023
ef7bd40
don't modify verify_block_signature
potuz Aug 25, 2023
9dbd2c5
remove clutter
potuz Aug 25, 2023
c7331a1
Check IL compatibility with parent block hash
potuz Aug 26, 2023
8d6ce8b
Do not broadcast the parent_block_hash but use it as parameter to the EL
potuz Aug 26, 2023
759cdd6
process payment immediately
potuz Aug 26, 2023
90b42e6
Deal with withdrawals
potuz Aug 26, 2023
a604462
fix withdrawals, check only in the CL
potuz Aug 26, 2023
d6ca928
remove unused request dataclass
potuz Aug 27, 2023
70a6e6d
pass the propsoer_index to process_execution_payload_header
potuz Aug 27, 2023
2c4fc84
run doctoc
potuz Aug 27, 2023
43a8dd6
only cache the withdrawals root in the state
potuz Aug 27, 2023
52067d5
ptc rewards pass 1
potuz Aug 28, 2023
a3c2468
only pass relevant IL info to the EL
potuz Aug 28, 2023
800a910
Use envelopes instead of adding builder info to the payload
potuz Aug 28, 2023
0228ea0
ptc message handlers in forkchoice
potuz Aug 29, 2023
1ae9cd9
take ptc members from all committees
potuz Aug 29, 2023
2ed9678
add forkchoice helper to get committee voted
potuz Aug 29, 2023
4389af4
add rewards and ptc attestations to the design doc
potuz Aug 29, 2023
23c46d7
doctoc
potuz Aug 29, 2023
4fe85f8
Design decisions in forkchoice
potuz Aug 30, 2023
4eaddd9
checkpoint descriptions
potuz Aug 30, 2023
d9e0278
fix PTC rewards for old blocks
potuz Aug 30, 2023
4060a9b
update forkchoice weights, take 1
potuz Aug 30, 2023
f3006ca
doctoc updated
potuz Aug 30, 2023
5004908
add head_root
potuz Aug 30, 2023
dc7b24c
add comment on equivocation
potuz Sep 1, 2023
169e02b
remove signed execution payload header
potuz Sep 1, 2023
a7e3ba1
typos
potuz Sep 1, 2023
837897e
add max EB changes
potuz Sep 4, 2023
a29a34c
add el withdraws in the beacon block body
potuz Sep 4, 2023
faacffe
doctoc
potuz Sep 4, 2023
aa88419
add slot to IL
potuz Sep 8, 2023
66f8ee1
use head_root in get_head
potuz Sep 11, 2023
b06e017
design notes
potuz Sep 11, 2023
c2eacf9
onboard builders
potuz Sep 11, 2023
1c6304b
block-slot is missing
potuz Sep 11, 2023
c43400a
block slot
potuz Sep 12, 2023
0c645ad
typos
potuz Sep 14, 2023
bcc1d5f
typos Terence found with chatgpt
potuz Sep 18, 2023
fad1f49
add helper to get payload hash
potuz Sep 20, 2023
458bb8f
minimal churn for transfers
potuz Oct 10, 2023
296a4e8
add mapping for exclusion
potuz Oct 11, 2023
9c5e60b
Revert "add mapping for exclusion"
potuz Oct 11, 2023
545d657
fix design for exclusion list
potuz Oct 11, 2023
bffcc04
fix signature verification
potuz Oct 13, 2023
99b2109
fix il proposers
potuz Oct 13, 2023
5db1f29
add censoring description
potuz Oct 13, 2023
f8db1ea
blockchain.md
potuz Apr 2, 2024
37e892b
doctoc
potuz Apr 2, 2024
945d8bb
init p2p
potuz Apr 2, 2024
ba51dcc
deal with withdrawals in two steps
potuz Apr 3, 2024
6e03e58
more p2p
potuz Apr 3, 2024
d89e527
deal with ptc equivocations
potuz Apr 3, 2024
7c5b458
builder init
potuz Apr 4, 2024
7198b11
Some hardening
potuz Apr 4, 2024
7adb9ea
blob sidecar changes
potuz Apr 4, 2024
4160deb
engine init
potuz Apr 4, 2024
77cd6aa
doctoc
potuz Apr 5, 2024
29a1c4d
move hash to the inclusion list envelope
potuz Apr 5, 2024
2bde439
use min instead of max for get_ptc
potuz Apr 5, 2024
5759e34
add parent_block_root to the execution bid
potuz Apr 7, 2024
de20380
beacon block p2p changes
potuz Apr 8, 2024
c4aa0cd
on_block and keep unsigned header in state
potuz Apr 8, 2024
99132a4
changed type in state too
potuz Apr 8, 2024
c9e1834
penalize twice the proposer for including bad ptc
potuz Apr 8, 2024
f785453
inclusion list forkchoice handler
potuz Apr 8, 2024
075837e
ptc_message forkchoice handler
potuz Apr 8, 2024
0659a91
only check payload hash if not withheld
potuz Apr 12, 2024
4d799b2
forkchoice no payload boosts
potuz Apr 15, 2024
7b6fa0f
Fix ePBS beacon_chain.md typos
terencechain Apr 15, 2024
3411f45
Add payload boosts
potuz Apr 16, 2024
b33c222
doctoc
potuz Apr 16, 2024
680bcdb
fix typo withheld -> withhold
potuz Apr 16, 2024
25dde5e
apply boost for attestations from blocks as well
potuz Apr 16, 2024
9fa6e14
typo
potuz Apr 16, 2024
960e92d
Fix some forkchoice typos
terencechain Apr 16, 2024
018fa39
Update specs/_features/epbs/fork-choice.md
terencechain Apr 16, 2024
ac93d02
fix get_head to take all children with or without payload from justified
potuz Apr 17, 2024
727a043
do not compute the same child twice
potuz Apr 17, 2024
5f97041
Revert "do not compute the same child twice"
potuz Apr 17, 2024
84280a7
Reapply "do not compute the same child twice"
potuz Apr 17, 2024
b68d884
only iterate over children with actual payloads
potuz Apr 17, 2024
8674517
consider PTC vote untying max weight
potuz Apr 17, 2024
b2c6482
Fix boost computation
potuz Apr 17, 2024
17b9e90
use ChildNode across forkchoice
potuz Apr 17, 2024
c63b81e
doctoc
potuz Apr 17, 2024
5ff8d54
modify get_ancestor to return a ChildNode
potuz Apr 17, 2024
f35cc68
typo
potuz Apr 17, 2024
18c31e4
fix boosts for future slots
potuz Apr 17, 2024
ba0283c
remove unnecessary node redefinition
potuz Apr 18, 2024
9edc282
descend only into right payload except at the justified checkpoint
potuz Apr 18, 2024
f3a035a
update head root in get_head loop
potuz Apr 18, 2024
6c60686
update get_head to use ChildNodes
potuz Apr 18, 2024
502e98d
stranded on_block simplifications
potuz Apr 18, 2024
05fbb9a
did not remove process_withdrawals
potuz Apr 18, 2024
1e9406d
Add engine_getInclusionListV1 to engine.md
terencechain Apr 19, 2024
8883b29
coherent naming in engine API
potuz Apr 19, 2024
ae35416
fix unused constant
potuz Apr 19, 2024
eedf7fb
Apply suggestions from Leonardo Arias
potuz Apr 24, 2024
5ebda89
Move exec payload header position to replace latest payload header
terencechain Apr 25, 2024
2decd43
require the target blockroot of a PTC message is valid
potuz May 17, 2024
d0060c0
Add fork logic for ePBS (#6)
terencechain Jun 25, 2024
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
731 changes: 731 additions & 0 deletions specs/_features/epbs/beacon-chain.md

Large diffs are not rendered by default.

116 changes: 116 additions & 0 deletions specs/_features/epbs/builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# ePBS -- Honest Builder

This is an accompanying document which describes the expected actions of a "builder" participating in the Ethereum proof-of-stake protocol.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Builders attributions](#builders-attributions)
- [Constructing the payload bid](#constructing-the-payload-bid)
- [Constructing the `BlobSidecar`s](#constructing-the-blobsidecars)
- [Constructing the execution payload envelope](#constructing-the-execution-payload-envelope)
- [Honest payload withheld messages](#honest-payload-withheld-messages)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Introduction

With the ePBS Fork, the protocol includes new staked participants of the protocol called *Builders*. While Builders are a subset of the validator set, they have extra attributions that are optional. Validators may opt to not be builders and as such we collect the set of guidelines for those validators that want to act as builders in this document.

Choose a reason for hiding this comment

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

Maybe mention that a validator that is not a builder is called a proposer.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I don't think this statement is true though.


## Builders attributions

Builders can submit bids to produce execution payloads. They can broadcast these bids in the form of `SignedExecutionPayloadHeader` objects, these objects encode a commitment to reveal an execution payload in exchange for a payment. When their bids are chosen by the corresponding proposer, builders are expected to broadcast an accompanying `SignedExecutionPayloadEnvelope` object honoring the commitment.

Thus, builders tasks are divided in two, submitting bids, and submitting payloads.

### Constructing the payload bid

Builders can broadcast a payload bid for the current or the next slot's proposer to include. They produce a `SignedExecutionPayloadHeader` as follows.

Prior to constructing a payload, the builder **MUST** have a full `InclusionList` object from the proposer matching `state.previous_inclusion_list_proposer`. The signed summary for this inclusion list will be needed when revealing the full execution payload (see below).
Copy link

Choose a reason for hiding this comment

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

may be totally remove inclusion list for now?

Copy link
Owner Author

Choose a reason for hiding this comment

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

it will be removed in the EIP, I'll open a new PR in this repo based on Electra soon

1. Set `header.parent_block_hash` to the current head of the execution chain (this can be obtained from the beacon state as `state.last_block_hash`).
2. Set `header.parent_block_root` to be the head of the consensus chain (this can be obtained from the beacon state as `hash_tree_root(state.latest_block_header)`.
3. Construct an execution payload. This can be performed with an external execution engine with a call to `engine_getPayloadV4`.
4. Set `header.block_hash` to be the block hash of the constructed payload, that is `payload.block_hash`
5. Set `header.builder_index` to be the validator index of the builder performing these actions.
6. Set `header.slot` to be the slot for which this bid is aimed. This slot **MUST** be either the current slot or the next slot.
7. Set `header.value` to be the value that the builder will pay the proposer if the bid is accepted. The builder **MUST** have balance enough to fulfill this bid.
8. Set `header.kzg_commitments_root` to be the `hash_tree_root` of the `blobsbundle.commitments` field returned by `engine_getPayloadV4`.

After building the `header`, the builder obtains a `signature` of the header by using

```python
def get_execution_payload_header_signature(state: BeaconState, header: ExecutionPayloadHeader, privkey: int) -> BLSSignature:
domain = get_domain(state, DOMAIN_BEACON_BUILDER, compute_epoch_at_slot(header.slot))
signing_root = compute_signing_root(header, domain)
return bls.Sign(privkey, signing_root)
```

The builder assembles then `signed_exceution_payload_header = SignedExecutionPayloadHeader(message=header, signature=signature)` and broadcasts it on the `execution_payload_header` global gossip topic.

### Constructing the `BlobSidecar`s

[Modified in ePBS]

The `BlobSidecar` container is modified indirectly because the constant `KZG_COMMITMENT_INCLUSION_PROOF_DEPTH` is modified. Each sidecar is obtained from the modified

```python
def get_blob_sidecars(signed_block: SignedBeaconBlock,
blobs: Sequence[Blob],
blob_kzg_proofs: Sequence[KZGProof]) -> Sequence[BlobSidecar]:
block = signed_block.message
block_header = BeaconBlockHeader(
slot=block.slot,
proposer_index=block.proposer_index,
parent_root=block.parent_root,
state_root=block.state_root,
body_root=hash_tree_root(block.body),
)
signed_block_header = SignedBeaconBlockHeader(message=block_header, signature=signed_block.signature)
return [
BlobSidecar(
index=index,
blob=blob,
kzg_commitment=block.body.blob_kzg_commitments[index],
kzg_proof=blob_kzg_proofs[index],
signed_block_header=signed_block_header,
kzg_commitment_inclusion_proof=compute_merkle_proof(
block.body,
GeneralizedIndex(KZG_GENERALIZED_INDEX_PREFIX + index),
),
)
for index, blob in enumerate(blobs)
]
```

### Constructing the execution payload envelope

When the proposer publishes a valid `SignedBeaconBlock` containing a signed commitment by the builder, the builder is later expected to broadcast the corresponding `SignedExecutionPayloadEnvelope` that fulfills this commitment. See below for a special case of an *honestly withheld payload*.

To construct the `execution_payload_envelope` the builder must perform the following steps, we alias `header` to be the committed `ExecutionPayloadHeader` in the beacon block.

1. Set the `payload` field to be the `ExecutionPayload` constructed when creating the corresponding bid. This payload **MUST** have the same block hash as `header.block_hash`.
2. Set the `builder_index` field to be the validator index of the builder performing these steps. This field **MUST** be `header.builder_index`.
3. Set `beacon_block_root` to be the `hash_tree_root` of the corresponding beacon block.
4. Set `blob_kzg_commitments` to be the `commitments` field of the blobs bundle constructed when constructing the bid. This field **MUST** have a `hash_tree_root` equal to `header.blob_kzg_commitments_root`.
5. Set `inclusion_list_proposer_index` to be the `inclusion_list_summary.proposer_index` from the inclusion list used when creating the bid.
6. Set `inclusion_list_slot` to be the `inclusion_list_summary.slot` from the inclusion list used when creating the bid.
7. Set the `inclusion_list_signature` to be `signed_inclusion_list_summary.signature` from the inclusion list used when creating the bid.
8. Set `payload_witheld` to `False`.

After setting these parameters, the builder should run `process_execution_payload(state, signed_envelope, verify=False)` and this function should not trigger an exception.

9. Set `state_root` to `hash_tree_root(state)`.
After preparing the `envelope` the builder should sign the envelope using:
```python
def get_execution_payload_envelope_signature(state: BeaconState, envelope: ExecutionPayloadEnvelope, privkey: int) -> BLSSignature:
domain = get_domain(state, DOMAIN_BEACON_BUILDER, compute_epoch_at_slot(state.slot))
signing_root = compute_signing_root(envelope, domain)
return bls.Sign(privkey, signing_root)
```
The builder assembles then `signed_exceution_payload_envelope = SignedExecutionPayloadEnvelope(message=envelope, signature=signature)` and broadcasts it on the `execution_payload` global gossip topic.

### Honest payload withheld messages

An honest builder that has seen a `SignedBeaconBlock` referencing his signed bid, but that block was not timely and thus it is not the head of the builder's chain, may choose to withhold their execution payload. For this the builder should simply act as if it were building an empty payload, without any transactions, withdrawals, etc. Omit step 9 above and set `payload_withheld` to `True`. If the PTC sees this message and votes for it, validators will attribute a *withholding boost* to the builder, which would increase the forkchoice weight of the parent block, favouring it and preventing the builder from being charged for the bid by not revealing.

Choose a reason for hiding this comment

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

Suggested change
An honest builder that has seen a `SignedBeaconBlock` referencing his signed bid, but that block was not timely and thus it is not the head of the builder's chain, may choose to withhold their execution payload. For this the builder should simply act as if it were building an empty payload, without any transactions, withdrawals, etc. Omit step 9 above and set `payload_withheld` to `True`. If the PTC sees this message and votes for it, validators will attribute a *withholding boost* to the builder, which would increase the forkchoice weight of the parent block, favouring it and preventing the builder from being charged for the bid by not revealing.
An honest builder that has seen a `SignedBeaconBlock` referencing his signed bid, but that block was not timely and thus it is not the head of the builder's chain, may choose to withhold their execution payload. For this the builder should simply act as if it were building an empty payload, without any transactions, withdrawals, etc. Omit step 9 above and set `payload_withheld` to `True`. If the Payload Committee sees this message and votes for it, validators will attribute a *withholding boost* to the builder, which would increase the forkchoice weight of the parent block, favouring it and preventing the builder from being charged for the bid by not revealing.

220 changes: 220 additions & 0 deletions specs/_features/epbs/engine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Engine API -- ePBS

Engine API changes introduced in the ePBS fork.

## Table of contents

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Structures](#structures)
- [ExecutionPayloadV4](#executionpayloadv4)
- [PayloadAttributesV3](#payloadattributesv3)
- [InclusionListV1](#inclusionlistv1)
- [InclusionListStatusV1](#inclusionliststatusv1)
- [Methods](#methods)
- [engine_newInclusionListV1](#engine_newinclusionlistv1)
- [Request](#request)
- [Response](#response)
- [Specification](#specification)
- [engine_newPayloadV4](#engine_newpayloadv4)
- [Request](#request-1)
- [Response](#response-1)
- [Specification](#specification-1)
- [engine_forkchoiceUpdatedV3](#engine_forkchoiceupdatedv3)
- [Request](#request-2)
- [Response](#response-2)
- [Specification](#specification-2)
- [engine_getPayloadV3](#engine_getpayloadv3)
- [Request](#request-3)
- [Response](#response-3)
- [Specification](#specification-3)
- [`engine_getInclusionListV1`](#engine_getinclusionlistv1)
- [Request](#request-4)
- [Response](#response-4)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Structures

### ExecutionPayloadV4

This structure has the syntax of [`ExecutionPayloadV3`](./cancun.md#executionpayloadv3) and appends the new field `inclusionListSummary`

- `parentHash`: `DATA`, 32 Bytes
- `feeRecipient`: `DATA`, 20 Bytes
- `stateRoot`: `DATA`, 32 Bytes
- `receiptsRoot`: `DATA`, 32 Bytes
- `logsBloom`: `DATA`, 256 Bytes
- `prevRandao`: `DATA`, 32 Bytes
- `blockNumber`: `QUANTITY`, 64 Bits
- `gasLimit`: `QUANTITY`, 64 Bits
- `gasUsed`: `QUANTITY`, 64 Bits
- `timestamp`: `QUANTITY`, 64 Bits
- `extraData`: `DATA`, 0 to 32 Bytes
- `baseFeePerGas`: `QUANTITY`, 256 Bits
- `blockHash`: `DATA`, 32 Bytes
- `transactions`: `Array of DATA` - Array of transaction objects, each object is a byte list (`DATA`) representing `TransactionType || TransactionPayload` or `LegacyTransaction` as defined in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
- `withdrawals`: `Array of WithdrawalV1` - Array of withdrawals, each object is an `OBJECT` containing the fields of a `WithdrawalV1` structure.
- `blobGasUsed`: `QUANTITY`, 64 Bits
- `excessBlobGas`: `QUANTITY`, 64 Bits
- `inclusionListSummary`: `Array of (DATA, 20 Bytes)` - The summary of an inclusion list signed by a previous proposer.

### PayloadAttributesV3

This structure has the syntax of [`PayloadAttributesV2`](./shanghai.md#payloadattributesv2) and appends the fields `inclusionListParentHash` and `inclusionListProposerIndex`.

- `timestamp`: `QUANTITY`, 64 Bits - value for the `timestamp` field of the new payload
- `prevRandao`: `DATA`, 32 Bytes - value for the `prevRandao` field of the new payload
- `suggestedFeeRecipient`: `DATA`, 20 Bytes - suggested value for the `feeRecipient` field of the new payload
- `withdrawals`: `Array of WithdrawalV1` - Array of withdrawals, each object is an `OBJECT` containing the fields of a `WithdrawalV1` structure.
- `parentBeaconBlockRoot`: `DATA`, 32 Bytes - Root of the parent beacon block.
- `inclusionListParentHash`: `DATA`, 32 Bytes - Hash of the parent block of the required inclusion list.
- `inclusionListProposer`: 64 Bits - Validator index of the proposer of the inclusion list.

### InclusionListV1

[New in ePBS]

This structure contains the full list of transactions and the summary broadcast by a proposer of an inclusion list.

- `transactions`: `Array of DATA` - Array of transaction objects, each object is a byte list (`DATA`) representing `TransactionType || TransactionPayload` or `LegacyTransaction` as defined in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
- `summary`: `Array of DATA` - Array of addresses, each object is a byte list (`DATA`, 20 Bytes) representing the "from" address from the transactions in the `transactions` list.
- `parentHash`: `DATA`, 32 Bytes.
- `proposerIndex` : `QUANTITY`, 64 Bits.

### InclusionListStatusV1

[New in ePBS]

This structure contains the result of processing an inclusion list. The fields are encoded as follows:

- `status`: `enum`- `"VALID" | "INVALID" | "SYNCING" | "ACCEPTED"`
- `validationError`: `String|null` - a message providing additional details on the validation error if the inclusion list is classified as `INVALID`.

## Methods

### engine_newInclusionListV1

[New in ePBS]

#### Request

* method: `engine_newInclusionListV1`
* params:
1. `inclusion_list`: [`InclusionListV1`](#InclusionListV1).

#### Response

- result: [`InclusionListStatusV1`](#InclusionListStatusV1).
- error: code and message set in case an exception happens while processing the payload.

#### Specification

### engine_newPayloadV4

#### Request

* method: `engine_newPayloadV3`
* params:
1. `executionPayload`: [`ExecutionPayloadV3`](#ExecutionPayloadV3).
2. `expectedBlobVersionedHashes`: `Array of DATA`, 32 Bytes - Array of expected blob versioned hashes to validate.
3. `parentBeaconBlockRoot`: `DATA`, 32 Bytes - Root of the parent beacon block.

#### Response

Refer to the response for [`engine_newPayloadV2`](./shanghai.md#engine_newpayloadv2).

#### Specification

This method follows the same specification as [`engine_newPayloadV2`](./shanghai.md#engine_newpayloadv2) with the addition of the following:

1. Client software **MUST** check that provided set of parameters and their fields strictly matches the expected one and return `-32602: Invalid params` error if this check fails. Any field having `null` value **MUST** be considered as not provided.

2. Client software **MUST** return `-38005: Unsupported fork` error if the `timestamp` of the payload does not fall within the time frame of the Cancun fork.

3. Given the expected array of blob versioned hashes client software **MUST** run its validation by taking the following steps:
1. Obtain the actual array by concatenating blob versioned hashes lists (`tx.blob_versioned_hashes`) of each [blob transaction](https://eips.ethereum.org/EIPS/eip-4844#new-transaction-type) included in the payload, respecting the order of inclusion. If the payload has no blob transactions the expected array **MUST** be `[]`.
2. Return `{status: INVALID, latestValidHash: null, validationError: errorMessage | null}` if the expected and the actual arrays don't match.

This validation **MUST** be instantly run in all cases even during active sync process.

### engine_forkchoiceUpdatedV3

#### Request

* method: `engine_forkchoiceUpdatedV3`
* params:
1. `forkchoiceState`: [`ForkchoiceStateV1`](./paris.md#ForkchoiceStateV1).
2. `payloadAttributes`: `Object|null` - Instance of [`PayloadAttributesV3`](#payloadattributesv3) or `null`.
* timeout: 8s

#### Response

Refer to the response for [`engine_forkchoiceUpdatedV2`](./shanghai.md#engine_forkchoiceupdatedv2).

#### Specification

This method follows the same specification as [`engine_forkchoiceUpdatedV2`](./shanghai.md#engine_forkchoiceupdatedv2) with the following changes to the processing flow:

1. Client software **MUST** verify that `forkchoiceState` matches the [`ForkchoiceStateV1`](./paris.md#ForkchoiceStateV1) structure and return `-32602: Invalid params` on failure.

2. Extend point (7) of the `engine_forkchoiceUpdatedV1` [specification](./paris.md#specification-1) by defining the following sequence of checks that **MUST** be run over `payloadAttributes`:

1. `payloadAttributes` matches the [`PayloadAttributesV3`](#payloadattributesv3) structure, return `-38003: Invalid payload attributes` on failure.

2. `payloadAttributes.timestamp` falls within the time frame of the Cancun fork, return `-38005: Unsupported fork` on failure.

3. `payloadAttributes.timestamp` is greater than `timestamp` of a block referenced by `forkchoiceState.headBlockHash`, return `-38003: Invalid payload attributes` on failure.

4. If any of the above checks fails, the `forkchoiceState` update **MUST NOT** be rolled back.

### engine_getPayloadV3

The response of this method is extended with [`BlobsBundleV1`](#blobsbundlev1) containing the blobs, their respective KZG commitments
and proofs corresponding to the `versioned_hashes` included in the blob transactions of the execution payload.

#### Request

* method: `engine_getPayloadV3`
* params:
1. `payloadId`: `DATA`, 8 Bytes - Identifier of the payload build process
* timeout: 1s

#### Response

* result: `object`
- `executionPayload`: [`ExecutionPayloadV3`](#ExecutionPayloadV3)
- `blockValue` : `QUANTITY`, 256 Bits - The expected value to be received by the `feeRecipient` in wei
- `blobsBundle`: [`BlobsBundleV1`](#BlobsBundleV1) - Bundle with data corresponding to blob transactions included into `executionPayload`
- `shouldOverrideBuilder` : `BOOLEAN` - Suggestion from the execution layer to use this `executionPayload` instead of an externally provided one
* error: code and message set in case an exception happens while getting the payload.

#### Specification

Refer to the specification for [`engine_getPayloadV2`](./shanghai.md#engine_getpayloadv2) with addition of the following:

1. Client software **MUST** return `-38005: Unsupported fork` error if the `timestamp` of the built payload does not fall within the time frame of the Cancun fork.

2. The call **MUST** return `blobsBundle` with empty `blobs`, `commitments` and `proofs` if the payload doesn't contain any blob transactions.

3. The call **MUST** return `commitments` matching the versioned hashes of the transactions list of the execution payload, in the same order,
i.e. `assert verify_kzg_commitments_against_transactions(payload.transactions, blobsBundle.commitments)` (see EIP-4844 consensus-specs).

4. The call **MUST** return `blobs` and `proofs` that match the `commitments` list, i.e. `assert len(blobsBundle.commitments) == len(blobsBundle.blobs) == len(blobsBundle.proofs)` and `assert verify_blob_kzg_proof_batch(blobsBundle.blobs, blobsBundle.commitments, blobsBundle.proofs)`.

5. Client software **MAY** use any heuristics to decide whether to set `shouldOverrideBuilder` flag or not. If client software does not implement any heuristic this flag **SHOULD** be set to `false`.

### `engine_getInclusionListV1`

#### Request

* method: `engine_getInclusionListV1`
* params:
1. `parentHash`: `DATA`, 32 Bytes - hash of the block which the returning inclusion list bases on
* timeout: 1s

#### Response

* result: [`InclusionListV1`](#inclusionlistv1)
* error: code and message set in case an exception happens while getting the inclusion list.
Loading
Loading