Skip to content

Commit e75a2de

Browse files
anylotschengwenxi
andauthored
Sync Prover mainnet fix (#821)
Co-authored-by: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
1 parent df65943 commit e75a2de

19 files changed

Lines changed: 125 additions & 118 deletions

File tree

prover/.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ shadow-proving
2424
contracts/cache
2525
contracts
2626
out
27-
lib
27+
lib
28+
29+
proof

prover/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

prover/bin/challenge/src/external_sign.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl ExternalSign {
8686
let req_data = self.craft_req_data(data, tx_info)?;
8787

8888
let rt = self.do_request(&self.url, &req_data).await?;
89-
log::debug!("ext_sign response: {:?}", rt);
89+
log::info!("ext_sign rt: {:?}", rt);
9090

9191
let response: Response = serde_json::from_str(&rt)?;
9292
if response.result.sign_datas.is_empty() {
@@ -97,6 +97,7 @@ impl ExternalSign {
9797
return Err("ext_sign response sign data invalid".into());
9898
}
9999

100+
100101
let sig = hex::decode(&response.result.sign_datas[0].sign[2..])?;
101102
let signed_tx: Bytes = tx.rlp_signed(&Signature::try_from(sig.as_slice())?);
102103
Ok(signed_tx)
@@ -139,8 +140,13 @@ impl ExternalSign {
139140
async fn do_request(&self, url: &str, payload: &ReqData) -> Result<String, Box<dyn Error>> {
140141
log::debug!("===payload: {:?}", serde_json::to_string(payload).unwrap());
141142
let response: reqwest::Response = self.client.post(url).json(&payload).send().await?;
142-
if !response.status().is_success() {
143-
return Err(format!("ext_sign response status not ok: {:?}", response.status()).into());
143+
log::info!("===do_request response: {:?}", response);
144+
145+
let status = response.status();
146+
if !status.is_success() {
147+
let text = response.text().await?;
148+
log::info!("===do_request response text: {:?}", &text);
149+
return Err(format!("ext_sign response status not ok: {:?}", status).into());
144150
}
145151
Ok(response.text().await?)
146152
}

prover/bin/challenge/src/handler.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use eyre::anyhow;
1212
use serde::{Deserialize, Serialize};
1313
use std::env::var;
1414
use std::error::Error;
15-
use std::ops::Mul;
1615
use std::str::FromStr;
1716
use std::sync::Arc;
1817
use std::time::Duration;
@@ -175,6 +174,7 @@ impl ChallengeHandler {
175174
if !batch_proof.proof_data.is_empty() {
176175
log::info!("query proof and prove state: {:#?}", batch_index);
177176
let batch_header = batch_info.fill_ext(batch_proof.batch_header.clone()).encode();
177+
sleep(Duration::from_secs(600)).await;
178178
self.prove_state(batch_index, batch_header, batch_proof, l1_rollup).await;
179179
continue;
180180
}
@@ -462,6 +462,8 @@ async fn batch_inspect(l1_rollup: &RollupType, l1_provider: &Provider<Http>, bat
462462
let withdrawal_root: [u8; 32] = param.batch_data_input.withdrawal_root;
463463
let last_block_number: u64 = param.batch_data_input.last_block_number;
464464
let num_l1_messages = param.batch_data_input.num_l1_messages;
465+
log::info!("======> batch inspect: decode tx.input, version = {:#?}", version);
466+
log::info!("======> batch inspect: decode tx.input, param = {:#?}", param);
465467

466468
let mut batch_info = BatchInfo {
467469
version,
@@ -574,4 +576,4 @@ pub fn contract_error<M: Middleware>(e: ContractError<M>) -> String {
574576
format!("error: {:?}", e)
575577
};
576578
error_msg
577-
}
579+
}

prover/bin/host/build.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.

prover/bin/host/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn prove(
3434

3535
// Prepare input.
3636
// Convert the traces' format to reduce conversion costs in the client.
37-
blocks.iter_mut().for_each(|blobk| blobk.flatten());
37+
blocks.iter_mut().for_each(|block| block.flatten());
3838
let client_input =
3939
ClientInput { l2_traces: blocks.clone(), blob_info: get_blob_info(blocks).unwrap() };
4040

prover/bin/server/src/queue.rs

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ impl Prover {
8686
if read_env_var("SAVE_TRACE", false) {
8787
save_trace(batch_index, block_traces);
8888
}
89-
save_batch_header(block_traces, batch_index);
89+
if !save_batch_header(block_traces, batch_index) {
90+
save_trace(batch_index, block_traces);
91+
continue;
92+
}
9093

9194
// Step3. Generate evm proof
9295
log::info!("Generate evm proof");
@@ -113,24 +116,40 @@ impl Prover {
113116
}
114117
}
115118

116-
fn save_batch_header(blocks: &mut Vec<BlockTrace>, batch_index: u64) {
117-
blocks.iter_mut().for_each(|blobk| blobk.flatten());
118-
let batch_info = EVMVerifier::verify(blocks).unwrap();
119-
let blob_info = morph_executor_host::get_blob_info(blocks).unwrap();
120-
let (versioned_hash, _) = BlobVerifier::verify(&blob_info, blocks.len()).unwrap();
121-
122-
// Save batch_header
123-
// | batch_data_hash | versioned_hash | sequencer_root |
124-
// |-----------------|----------------|----------------|
125-
// | bytes32 | bytes32 | bytes32 |
126-
let mut batch_header: Vec<u8> = Vec::with_capacity(96);
127-
batch_header.extend_from_slice(&batch_info.data_hash().0);
128-
batch_header.extend_from_slice(&versioned_hash.0);
129-
batch_header.extend_from_slice(&batch_info.sequencer_root().0);
119+
fn save_batch_header(blocks: &mut Vec<BlockTrace>, batch_index: u64) -> bool {
130120
let proof_dir = PROVER_PROOF_DIR.to_string() + format!("/batch_{}", batch_index).as_str();
131121
std::fs::create_dir_all(&proof_dir).expect("failed to create proof path");
132-
let mut batch_file = File::create(format!("{}/batch_header.data", proof_dir)).unwrap();
133-
batch_file.write_all(&batch_header[..]).expect("failed to batch_header");
122+
blocks.iter_mut().for_each(|block| block.flatten());
123+
let verify_result = EVMVerifier::verify(blocks);
124+
125+
if let Ok(batch_info) = verify_result {
126+
let blob_info = morph_executor_host::get_blob_info(blocks).unwrap();
127+
let (versioned_hash, _) = BlobVerifier::verify(&blob_info, blocks.len()).unwrap();
128+
129+
// Save batch_header
130+
// | batch_data_hash | versioned_hash | sequencer_root |
131+
// |-----------------|----------------|----------------|
132+
// | bytes32 | bytes32 | bytes32 |
133+
let mut batch_header: Vec<u8> = Vec::with_capacity(96);
134+
batch_header.extend_from_slice(&batch_info.data_hash().0);
135+
batch_header.extend_from_slice(&versioned_hash.0);
136+
batch_header.extend_from_slice(&batch_info.sequencer_root().0);
137+
let mut batch_file = File::create(format!("{}/batch_header.data", proof_dir)).unwrap();
138+
batch_file.write_all(&batch_header[..]).expect("failed to batch_header");
139+
true
140+
} else {
141+
let e = verify_result.unwrap_err();
142+
let error_data = serde_json::json!({
143+
"error_code": "EVM_EXECUTE_NOT_EXPECTED",
144+
"error_msg": e.to_string()
145+
});
146+
let mut batch_file = File::create(format!("{}/execute_result.json", proof_dir)).unwrap();
147+
batch_file
148+
.write_all(serde_json::to_string_pretty(&error_data).unwrap().as_bytes())
149+
.expect("failed to write error");
150+
log::error!("EVM verification failed for batch {}: {}", batch_index, e);
151+
false
152+
}
134153
}
135154

136155
fn save_proof(batch_index: u64, proof: EvmProofFixture) {
@@ -191,3 +210,19 @@ fn save_trace(batch_index: u64, chunk_traces: &Vec<BlockTrace>) {
191210
serde_json::to_writer_pretty(writer, &chunk_traces).unwrap();
192211
log::info!("chunk_traces of batch_index = {:#?} saved", batch_index);
193212
}
213+
214+
#[test]
215+
fn test_save_execute() {
216+
let batch_index = 102u64;
217+
218+
let mut blocks = load_trace("../../testdata/viridian/eip7702_traces.json");
219+
println!("blocks.len(): {:?}", blocks.len());
220+
let traces = blocks.first_mut().unwrap();
221+
222+
if !save_batch_header(traces, batch_index) {
223+
save_trace(batch_index, traces);
224+
println!("save_batch_header error");
225+
} else {
226+
println!("save_batch_header success");
227+
}
228+
}

prover/bin/server/src/server.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,31 @@ async fn query_proof(batch_index: String) -> ProveResult {
224224
.unwrap_or("nothing")
225225
.ends_with(format!("batch_{}", batch_index.trim()).as_str())
226226
{
227+
// execute_result
228+
let prove_result_path = path.join("execute_result.json");
229+
if prove_result_path.exists() {
230+
match fs::File::open(prove_result_path) {
231+
Ok(file) => {
232+
let reader = BufReader::new(file);
233+
let prove_result: serde_json::Value =
234+
serde_json::from_reader(reader).unwrap_or_default();
235+
if let Some(error_code) = prove_result.get("error_code") {
236+
result.error_code = error_code.as_str().unwrap_or("").to_string();
237+
}
238+
if let Some(error_msg) = prove_result.get("error_msg") {
239+
result.error_msg = error_msg.as_str().unwrap_or("").to_string();
240+
}
241+
}
242+
Err(e) => {
243+
log::error!("Failed to load prove_result: {:#?}", e);
244+
result.error_msg = String::from("Failed to load prove_result");
245+
}
246+
}
247+
}
248+
if !result.error_code.is_empty() {
249+
return result;
250+
}
251+
227252
//pi_batch_agg.data
228253
let proof_path = path.join("plonk_proof.json");
229254
if !proof_path.exists() {
@@ -261,7 +286,7 @@ async fn query_proof(batch_index: String) -> ProveResult {
261286
break;
262287
}
263288
}
264-
if result.proof_data.is_empty() {
289+
if result.proof_data.is_empty() && result.error_msg.is_empty() {
265290
result.error_msg = String::from("No proof was found");
266291
}
267292
result

prover/bin/shadow-prove/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ async fn main() {
7272
);
7373

7474
loop {
75-
sleep(Duration::from_secs(12)).await;
75+
sleep(Duration::from_secs(30)).await;
7676
// Sync & Prove
7777
let result = match batch_syncer.sync_batch().await {
7878
Ok(Some(batch)) => shadow_prover.prove(batch).await,

prover/bin/shadow-prove/src/shadow_prove.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ async fn handle_with_prover<T, P, N>(
110110

111111
// Query existing proof
112112
if let Some(prove_result) = query_proof(batch_index).await {
113+
if !prove_result.error_code.is_empty() {
114+
log::error!("query proof and prove state error, batch_index: {:?}, prove_result.error_code: {:?}, prove_result.error_msg: {:?}", batch_index, prove_result.error_code, prove_result.error_msg);
115+
break;
116+
}
113117
if !prove_result.proof_data.is_empty() {
114118
log::info!("query proof and prove state: {:?}", batch_index);
115119
prove_state(batch_index, l1_shadow_rollup).await;
@@ -160,6 +164,10 @@ async fn handle_with_prover<T, P, N>(
160164
max_waiting_time -= 300; // Query results every 5 minutes.
161165
match query_proof(batch_index).await {
162166
Some(prove_result) => {
167+
if !prove_result.error_code.is_empty() {
168+
log::error!("query proof and prove state error, batch_index: {:?}, prove_result.error_code: {:?}, prove_result.error_msg: {:?}", batch_index, prove_result.error_code, prove_result.error_msg);
169+
return;
170+
}
163171
log::debug!("query proof and prove state: {:#?}", batch_index);
164172
if !prove_result.proof_data.is_empty() {
165173
prove_state(batch_index, l1_shadow_rollup).await;

0 commit comments

Comments
 (0)