Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8399512
initial commit
kevaundray Sep 15, 2025
9b78a25
rename to zkevm_proof
kevaundray Sep 15, 2025
abb1360
remove payload header from verify_zkevm_proof
kevaundray Sep 15, 2025
d887390
initial beacon chain commit
kevaundray Sep 16, 2025
882fb04
remove fork epoch and version
kevaundray Sep 16, 2025
833dca3
commit fork.md
kevaundray Sep 16, 2025
81326d4
remove fork.md (ie no fork is needed)
kevaundray Sep 16, 2025
4bd49cc
add SignedExecutionProof
kevaundray Sep 16, 2025
69ebaa3
initial validator.md
kevaundray Sep 16, 2025
bb16ed4
remove MAX_PROF_SYSTEM
kevaundray Sep 16, 2025
6ba4645
raise exception when proofID not found
kevaundray Sep 16, 2025
f9d600c
init p2p-interface.md
kevaundray Sep 16, 2025
93fce96
Merge branch 'master' into kw/zkevm-proof
kevaundray Sep 16, 2025
d890137
ExecutionWitness -> ZkExecutionWitness
kevaundray Sep 16, 2025
4f78959
use SignedExecutionProofs
kevaundray Sep 16, 2025
564e33e
ExecutionWitness -> ZKExecutionWitness
kevaundray Sep 16, 2025
860b277
JT review
kevaundray Sep 16, 2025
fe497a7
EL_PROGRAM -> ProgramSource
kevaundray Sep 16, 2025
15da8bf
remove ProgramSource
kevaundray Sep 16, 2025
fcc6bdf
rm
kevaundray Sep 16, 2025
7ba7640
remove public methods header and ProgramSource
kevaundray Sep 16, 2025
b912057
remove multiple EL programs
kevaundray Sep 16, 2025
21376dd
make lint
kevaundray Sep 16, 2025
998f2aa
make lint
kevaundray Sep 16, 2025
be4509a
Merge branch 'master' into kw/zkevm-proof
kevaundray Sep 16, 2025
780918c
use blockhash and subnet id
kevaundray Sep 16, 2025
feb53be
lint
kevaundray Sep 16, 2025
bd54aae
append proof_id to bytecode
kevaundray Sep 16, 2025
f197c2a
change desc
kevaundray Sep 16, 2025
69b967e
extend description
kevaundray Sep 16, 2025
4027018
multi:
kevaundray Sep 16, 2025
6175bcb
add comments on the constants
kevaundray Sep 16, 2025
187307b
update domain type
kevaundray Sep 16, 2025
605ac53
rename folder: execution_proofs -> optional_execution_proofs
kevaundray Sep 16, 2025
f5d62ad
remove extraneous constants
kevaundray Sep 16, 2025
9b7179c
reduce `MAX_EXECUTION_PROOFS_PER_PAYLOAD` -- its arbitrary
kevaundray Sep 16, 2025
a367540
reduce maximum amount of proofs per payload and make ProgramBytecode …
kevaundray Sep 16, 2025
52010b9
rename folder eip8025
kevaundray Sep 17, 2025
504568d
Fix spec titles & use minlevel=2 for toc
jtraglia Sep 17, 2025
2752875
Fix some nits
jtraglia Sep 17, 2025
5220338
Add eip8025 section to release notes
jtraglia Sep 17, 2025
9adbefa
Fix prereq sentence
jtraglia Sep 17, 2025
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
2 changes: 2 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ categories:
label: eip7441
- title: EIP-7805
label: eip7805
- title: EIP-8025
label: eip8025

# Testing
- title: Testing
Expand Down
215 changes: 215 additions & 0 deletions specs/_features/eip8025/beacon-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# EIP-8025 -- The Beacon Chain

*Note*: This document is a work-in-progress for researchers and implementers.

## Table of contents

<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->

