Skip to content

Commit 5c27731

Browse files
ManuelBilbaojrchatrucilitteri
authored
chore(l2): separete ProverServer and ProofSender (#2478)
**Motivation** <!-- Why does this pull request exist? What are its goals? --> Currently the ProverServer component have the responsibility for both act as a server for the ProverClient (i.e., send blocks to prove and receive proofs) and send proofs to the L1 contract to verify blocks. This tasks can be parallel and decoupled one from the other. **Description** <!-- A clear and concise general description of the changes this PR introduces --> A new struct `L1ProofSender` is created that periodically checks if there're new proofs to send to the L1, removing that job from the `ProverServer`. Also, components were renamed for better clarity. Note that the config names were not changed as there's a WIP PR (#2501) doing a full refactor of it <!-- Link to issues: Resolves #111, Resolves #222 --> --------- Co-authored-by: Javier Rodríguez Chatruc <49622509+jrchatruc@users.noreply.github.com> Co-authored-by: Javier Chatruc <jrchatruc@gmail.com> Co-authored-by: Ivan Litteri <67517699+ilitteri@users.noreply.github.com>
1 parent 7de4cda commit 5c27731

File tree

20 files changed

+630
-654
lines changed

20 files changed

+630
-654
lines changed

crates/l2/Makefile

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ down: down-local-l1 down-l2 down-metrics## 🛑 Shuts down the localnet
2121

2222
clean: clean-contract-deps ## 🧹 Cleans the localnet
2323

24-
restart: restart-local-l1 deploy-l1 restart-l2 ## 🔄 Restarts the localnet
24+
restart: restart-local-l1 deploy-l1 purge_prover_state restart-l2 ## 🔄 Restarts the localnet
2525

2626
## Same as restart but for testnet deployment. The local database is cleaned and the contracts are deployed again.
2727
restart-testnet:
@@ -243,10 +243,5 @@ else
243243
endif
244244

245245
purge_prover_state: ## 🧹 Removes the L2 state, only use to start fresh.
246-
@echo "Are you sure you want to delete the directory: $(PROJECT_PATH) ? [y/n]"
247-
@read answer; \
248-
if [ "$$answer" != "y" ]; then \
249-
echo "Operation canceled."; \
250-
fi; \
251246
rm -rf $(PROJECT_PATH); \
252247
echo "Directory deleted."

crates/l2/configs/sequencer_config_example.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ l1_private_key = "0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45
4949
# Set it to 0.0.0.0 to allow connections from other machines.
5050
listen_ip = "127.0.0.1"
5151
listen_port = 3900
52+
proof_send_interval_ms = 5000
5253
dev_mode = true

crates/l2/docs/prover.md

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,26 @@
2020
2121
## What
2222

23-
The prover consists of two main components: handling incoming proving data from the `L2 proposer`, specifically the `prover_server` component, and the `zkVM`. The `prover_client` is responsible for this first part, while the `zkVM` serves as a RISC-V emulator executing code specified in `crates/l2/prover/zkvm/interface/guest/src`.
23+
The prover consists of two main components: handling incoming proving data from the `L2 proposer`, specifically from the `ProofCoordinator` component, and the `zkVM`. The `Prover` is responsible for this first part, while the `zkVM` serves as a RISC-V emulator executing code specified in `crates/l2/prover/zkvm/interface/guest/src`.
2424
Before the `zkVM` code (or guest), there is a directory called `interface`, which indicates that we access the `zkVM` through the "interface" crate.
2525

26-
In summary, the `prover_client` manages the inputs from the `prover_server` and then "calls" the `zkVM` to perform the proving process and generate the `groth16` ZK proof.
26+
In summary, the `Prover` manages the inputs from the `ProofCoordinator` and then "calls" the `zkVM` to perform the proving process and generate the `groth16` ZK proof.
2727

2828
## Workflow
2929

30-
The `Prover Server` monitors requests for new jobs from the `Prover Client`, which are sent when the prover is available. Upon receiving a new job, the Prover generates the proof, after which the `Prover Client` sends the proof back to the `Prover Server`.
30+
The `ProofCoordinator` monitors requests for new jobs from the `Prover`, which are sent when the prover is available. Upon receiving a new job, the Prover generates the proof, after which the `Prover` sends the proof back to the `ProofCoordinator`.
3131

3232
```mermaid
3333
sequenceDiagram
3434
participant zkVM
35-
participant ProverClient
36-
participant ProverServer
37-
ProverClient->>+ProverServer: ProofData::Request
38-
ProverServer-->>-ProverClient: ProofData::Response(block_number, ProverInputs)
39-
ProverClient->>+zkVM: Prove(ProverInputs)
40-
zkVM-->>-ProverClient: Creates zkProof
41-
ProverClient->>+ProverServer: ProofData::Submit(block_number, zkProof)
42-
ProverServer-->>-ProverClient: ProofData::SubmitAck(block_number)
35+
participant Prover
36+
participant ProofCoordinator
37+
Prover->>+ProofCoordinator: ProofData::Request
38+
ProofCoordinator-->>-Prover: ProofData::Response(block_number, ProverInputs)
39+
Prover->>+zkVM: Prove(ProverInputs)
40+
zkVM-->>-Prover: Creates zkProof
41+
Prover->>+ProofCoordinator: ProofData::Submit(block_number, zkProof)
42+
ProofCoordinator-->>-Prover: ProofData::SubmitAck(block_number)
4343
```
4444

4545
## How
@@ -76,7 +76,7 @@ Then run any of the targets:
7676

7777
### Dev Mode
7878

79-
To run the blockchain (`proposer`) and prover in conjunction, start the `prover_client`, use the following command:
79+
To run the blockchain (`proposer`) and prover in conjunction, start the `Prover`, use the following command:
8080

8181
```sh
8282
make init-prover T="prover_type (pico,risc0,sp1) G=true"
@@ -137,12 +137,12 @@ Then run any of the targets:
137137

138138
#### Run the whole system with a GPU Prover
139139

140-
Two servers are required: one for the `prover` and another for the `proposer`. If you run both components on the same machine, the `prover` may consume all available resources, leading to potential stuttering or performance issues for the `proposer`/`node`.
140+
Two servers are required: one for the `Prover` and another for the `sequencer`. If you run both components on the same machine, the `Prover` may consume all available resources, leading to potential stuttering or performance issues for the `sequencer`/`node`.
141141

142-
- The number 1 simbolizes a machine with GPU for the `prover_client`.
142+
- The number 1 simbolizes a machine with GPU for the `Prover`.
143143
- The number 2 simbolizes a machine for the `sequencer`/L2 node itself.
144144

145-
1. `prover_client`/`zkvm` &rarr; prover with gpu, make sure to have all the required dependencies described at the beginning of [Gpu Mode](#gpu-mode) section.
145+
1. `Prover`/`zkvm` &rarr; prover with gpu, make sure to have all the required dependencies described at the beginning of [Gpu Mode](#gpu-mode) section.
146146
1. `cd ethrex/crates/l2`
147147
2. `cp configs/prover_client_config_example.toml configs/prover_client_config.toml` and change the `prover_server_endpoint` with machine's `2` ip and make sure the port matches the one defined in machine 2.
148148

@@ -153,10 +153,10 @@ The important variables are:
153153
prover_server_endpoint=<ip-address>:3900
154154
```
155155

156-
- `Finally`, to start the `prover_client`/`zkvm`, run:
156+
- `Finally`, to start the `Prover`/`zkvm`, run:
157157
- `make init-prover T=(sp1,risc0,pico) G=true`
158158

159-
2. `prover_server`/`proposer` &rarr; this server just needs rust installed.
159+
2. `ProofCoordinator`/`sequencer` &rarr; this server just needs rust installed.
160160
1. `cd ethrex/crates/l2`
161161
2. `cp configs/sequencer_config_example.toml configs/sequencer_config.toml` and change the addresses and the following fields:
162162
- [prover_server]
@@ -184,14 +184,12 @@ prover_server_endpoint=<ip-address>:3900
184184

185185
## Configuration
186186

187-
Configuration is done through environment variables. The easiest way to configure the ProverClient is by creating a `prover_client_config.toml` file and setting the variables there. Then, at start, it will read the file and set the variables.
187+
Configuration is done through environment variables. The easiest way to configure the `Prover` is by creating a `prover_client_config.toml` file and setting the variables there. Then, at start, it will read the file and set the variables.
188188

189-
The following environment variables are available to configure the Proposer consider looking at the provided [prover_client_config_example.toml](../configs/prover_client_config_example.toml):
190-
191-
The following environment variables are used by the ProverClient:
189+
The following environment variables are available to configure the `Prover`, consider looking at the provided [prover_client_config_example.toml](../configs/prover_client_config_example.toml):
192190

193191
- `CONFIGS_PATH`: The path where the `PROVER_CLIENT_CONFIG_FILE` is located at.
194-
- `PROVER_CLIENT_CONFIG_FILE`: The `.toml` that contains the config for the `prover_client`.
192+
- `PROVER_CLIENT_CONFIG_FILE`: The `.toml` that contains the config for the `Prover`.
195193
- `PROVER_ENV_FILE`: The name of the `.env` that has the parsed `.toml` configuration.
196194
- `PROVER_CLIENT_PROVER_SERVER_ENDPOINT`: Prover Server's Endpoint used to connect the Client to the Server.
197195

crates/l2/prover/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
pub mod backends;
22
pub mod errors;
3-
pub mod prover_client;
3+
pub mod prover;
44

5-
use ethrex_l2::utils::config::prover_client::ProverClientConfig;
5+
use ethrex_l2::utils::config::prover::ProverConfig;
66
use tracing::warn;
77

8-
pub async fn init_client(config: ProverClientConfig) {
9-
prover_client::start_proof_data_client(config).await;
8+
pub async fn init_client(config: ProverConfig) {
9+
prover::start_prover(config).await;
1010
warn!("Prover finished!");
1111
}
1212

crates/l2/prover/src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use ethrex_l2::utils::config::{
2-
prover_client::ProverClientConfig, read_env_file_by_config, toml_parser::parse_configs,
3-
ConfigMode,
2+
prover::ProverConfig, read_env_file_by_config, toml_parser::parse_configs, ConfigMode,
43
};
54
use ethrex_prover_lib::init_client;
65
use tracing::{self, debug, error, Level};
@@ -26,7 +25,7 @@ async fn main() {
2625
return;
2726
}
2827

29-
let Ok(config) = ProverClientConfig::from_env() else {
28+
let Ok(config) = ProverConfig::from_env() else {
3029
error!("Failed to read ProverClientConfig from .env file. It is '.env.prover' by default");
3130
return;
3231
};

crates/l2/prover/src/prover_client.rs renamed to crates/l2/prover/src/prover.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{prove, to_calldata};
22
use ethrex_l2::{
3-
sequencer::prover_server::ProofData,
4-
utils::{config::prover_client::ProverClientConfig, prover::proving_systems::ProofCalldata},
3+
sequencer::proof_coordinator::ProofData,
4+
utils::{config::prover::ProverConfig, prover::proving_systems::ProofCalldata},
55
};
66
use std::time::Duration;
77
use tokio::{
@@ -12,23 +12,23 @@ use tokio::{
1212
use tracing::{debug, error, info, warn};
1313
use zkvm_interface::io::ProgramInput;
1414

15-
pub async fn start_proof_data_client(config: ProverClientConfig) {
16-
let proof_data_client = ProverClient::new(config);
17-
proof_data_client.start().await;
15+
pub async fn start_prover(config: ProverConfig) {
16+
let prover_worker = Prover::new(config);
17+
prover_worker.start().await;
1818
}
1919

2020
struct ProverData {
2121
block_number: u64,
2222
input: ProgramInput,
2323
}
2424

25-
struct ProverClient {
25+
struct Prover {
2626
prover_server_endpoint: String,
2727
proving_time_ms: u64,
2828
}
2929

30-
impl ProverClient {
31-
pub fn new(config: ProverClientConfig) -> Self {
30+
impl Prover {
31+
pub fn new(config: ProverConfig) -> Self {
3232
Self {
3333
prover_server_endpoint: config.prover_server_endpoint,
3434
proving_time_ms: config.proving_time_ms,
@@ -66,13 +66,13 @@ impl ProverClient {
6666

6767
async fn request_new_input(&self) -> Result<ProverData, String> {
6868
// Request the input with the correct block_number
69-
let request = ProofData::request();
69+
let request = ProofData::block_request();
7070
let response = connect_to_prover_server_wr(&self.prover_server_endpoint, &request)
7171
.await
7272
.map_err(|e| format!("Failed to get Response: {e}"))?;
7373

7474
match response {
75-
ProofData::Response {
75+
ProofData::BlockResponse {
7676
block_number,
7777
input,
7878
} => match (block_number, input) {
@@ -102,14 +102,14 @@ impl ProverClient {
102102
block_number: u64,
103103
proving_output: ProofCalldata,
104104
) -> Result<(), String> {
105-
let submit = ProofData::submit(block_number, proving_output);
105+
let submit = ProofData::proof_submit(block_number, proving_output);
106106

107107
let submit_ack = connect_to_prover_server_wr(&self.prover_server_endpoint, &submit)
108108
.await
109109
.map_err(|e| format!("Failed to get SubmitAck: {e}"))?;
110110

111111
match submit_ack {
112-
ProofData::SubmitAck { block_number } => {
112+
ProofData::ProofSubmitACK { block_number } => {
113113
info!("Received submit ack for block_number: {}", block_number);
114114
Ok(())
115115
}

crates/l2/sequencer/errors.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::utils::config::errors::ConfigError;
22
use crate::utils::error::UtilsError;
33
use crate::utils::prover::errors::SaveStateError;
4+
use crate::utils::prover::proving_systems::ProverType;
45
use ethereum_types::FromStrRadixErr;
56
use ethrex_blockchain::error::{ChainError, InvalidForkChoice};
67
use ethrex_common::types::{BlobsBundleError, FakeExponentialError};
@@ -60,6 +61,20 @@ pub enum ProverServerError {
6061
JsonError(#[from] serde_json::Error),
6162
}
6263

64+
#[derive(Debug, thiserror::Error)]
65+
pub enum ProofSenderError {
66+
#[error("Failed because of an EthClient error: {0}")]
67+
EthClientError(#[from] EthClientError),
68+
#[error("Failed to encode calldata: {0}")]
69+
CalldataEncodeError(#[from] CalldataEncodeError),
70+
#[error("Failed with a SaveStateError: {0}")]
71+
SaveStateError(#[from] SaveStateError),
72+
#[error("{0} proof is not present")]
73+
ProofNotPresent(ProverType),
74+
#[error("Unexpected Error: {0}")]
75+
InternalError(String),
76+
}
77+
6378
#[derive(Debug, thiserror::Error)]
6479
pub enum BlockProducerError {
6580
#[error("Block Producer failed because of an EngineClient error: {0}")]

0 commit comments

Comments
 (0)