diff --git a/src/engine/eip8025.md b/src/engine/eip8025.md new file mode 100644 index 000000000..3d51ea368 --- /dev/null +++ b/src/engine/eip8025.md @@ -0,0 +1,184 @@ +# Engine API -- EIP-8025 + +Engine API methods for stateless validation using execution proofs. + +This specification is based on and extends [Engine API - Osaka](./osaka.md) specification. + +## Table of contents + + + + +- [Structures](#structures) + - [PublicInputV1](#publicinputv1) + - [ExecutionProofV1](#executionproofv1) + - [ProofAttributesV1](#proofAttributesv1) + - [ExecutionPayloadHeaderV1](#executionpayloadheaderv1) + - [NewPayloadRequestHeaderV1](#newpayloadrequestheaderv1) + - [ProofStatusV1](#proofstatusv1) +- [Methods](#methods) + - [engine_verifyExecutionProofV1](#engine_verifyexecutionproofv1) + - [engine_verifyNewPayloadRequestHeaderV1](#engine_verifynewpayloadrequestheaderv1) + - [engine_requestProofsV1](#engine_requestproofsv1) +- [Errors](#errors) + + + +## Configuration + +*Note*: The configuration values are not definitive. + +| Name | Value | Description | +|--------------------------------|-------|-------------| +| `MIN_REQUIRED_EXECUTION_PROOFS` | `1` | Minimum number of valid execution proofs required to satisfy proof requirements | + +## Structures + +### PublicInputV1 + +The fields are encoded as follows: + +- `newPayloadRequestRoot`: `DATA`, 32 Bytes - The hash tree root of the `NewPayloadRequest`. + +### ExecutionProofV1 + +The fields are encoded as follows: + +- `proofData`: `DATA` - Variable length proof data, maximum 300 KiB. +- `proofType`: `QUANTITY`, 64 Bits - Type identifier for the proof system. +- `publicInput`: `Object` - A [`PublicInputV1`](#publicinputv1) object. + +### ProofAttributesV1 + +The fields are encoded as follows: + +- `proofTypes`: `Array of QUANTITY` - Array of proof type identifiers to request. + +### ExecutionPayloadHeaderV1 + +This structure maps on the [`ExecutionPayloadHeader`] structure of the beacon chain spec. +The fields are encoded as follows: + +- `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 +- `transactionsRoot`: `DATA`, 32 Bytes - The hash tree root of the transactions included in the payload. +- `withdrawalsRoot`: `DATA`, 32 Bytes - The hash tree root of the withdrawals included in the payload. +- `blobGasUsed`: `QUANTITY`, 64 Bits +- `excessBlobGas`: `QUANTITY`, 64 Bits + +### NewPayloadRequestHeaderV1 + +The fields are encoded as follows: + +- `executionPayloadHeader`: `Object` - An [`ExecutionPayloadHeaderV1`](#executionpayloadheaderv1) object. +- `versionedHashes`: `Array of DATA`, 32 Bytes each - Array of blob versioned hashes. +- `parentBeaconBlockRoot`: `DATA`, 32 Bytes - Root of the parent beacon block. +- `executionRequests`: `Array of DATA` - Execution layer triggered requests. + +### ProofStatusV1 + +The fields are encoded as follows: + +- `status`: `String` - The verification status. One of: + - `"VALID"` - The proof/header verification succeeded. + - `"INVALID"` - The proof/header verification failed. + - `"SYNCING"` - Less than `MIN_REQUIRED_EXECUTION_PROOFS` valid proofs have been verified for the given header. + - `"NOT_SUPPORTED"` - The proof type is not supported by this client. +- `error`: `String` - Optional error message if status is not `"VALID"`. + +## Methods + +*Note*: The timeouts are not definitive. + +### engine_verifyExecutionProofV1 + +#### Request + +* method: `engine_verifyExecutionProofV1` +* params: + 1. `executionProof`: [`ExecutionProofV1`](#executionproofv1) - The execution proof to verify. +* timeout: 1s + +#### Response + +* result: [`ProofStatusV1`](#proofstatusv1) - The verification result. +* error: code and message set in case an exception happens while verifying the proof. + +#### Specification + +1. Client software **MUST** validate the `executionProof` parameter: + - `proofData` **MUST** be non-empty and not exceed 300 KiB. + - `proofType` **MUST** be a supported proof type. + - `publicInput.newPayloadRequestRoot` **MUST** be a valid 32-byte hash. + +2. Client software **MUST** verify the execution proof using the appropriate proof verification algorithm based on `proofType`. + +3. Client software **MUST** respond with `{status: "VALID"}` if the proof is valid, `{status: "INVALID", error: "..."}` if the proof is invalid, or `{status: "NOT_SUPPORTED", error: "..."}` if the proof type is not supported. + +### engine_verifyNewPayloadRequestHeaderV1 + +#### Request + +* method: `engine_verifyNewPayloadRequestHeaderV1` +* params: + 1. `newPayloadRequestHeader`: [`NewPayloadRequestHeaderV1`](#newpayloadrequestheaderv1) - The header to verify. +* timeout: 1s + +#### Response + +* result: [`ProofStatusV1`](#proofstatusv1) - The verification result. +* error: code and message set in case an exception happens while verifying. + +#### Specification + +1. Client software **MUST** validate the `newPayloadRequestHeader` parameter structure. + +2. Client software **MUST** respond with `{status: "VALID"}` if at least `MIN_REQUIRED_EXECUTION_PROOFS` proofs have been verified for this `NewPayloadRequestHeader`, or `{status: "SYNCING "}` if not. + +### engine_requestProofsV1 + +#### Request + +* method: `engine_requestProofsV1` +* params: + 1. `executionPayload`: [`ExecutionPayloadV3`](./cancun.md#executionpayloadv3) - The execution payload to generate proofs for. + 2. `versionedHashes`: `Array of DATA`, 32 Bytes each - Array of blob versioned hashes. + 3. `parentBeaconBlockRoot`: `DATA`, 32 Bytes - Root of the parent beacon block. + 4. `executionRequests`: `Array of DATA` - List of execution layer triggered requests. + 5. `proofAttributes`: [`ProofAttributesV1`](#proofAttributesv1) - Attributes specifying which proofs to generate. +* timeout: 1s + +#### Response + +* result: `DATA`, 8 Bytes - A `ProofGenId` to track the proof generation request. +* error: code and message set in case an exception happens while initiating proof generation. + +#### Specification + +1. Client software **MUST** validate all parameters. + +2. Client software **MUST** initiate asynchronous proof generation for the given payload and return a `ProofGenId` immediately. + +3. Generated proofs are delivered asynchronously via the beacon API endpoint `POST /eth/v1/prover/execution_proofs`. The client **MUST NOT** block waiting for proof generation to complete. + +4. If proof generation is unavailable (e.g., no prover configured), client software **MUST** return error code `-39004`. + +## Errors + +| Code | Message | Meaning | +|------|---------|---------| +| -39001 | Invalid proof format | The execution proof structure is malformed | +| -39002 | Invalid header format | The new payload request header structure is malformed | +| -39003 | Invalid payload | The execution payload is invalid | +| -39004 | Proof generation unavailable | The client cannot generate proofs | diff --git a/src/engine/openrpc/methods/proof.yaml b/src/engine/openrpc/methods/proof.yaml new file mode 100644 index 000000000..d6b0a6bd9 --- /dev/null +++ b/src/engine/openrpc/methods/proof.yaml @@ -0,0 +1,145 @@ +- name: engine_verifyExecutionProofV1 + summary: Verifies an execution proof + externalDocs: + description: Method specification + url: https://github.com/ethereum/execution-apis/blob/main/src/engine/eip8025.md#engine_verifyexecutionproofv1 + params: + - name: Execution proof + required: true + schema: + $ref: '#/components/schemas/ExecutionProofV1' + result: + name: Proof status + schema: + $ref: '#/components/schemas/ProofStatusV1' + errors: + - code: -39001 + message: Invalid proof format + examples: + - name: engine_verifyExecutionProofV1 example + params: + - name: Execution proof + value: + proofData: '0x0000000000000000000000000000000000000000000000000000000000000000' + proofType: '0x1' + publicInput: + newPayloadRequestRoot: '0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858' + result: + name: Proof status + value: + valid: true + +- name: engine_verifyNewPayloadRequestHeaderV1 + summary: Verifies a new payload request header has sufficient proof coverage + externalDocs: + description: Method specification + url: https://github.com/ethereum/execution-apis/blob/main/src/engine/eip8025.md#engine_verifynewpayloadrequestheaderv1 + params: + - name: New payload request header + required: true + schema: + $ref: '#/components/schemas/NewPayloadRequestHeaderV1' + result: + name: Verification status + schema: + $ref: '#/components/schemas/ProofStatusV1' + errors: + - code: -39002 + message: Invalid header format + examples: + - name: engine_verifyNewPayloadRequestHeaderV1 example + params: + - name: New payload request header + value: + executionPayloadHeader: + parentHash: '0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a' + feeRecipient: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b' + stateRoot: '0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45' + receiptsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + prevRandao: '0x0000000000000000000000000000000000000000000000000000000000000000' + blockNumber: '0x1' + gasLimit: '0x1c9c380' + gasUsed: '0x0' + timestamp: '0x5' + extraData: '0x' + baseFeePerGas: '0x7' + blockHash: '0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858' + transactionsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + withdrawalsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + blobGasUsed: '0x0' + excessBlobGas: '0x0' + versionedHashes: [] + parentBeaconBlockRoot: '0x0000000000000000000000000000000000000000000000000000000000000000' + executionRequests: [] + result: + name: Verification status + value: + valid: true + +- name: engine_requestProofsV1 + summary: Requests proof generation for a new payload request + externalDocs: + description: Method specification + url: https://github.com/ethereum/execution-apis/blob/main/src/engine/eip8025.md#engine_requestproofsv1 + params: + - name: Execution payload + required: true + schema: + $ref: '#/components/schemas/ExecutionPayloadV3' + - name: Versioned hashes + required: true + schema: + type: array + items: + $ref: '#/components/schemas/hash32' + - name: Parent beacon block root + required: true + schema: + $ref: '#/components/schemas/hash32' + - name: Proof attributes + required: true + schema: + $ref: '#/components/schemas/ProofAttributesV1' + result: + name: Proof generation ID + schema: + $ref: '#/components/schemas/bytes8' + errors: + - code: -39003 + message: Invalid payload + - code: -39004 + message: Proof generation unavailable + examples: + - name: engine_requestProofsV1 example + params: + - name: Execution payload + value: + parentHash: '0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a' + feeRecipient: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b' + stateRoot: '0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45' + receiptsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + prevRandao: '0x0000000000000000000000000000000000000000000000000000000000000000' + blockNumber: '0x1' + gasLimit: '0x1c9c380' + gasUsed: '0x0' + timestamp: '0x5' + extraData: '0x' + baseFeePerGas: '0x7' + blockHash: '0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858' + transactions: [] + withdrawals: [] + blobGasUsed: '0x0' + excessBlobGas: '0x0' + - name: Versioned hashes + value: [] + - name: Parent beacon block root + value: '0x0000000000000000000000000000000000000000000000000000000000000000' + - name: Proof attributes + value: + proofTypes: + - '0x1' + result: + name: Proof generation ID + value: '0x0000000000000001' diff --git a/src/engine/openrpc/schemas/proof.yaml b/src/engine/openrpc/schemas/proof.yaml new file mode 100644 index 000000000..324870bf6 --- /dev/null +++ b/src/engine/openrpc/schemas/proof.yaml @@ -0,0 +1,152 @@ +PublicInputV1: + title: Public input object V1 + type: object + required: + - newPayloadRequestRoot + properties: + newPayloadRequestRoot: + title: New payload request root + $ref: '#/components/schemas/hash32' + +ExecutionProofV1: + title: Execution proof object V1 + type: object + required: + - proofData + - proofType + - publicInput + properties: + proofData: + title: Proof data + $ref: '#/components/schemas/bytes' + proofType: + title: Proof type identifier + $ref: '#/components/schemas/uint64' + publicInput: + title: Public input + $ref: '#/components/schemas/PublicInputV1' + +ProofAttributesV1: + title: Proof attributes object V1 + type: object + required: + - proofTypes + properties: + proofTypes: + title: Requested proof types + type: array + items: + $ref: '#/components/schemas/uint64' + +NewPayloadRequestHeaderV1: + title: New payload request header V1 + type: object + required: + - executionPayloadHeader + - versionedHashes + - parentBeaconBlockRoot + - executionRequests + properties: + executionPayloadHeader: + title: Execution payload header + $ref: '#/components/schemas/ExecutionPayloadHeaderV1' + versionedHashes: + title: Versioned hashes + type: array + items: + $ref: '#/components/schemas/hash32' + parentBeaconBlockRoot: + title: Parent beacon block root + $ref: '#/components/schemas/hash32' + executionRequests: + title: Execution requests + type: array + items: + $ref: '#/components/schemas/bytes' + +ExecutionPayloadHeaderV1: + title: Execution payload header V1 + type: object + required: + - parentHash + - feeRecipient + - stateRoot + - receiptsRoot + - logsBloom + - prevRandao + - blockNumber + - gasLimit + - gasUsed + - timestamp + - extraData + - baseFeePerGas + - blockHash + - transactionsRoot + - withdrawalsRoot + - blobGasUsed + - excessBlobGas + properties: + parentHash: + title: Parent block hash + $ref: '#/components/schemas/hash32' + feeRecipient: + title: Recipient of transaction priority fees + $ref: '#/components/schemas/address' + stateRoot: + title: State root + $ref: '#/components/schemas/hash32' + receiptsRoot: + title: Receipts root + $ref: '#/components/schemas/hash32' + logsBloom: + title: Bloom filter + $ref: '#/components/schemas/bytes256' + prevRandao: + title: Previous randao value + $ref: '#/components/schemas/bytes32' + blockNumber: + title: Block number + $ref: '#/components/schemas/uint64' + gasLimit: + title: Gas limit + $ref: '#/components/schemas/uint64' + gasUsed: + title: Gas used + $ref: '#/components/schemas/uint64' + timestamp: + title: Timestamp + $ref: '#/components/schemas/uint64' + extraData: + title: Extra data + $ref: '#/components/schemas/bytesMax32' + baseFeePerGas: + title: Base fee per gas + $ref: '#/components/schemas/uint256' + blockHash: + title: Block hash + $ref: '#/components/schemas/hash32' + transactionsRoot: + title: Transactions root + $ref: '#/components/schemas/hash32' + withdrawalsRoot: + title: Withdrawals root + $ref: '#/components/schemas/hash32' + blobGasUsed: + title: Blob gas used + $ref: '#/components/schemas/uint64' + excessBlobGas: + title: Excess blob gas + $ref: '#/components/schemas/uint64' + +ProofStatusV1: + title: Proof verification status V1 + type: object + required: + - valid + properties: + valid: + title: Proof validity + type: boolean + error: + title: Error message if invalid + type: string