- [Table of contents](#table-of-contents)
- [Introduction](#introduction)
- [Constants](#constants)
- [Execution](#execution)
- [Domain types](#domain-types)
- [Configuration](#configuration)
- [Containers](#containers)
- [New containers](#new-containers)
- [`ExecutionProof`](#executionproof)
- [`SignedExecutionProof`](#signedexecutionproof)
- [Extended Containers](#extended-containers)
- [Helper functions](#helper-functions)
- [Execution proof functions](#execution-proof-functions)
- [`verify_execution_proof`](#verify_execution_proof)
- [`verify_execution_proofs`](#verify_execution_proofs)
- [Beacon chain state transition function](#beacon-chain-state-transition-function)
- [Execution payload processing](#execution-payload-processing)
- [Modified `process_execution_payload`](#modified-process_execution_payload)

<!-- mdformat-toc end -->

## Introduction

This document contains the consensus specs for EIP-8025. This enables stateless
validation of execution payloads through cryptographic proofs.

*Note*: This specification is built upon [Fulu](../../fulu/beacon-chain.md) and
is under active development.

*Note*: This specification assumes the reader is familiar with the
[public zkEVM methods exposed](./zkevm.md).

## Constants

### Execution

| Name | Value |
| ---------------------------------- | -------------------------------------- |
| `MAX_EXECUTION_PROOFS_PER_PAYLOAD` | `uint64(4)` |
| `PROGRAM` | `ProgramBytecode(b"DEFAULT__PROGRAM")` |

### Domain types

| Name | Value |
| ------------------------ | -------------------------- |
| `DOMAIN_EXECUTION_PROOF` | `DomainType('0x0B000000')` |

## Configuration

*Note*: The configuration values are not definitive.

| Name | Value |
| ------------------------------- | ----------- |
| `MIN_REQUIRED_EXECUTION_PROOFS` | `uint64(1)` |

## Containers

### New containers

#### `ExecutionProof`

```python
class ExecutionProof(Container):
beacon_root: Root
zk_proof: ZKEVMProof
validator_index: ValidatorIndex
```

#### `SignedExecutionProof`

```python
class SignedExecutionProof(Container):
message: ExecutionProof
signature: BLSSignature
```

### Extended Containers

*Note*: `BeaconState` and `BeaconBlockBody` remain the same. No modifications
are required for execution proofs since they are handled externally.

## Helper functions

### Execution proof functions

#### `verify_execution_proof`

```python
def verify_execution_proof(
signed_proof: SignedExecutionProof,
parent_hash: Hash32,
block_hash: Hash32,
state: BeaconState,
el_program: ProgramBytecode,
) -> bool:
"""
Verify an execution proof against a payload header using zkEVM verification.
"""

# Note: signed_proof.message.beacon_root verification will be done at a higher level

# Verify the validator signature
proof_message = signed_proof.message
validator = state.validators[proof_message.validator_index]
signing_root = compute_signing_root(proof_message, get_domain(state, DOMAIN_EXECUTION_PROOF))
if not bls.Verify(validator.pubkey, signing_root, signed_proof.signature):
return False

# Derive program bytecode from the EL program identifier and proof type
program_bytecode = ProgramBytecode(
el_program + proof_message.zk_proof.proof_type.to_bytes(1, "little")
)

return verify_zkevm_proof(proof_message.zk_proof, parent_hash, block_hash, program_bytecode)
```

#### `verify_execution_proofs`

```python
def verify_execution_proofs(parent_hash: Hash32, block_hash: Hash32, state: BeaconState) -> bool:
"""
Verify that execution proofs are available and valid for an execution payload.
"""
# `retrieve_execution_proofs` is implementation and context dependent.
# It returns all execution proofs for the given payload block hash.
signed_execution_proofs = retrieve_execution_proofs(block_hash)

# Verify there are sufficient proofs
if len(signed_execution_proofs) < MIN_REQUIRED_EXECUTION_PROOFS:
return False

# Verify all execution proofs
for signed_proof in signed_execution_proofs:
if not verify_execution_proof(signed_proof, parent_hash, block_hash, state, PROGRAM):
return False

return True
```

## Beacon chain state transition function

### Execution payload processing

#### Modified `process_execution_payload`

```python
def process_execution_payload(
state: BeaconState,
body: BeaconBlockBody,
execution_engine: ExecutionEngine,
stateless_validation: bool = False,
) -> None:
"""
Note: This function is modified to support optional stateless validation with execution proofs.
"""
payload = body.execution_payload

# Verify consistency of the parent hash with respect to the previous execution payload header
assert payload.parent_hash == state.latest_execution_payload_header.block_hash
# Verify prev_randao
assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state))
# Verify timestamp
assert payload.timestamp == compute_time_at_slot(state, state.slot)
# Verify commitments are under limit
assert (
len(body.blob_kzg_commitments)
<= get_blob_parameters(get_current_epoch(state)).max_blobs_per_block
)

if stateless_validation:
# Stateless validation using execution proofs
assert verify_execution_proofs(payload.parent_hash, payload.block_hash, state)
else:
# Traditional validation - execute the payload
versioned_hashes = [
kzg_commitment_to_versioned_hash(commitment) for commitment in body.blob_kzg_commitments
]
assert execution_engine.verify_and_notify_new_payload(
NewPayloadRequest(
execution_payload=payload,
versioned_hashes=versioned_hashes,
parent_beacon_block_root=state.latest_block_header.parent_root,
execution_requests=body.execution_requests,
)
)

# Cache execution payload header
state.latest_execution_payload_header = ExecutionPayloadHeader(
parent_hash=payload.parent_hash,
fee_recipient=payload.fee_recipient,
state_root=payload.state_root,
receipts_root=payload.receipts_root,
logs_bloom=payload.logs_bloom,
prev_randao=payload.prev_randao,
block_number=payload.block_number,
gas_limit=payload.gas_limit,
gas_used=payload.gas_used,
timestamp=payload.timestamp,
extra_data=payload.extra_data,
base_fee_per_gas=payload.base_fee_per_gas,
block_hash=payload.block_hash,
transactions_root=hash_tree_root(payload.transactions),
withdrawals_root=hash_tree_root(payload.withdrawals),
blob_gas_used=payload.blob_gas_used,
excess_blob_gas=payload.excess_blob_gas,
)
```
108 changes: 108 additions & 0 deletions specs/_features/eip8025/p2p-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# EIP-8025 -- Networking

This document contains the networking specification for EIP-8025.

## Table of contents

<!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=2 -->

- [Table of contents](#table-of-contents)
- [Constants](#constants)
- [Containers](#containers)
- [The gossip domain: gossipsub](#the-gossip-domain-gossipsub)
- [Topics and messages](#topics-and-messages)
- [Global topics](#global-topics)
- [`execution_proof_{subnet_id}`](#execution_proof_subnet_id)
- [The Req/Resp domain](#the-reqresp-domain)
- [Messages](#messages)
- [ExecutionProofsByHash](#executionproofsbyhash)

<!-- mdformat-toc end -->

## Constants

*Note*: There are `MAX_EXECUTION_PROOFS_PER_PAYLOAD` (from
[beacon-chain.md](./beacon-chain.md)) execution proof subnets to provide 1-to-1
mapping with proof systems. Each proof system gets its own dedicated subnet.

## Containers

*Note*: Execution proofs are broadcast directly as `SignedExecutionProof`
containers. No additional message wrapper is needed.

## The gossip domain: gossipsub

### Topics and messages

#### Global topics

##### `execution_proof_{subnet_id}`

Execution proof subnets are used to propagate execution proofs for specific
proof systems.

The execution proof subnet for a given `proof_id` is:

```python
def compute_subnet_for_execution_proof(proof_id: ProofID) -> SubnetID:
assert proof_id < MAX_EXECUTION_PROOFS_PER_PAYLOAD
return SubnetID(proof_id)
```

The following validations MUST pass before forwarding the
`signed_execution_proof` on the network:

- _[IGNORE]_ The proof is the first valid proof received for the tuple
`(signed_execution_proof.message.zk_proof.public_inputs.block_hash, subnet_id)`.
- _[REJECT]_ The `signed_execution_proof.message.validator_index` is within the
known validator registry.
- _[REJECT]_ The `signed_execution_proof.signature` is valid with respect to the
validator's public key.
- _[REJECT]_ The `signed_execution_proof.message.zk_proof.proof_data` is
non-empty.
- _[REJECT]_ The proof system ID matches the subnet:
`signed_execution_proof.message.zk_proof.proof_type == subnet_id`.
- _[REJECT]_ The execution proof is valid as verified by
`verify_execution_proof()` with the appropriate parent and block hashes from
the execution layer.

## The Req/Resp domain

### Messages

#### ExecutionProofsByHash

**Protocol ID:** `/eth2/beacon/req/execution_proofs_by_hash/1/`

The `<context-bytes>` field is calculated as
`context = compute_fork_digest(fork_version, genesis_validators_root)`.

Request Content:

```
(
Hash32 # block_hash
)
```

Response Content:

```
(
List[SignedExecutionProof, MAX_EXECUTION_PROOFS_PER_PAYLOAD]
)
```

Requests execution proofs for the given execution payload `block_hash`. The
response MUST contain all available proofs for the requested block hash, up to
`MAX_EXECUTION_PROOFS_PER_PAYLOAD`.

The following validations MUST pass:

- _[REJECT]_ The `block_hash` is a 32-byte value.

The response MUST contain:

- All available execution proofs for the requested block hash.
- The response MUST NOT contain more than `MAX_EXECUTION_PROOFS_PER_PAYLOAD`
proofs.
Loading