-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add specs for EIP-8025 (Optional Execution Proofs) #4591
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
Merged
+638
−0
Merged
Changes from 22 commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
8399512
initial commit
kevaundray 9b78a25
rename to zkevm_proof
kevaundray abb1360
remove payload header from verify_zkevm_proof
kevaundray d887390
initial beacon chain commit
kevaundray 882fb04
remove fork epoch and version
kevaundray 833dca3
commit fork.md
kevaundray 81326d4
remove fork.md (ie no fork is needed)
kevaundray 4bd49cc
add SignedExecutionProof
kevaundray 69ebaa3
initial validator.md
kevaundray bb16ed4
remove MAX_PROF_SYSTEM
kevaundray 6ba4645
raise exception when proofID not found
kevaundray f9d600c
init p2p-interface.md
kevaundray 93fce96
Merge branch 'master' into kw/zkevm-proof
kevaundray d890137
ExecutionWitness -> ZkExecutionWitness
kevaundray 4f78959
use SignedExecutionProofs
kevaundray 564e33e
ExecutionWitness -> ZKExecutionWitness
kevaundray 860b277
JT review
kevaundray fe497a7
EL_PROGRAM -> ProgramSource
kevaundray 15da8bf
remove ProgramSource
kevaundray fcc6bdf
rm
kevaundray 7ba7640
remove public methods header and ProgramSource
kevaundray b912057
remove multiple EL programs
kevaundray 21376dd
make lint
kevaundray 998f2aa
make lint
kevaundray be4509a
Merge branch 'master' into kw/zkevm-proof
kevaundray 780918c
use blockhash and subnet id
kevaundray feb53be
lint
kevaundray bd54aae
append proof_id to bytecode
kevaundray f197c2a
change desc
kevaundray 69b967e
extend description
kevaundray 4027018
multi:
kevaundray 6175bcb
add comments on the constants
kevaundray 187307b
update domain type
kevaundray 605ac53
rename folder: execution_proofs -> optional_execution_proofs
kevaundray f5d62ad
remove extraneous constants
kevaundray 9b7179c
reduce `MAX_EXECUTION_PROOFS_PER_PAYLOAD` -- its arbitrary
kevaundray a367540
reduce maximum amount of proofs per payload and make ProgramBytecode …
kevaundray 52010b9
rename folder eip8025
kevaundray 504568d
Fix spec titles & use minlevel=2 for toc
jtraglia 2752875
Fix some nits
jtraglia 5220338
Add eip8025 section to release notes
jtraglia 9adbefa
Fix prereq sentence
jtraglia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| # Execution Proofs -- 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=1 --> | ||
|
|
||
| - [Execution Proofs -- The Beacon Chain](#execution-proofs----the-beacon-chain) | ||
| - [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 Execution Proofs. This enables stateless validation of execution payloads through cryptographic proofs. | ||
|
|
||
| *Note*: This specification assumes the reader is familiar with the [zkEVM cryptographic operations](./zkevm.md). | ||
|
|
||
| ## Constants | ||
|
|
||
| ### Execution | ||
|
|
||
| | Name | Value | | ||
| | --------------------------------------- | ----------------- | | ||
| | `MAX_EXECUTION_PROOFS_PER_PAYLOAD` | `uint64(8)` | | ||
| | `PROGRAM` | `ProgramSource(b"PROG_V1" + b"\x00" * 25)` | | ||
|
|
||
| ### Domain types | ||
|
|
||
| | Name | Value | | ||
| | -------------------------- | -------------------------- | | ||
| | `DOMAIN_EXECUTION_PROOF` | `DomainType('0x0A000000')` | | ||
|
|
||
| ## 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: ZKProof | ||
| validator_index: ValidatorIndex | ||
| ``` | ||
|
|
||
| #### `SignedExecutionProof` | ||
|
|
||
| ```python | ||
| class SignedExecutionProof(Container): | ||
| message: ExecutionProof | ||
| signature: BLSSignature | ||
| ``` | ||
|
|
||
| ### Extended Containers | ||
|
|
||
| *Note*: `BeaconState` and `BeaconBlockBody` remain the same as Fulu. 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: ProgramSource) -> bool: | ||
| """ | ||
| Verify an execution proof against a payload header using zkEVM verification. | ||
| """ | ||
|
|
||
| # Note: signed_proof.message.beacon_root verification would 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 the execution proofs for the given payload block hash | ||
| signed_execution_proofs = retrieve_execution_proofs(block_hash) | ||
|
|
||
| # Verify we have 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, | ||
| ) | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # Execution Proofs -- Networking | ||
|
|
||
| This document contains the networking specification for Execution Proofs. | ||
|
|
||
| ## Table of contents | ||
|
|
||
| <!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=1 --> | ||
|
|
||
| - [Execution Proofs -- Networking](#execution-proofs----networking) | ||
| - [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`](#execution_proof) | ||
| - [The Req/Resp domain](#the-reqresp-domain) | ||
| - [Messages](#messages) | ||
| - [ExecutionProofsByHash](#executionproofsbyHash) | ||
|
|
||
| <!-- mdformat-toc end --> | ||
|
|
||
| ## Constants | ||
|
|
||
| *Note*: Execution proof subnets use `MAX_EXECUTION_PROOFS_PER_PAYLOAD` (from [beacon-chain.md](./beacon-chain.md)) 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.beacon_root, signed_execution_proof.message.validator_index)`. | ||
| - _[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`. | ||
|
|
||
| Subnet topics follow the pattern: `/eth2/execution_proof_{subnet_id}/ssz_snappy` | ||
|
|
||
| ## 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # Execution Proofs -- Validator | ||
|
|
||
| **Notice**: This document is a work-in-progress for researchers and implementers. | ||
|
|
||
| ## Table of contents | ||
|
|
||
| <!-- mdformat-toc start --slug=github --no-anchors --maxlevel=6 --minlevel=1 --> | ||
|
|
||
| - [Execution Proofs -- Validator](#execution-proofs----validator) | ||
| - [Table of contents](#table-of-contents) | ||
| - [Introduction](#introduction) | ||
| - [Prerequisites](#prerequisites) | ||
| - [Configuration](#configuration) | ||
| - [Optional execution proof generation](#optional-execution-proof-generation) | ||
| - [`generate_execution_proof`](#generate_execution_proof) | ||
| - [`broadcast_execution_proof`](#broadcast_execution_proof) | ||
|
|
||
| <!-- mdformat-toc end --> | ||
|
|
||
| ## Introduction | ||
|
|
||
| This document represents optional execution proof generation capabilities that validators may choose to implement. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| This document is an extension of the [Fulu -- Validator](../../fulu/validator.md) guide. | ||
|
|
||
| ## Configuration | ||
|
|
||
| | Name | Value | | ||
| | --------------------------------------- | ----------------- | | ||
| | `EXECUTION_PROOF_GENERATION_ENABLED` | `False` | | ||
|
|
||
| ## Optional execution proof generation | ||
|
|
||
| Validators MAY choose to generate execution proofs for payloads they propose or receive. | ||
|
|
||
| ### `generate_execution_proof` | ||
|
|
||
| ```python | ||
| def generate_execution_proof(payload: ExecutionPayload, execution_witness: ZKExecutionWitness, proof_id: ProofID) -> Optional[SignedExecutionProof]: | ||
| """ | ||
| Generate an execution proof for the given payload | ||
| """ | ||
| if not EXECUTION_PROOF_GENERATION_ENABLED: | ||
| return None | ||
|
|
||
| zk_proof = generate_zkevm_proof(payload, execution_witness, PROGRAM, proof_id) | ||
|
|
||
| if zk_proof is None: | ||
| return None | ||
|
|
||
| validator_index = get_validator_index() | ||
| beacon_root = get_current_beacon_root() | ||
|
|
||
| execution_proof_message = ExecutionProof( | ||
| beacon_root=beacon_root, | ||
| zk_proof=zk_proof, | ||
| validator_index=validator_index, | ||
| ) | ||
|
|
||
| signing_root = compute_signing_root(execution_proof_message, get_domain(get_current_state(), DOMAIN_EXECUTION_PROOF)) | ||
| signature = bls.Sign(get_validator_private_key(), signing_root) | ||
|
|
||
| return SignedExecutionProof( | ||
| message=execution_proof_message, | ||
| signature=signature, | ||
| ) | ||
| ``` | ||
|
|
||
| ### `broadcast_execution_proof` | ||
|
|
||
| ```python | ||
| def broadcast_execution_proof(signed_proof: SignedExecutionProof) -> None: | ||
| """ | ||
| Broadcast an execution proof to the network. | ||
| """ | ||
| # Broadcast on the appropriate subnet based on proof system | ||
| subnet_id = compute_subnet_for_execution_proof(signed_proof.message.zk_proof.proof_type) | ||
| topic = f"execution_proof_{subnet_id}" | ||
|
|
||
| broadcast_to_topic(topic, signed_proof) | ||
| ``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
main change is additional stateless_validation parameter. When set to false, nothing changes from the fork it was built upon