> [!Note] > Current version: https://github.com/developeruche/prysm/tree/ca228fca440f72da329f0d5d0488d105a633118c > [!Tip] > Legend > - ✅: Complete! > - 🚧: Under construction. > - 🔘: Nothing done. ## ✅ Flags - **`--activate-zkvm`**: If specified, set `cfg.EnableZkvm` to `true`. We can use `features.Get().EnableZkvm` to access this value in the codebase. - **`--zkvm-generation-proof-types`**: If specified, set `cfg.ProofGenerationTypes` to the slice of `ExecutionProofId`. We can use `flags.Get().ProofGenerationTypes` to access this value in the codebase. ## ✅ Data types ```go // ExecutionProofId identifies which zkVM/proof system a proof belongs to. type ExecutionProofId uint8 ``` - **`ExecutionProofId`**: Alias for `uint8`. Implemented in `consensus-types/primitives/execution_proof_id.go` ([Link](https://github.com/syjn99/prysm/blob/2d9e6ad2c8302b0045a4c6020f52e997c3f20bdf/consensus-types/primitives/execution_proof_id.go)). ```protobuf message ExecutionProof { // Which proof type (zkVM+EL combination) this proof belongs to // Examples: 0=SP1+Reth, 1=Risc0+Geth, 2=SP1+Geth, etc. uint64 proof_id = 1 [ (ethereum.eth.ext.cast_type) = "github.com/OffchainLabs/prysm/v7/consensus-types/primitives.ExecutionProofId" ]; // The slot of the beacon block this proof validates uint64 slot = 2 [ (ethereum.eth.ext.cast_type) = "github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Slot" ]; // The block hash of the execution payload this proof validates bytes block_hash = 3 [ (ethereum.eth.ext.ssz_size) = "32" ]; // The beacon block root corresponding to the beacon block // with the execution payload, that this proof attests to. bytes block_root = 4 [ (ethereum.eth.ext.ssz_size) = "32" ]; // The actual proof data bytes proof_data = 5 [ (ethereum.eth.ext.ssz_max) = "1048576" ]; } ``` - **`ExecutionProof`**: A core SSZ Container that is used in P2P, Proof Generation Service, etc. Defined as a proto message at `proto/prysm/v1alpha1/execution_proof.proto` ([Link](https://github.com/syjn99/prysm/blob/2d9e6ad2c8302b0045a4c6020f52e997c3f20bdf/proto/prysm/v1alpha1/execution_proof.proto)) and implemented corresponding SSZ-related methods (e.g., `MarshalSSZ`, `HashTreeRoot`) under the same directory. ## ✅ Cache - [x] Currently implemented in `zkvm-execution-layer/proof_cache.go` ([Link](https://github.com/syjn99/prysm/blob/2d9e6ad2c8302b0045a4c6020f52e997c3f20bdf/zkvm-execution-layer/proof_cache.go)) - [x] **would be better** to re-implement and move this under `beacon-chain/cache` ([Link](https://github.com/OffchainLabs/prysm/tree/develop/beacon-chain/cache)). See other cache examples under the directory. ## ✅ P2P > [!Note] > We assume all functionalities are enabled **after** Fulu. ### ✅ ENR: `"zkvm"` When a node activates zkVM mode by `--activate-zkvm`, it *explicitly* advertises by adding an entry for `zkvm`. - [x] Add `ZkvmKey` (= `zkvm`) under `NetworkConfig` in `config/params/network_config.go` - [x] Set zkVM entry in `updateSubnetRecordWithMetadataV3`. ### ✅ Gossip A node [subscribes](https://github.com/OffchainLabs/prysm/blob/2773bdef89ab460aea4353d4d98833a4eeaa4918/beacon-chain/sync/fork_watcher.go#L19) to each pubsub topic *after* chain starts. Note: Unlike the [specification](https://github.com/ethereum/consensus-specs/blob/master/specs/_features/eip8025/p2p-interface.md#topics-and-messages), current implementation has **one single global** topic `/eth2/{fork_digest}/execution_proof`. - [x] Add `ExecutionProofTopicFormat`(`/eth2/{fork_digest}/execution_proof`) under `beacon-chain/p2p/topics.go` - [x] Add `defaultExecutionProofTopicParams()` under `beacon-chain/p2p/gossip_scoring_params.go` - [x] Add `seenExecutionProofCache` and lock for the Sync service - [x] Add validation function (`validateExecutionProof()`) - [x] Add subscriber (`executionProofSubscriber`) - [x] Register the subscriber (`registerSubscribers`) ### ✅ RPC (Req/Resp) Handlers for P2P RPC are [registered](https://github.com/OffchainLabs/prysm/blob/2773bdef89ab460aea4353d4d98833a4eeaa4918/beacon-chain/sync/service.go#L383) when the Sync service starts. - [x] Add `RPCExecutionProofsByRootTopicV1` (`/eth2/beacon_chain/req/execution_proofs_by_root/1/`) under `beacon-chain/p2p/rpc_topic_mappings.go` - [x] Add an entry for `RPCTopicMappings` - [x] Add rate limiter for this (modification in `newRateLimiter`) - [x] Add handler - [x] Send request by block hash ## ✅ DA Check ```rust! // Check if this node needs execution proofs to validate blocks. // Nodes that have EL and generate proofs validate via EL execution. // Nodes that have EL but DON'T generate proofs are lightweight verifiers and wait for proofs. // TODO(zkproofs): This is a technicality mainly because we cannot remove the EL on kurtosis // ie each CL is coupled with an EL let needs_execution_proofs = spec.zkvm_min_proofs_required().is_some() && !has_execution_layer_and_proof_gen; if needs_execution_proofs { let min_proofs = spec.zkvm_min_proofs_required().unwrap(); let num_proofs = self.execution_proof_subnet_count(); if num_proofs < min_proofs { // Not enough execution proofs yet return Ok(None); } } ``` We need to add whether we've seen enough proofs. `ReceiveBlock` in `beacon-chain/blockchain/receive_block.go` is the core function when a block is received from gossip/rpc. ```go! func (s *Service) handleDA(ctx context.Context, avs das.AvailabilityStore, block blocks.ROBlock) (time.Duration, error) { var err error start := time.Now() if avs != nil { err = avs.IsDataAvailable(ctx, s.CurrentSlot(), block) } else { err = s.isDataAvailable(ctx, block) } elapsed := time.Since(start) if err == nil { dataAvailWaitedTime.Observe(float64(elapsed.Milliseconds())) } return elapsed, err } ``` For now, we can ignore `das.AvailabilityStore` and add proof availability logic in `isDataAvaiable`. ## ✅ Proof Generation Service - [x] Add skeleton under `beacon-chain/proof-generation` and register when zkVM mode is enabled. - [x] Generate execution proofs in altruistic manner when a block is imported. - [x] Check whether the proof generation is needed or not. - [x] Broadcast the proof via gossipsub. ## 📚 References - My current implementation: https://github.com/syjn99/prysm/pull/11 - Kev's implementation on Lighthouse: https://github.com/sigp/lighthouse/pull/8316 - Related write-up: https://hackmd.io/@kevaundray/BJeZCo5Tgx - Developeruche's initial implementation on Prysm: https://github.com/OffchainLabs/prysm/pull/16003 - Related write-up: https://hackmd.io/@0xdeveloperuche/rJyb-aEyWx - EIP-8025 Specification (Note: Spec is outdated): https://github.com/ethereum/consensus-specs/tree/master/specs/_features/eip8025