Skip to content

Commit c6761a4

Browse files
committed
test: Refactor code to fetch proofs from server
Refactor this code to fetch proofs from server so it can be used for other data as well, specifically to also fetch blk files containing block data.
1 parent daf4faa commit c6761a4

File tree

2 files changed

+207
-174
lines changed

2 files changed

+207
-174
lines changed

src/models/proof_abstractions/tasm/program.rs

Lines changed: 35 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -176,32 +176,28 @@ pub mod tests {
176176
use std::fs::create_dir_all;
177177
use std::fs::File;
178178
use std::io::stdout;
179-
use std::io::Read;
180179
use std::io::Write;
181180
use std::panic::catch_unwind;
182181
use std::path::Path;
183182
use std::path::PathBuf;
184-
use std::time::Duration;
185183
use std::time::SystemTime;
186184

187185
use itertools::Itertools;
188186
use macro_rules_attr::apply;
189-
use rand::seq::SliceRandom;
190187
use tasm_lib::triton_vm;
191188
use tracing::debug;
192-
use tracing::Span;
193189

194190
use super::*;
195191
use crate::models::blockchain::shared::Hash;
196192
use crate::models::blockchain::transaction::transaction_proof::TransactionProofType;
197193
use crate::models::proof_abstractions::tasm::environment;
198194
use crate::models::state::tx_proving_capability::TxProvingCapability;
195+
use crate::tests::shared::test_helper_data_dir;
196+
use crate::tests::shared::try_fetch_file_from_server;
197+
use crate::tests::shared::try_load_file_from_disk;
199198
use crate::tests::shared_tokio_runtime;
200199
use crate::triton_vm::stark::Stark;
201200

202-
const TEST_DATA_DIR: &str = "test_data";
203-
const TEST_NAME_HTTP_HEADER_KEY: &str = "Test-Name";
204-
205201
impl From<TritonVmJobPriority> for TritonVmProofJobOptions {
206202
fn from(job_priority: TritonVmJobPriority) -> Self {
207203
let job_settings = ProverJobSettings {
@@ -349,13 +345,31 @@ pub mod tests {
349345

350346
fn proof_path(claim: &Claim) -> PathBuf {
351347
let name = proof_filename(claim);
352-
let mut path = PathBuf::new();
353-
path.push(TEST_DATA_DIR);
348+
let mut path = test_helper_data_dir();
354349
path.push(Path::new(&name));
355350

356351
path
357352
}
358353

354+
/// Tries to load a proof for the claim from the test data directory
355+
fn try_load_proof_from_disk(claim: &Claim) -> Option<Proof> {
356+
let file_path = proof_path(claim);
357+
let file_contents = try_load_file_from_disk(&file_path)?;
358+
359+
let mut proof_data = vec![];
360+
for ch in file_contents.chunks(8) {
361+
if let Ok(eight_bytes) = TryInto::<[u8; 8]>::try_into(ch) {
362+
proof_data.push(BFieldElement::new(u64::from_be_bytes(eight_bytes)));
363+
} else {
364+
debug!("cannot cast chunk to eight bytes");
365+
return None;
366+
}
367+
}
368+
369+
let proof = Proof::from(proof_data);
370+
Some(proof)
371+
}
372+
359373
/// First, attempt to load the proof from disk. If it does not exist,
360374
/// attempt to fetch it online. If that also fails, run the prover and
361375
/// save the proof before returning it.
@@ -395,66 +409,6 @@ pub mod tests {
395409
}
396410
}
397411

398-
/// Tries to load a proof for the claim from the test data directory
399-
fn try_load_proof_from_disk(claim: &Claim) -> Option<Proof> {
400-
let path = proof_path(claim);
401-
let Ok(mut input_file) = File::open(path.clone()) else {
402-
debug!("cannot open file '{}' -- might not exist", path.display());
403-
return None;
404-
};
405-
let mut file_contents = vec![];
406-
if input_file.read_to_end(&mut file_contents).is_err() {
407-
debug!("cannot read file '{}'", path.display());
408-
return None;
409-
}
410-
let mut proof_data = vec![];
411-
for ch in file_contents.chunks(8) {
412-
if let Ok(eight_bytes) = TryInto::<[u8; 8]>::try_into(ch) {
413-
proof_data.push(BFieldElement::new(u64::from_be_bytes(eight_bytes)));
414-
} else {
415-
debug!("cannot cast chunk to eight bytes");
416-
return None;
417-
}
418-
}
419-
let proof = Proof::from(proof_data);
420-
Some(proof)
421-
}
422-
423-
/// Load a list of proof-servers from test data directory
424-
fn load_servers() -> Vec<String> {
425-
let mut server_list_path = PathBuf::new();
426-
server_list_path.push(TEST_DATA_DIR);
427-
server_list_path.push(Path::new("proof_servers").with_extension("txt"));
428-
let Ok(mut input_file) = File::open(server_list_path.clone()) else {
429-
debug!(
430-
"cannot proof-server list '{}' -- file might not exist",
431-
server_list_path.display()
432-
);
433-
return vec![];
434-
};
435-
let mut file_contents = vec![];
436-
if input_file.read_to_end(&mut file_contents).is_err() {
437-
debug!("cannot read file '{}'", server_list_path.display());
438-
return vec![];
439-
}
440-
let Ok(file_as_string) = String::from_utf8(file_contents) else {
441-
debug!(
442-
"cannot parse file '{}' -- is it valid utf8?",
443-
server_list_path.display()
444-
);
445-
return vec![];
446-
};
447-
file_as_string.lines().map(|s| s.to_string()).collect()
448-
}
449-
450-
#[test]
451-
fn test_load_servers() {
452-
let servers = load_servers();
453-
for server in servers {
454-
println!("read server: {}", server);
455-
}
456-
}
457-
458412
/// Queries known servers for proofs.
459413
///
460414
/// The proof-servers file is located in `proof_servers.txt` test data
@@ -481,113 +435,21 @@ pub mod tests {
481435
/// not store the proof to disk.
482436
/// TODO: Consider making this async.
483437
fn try_fetch_from_server_inner(filename: String) -> Option<(Proof, String)> {
484-
fn get_test_name_from_tracing() -> String {
485-
match Span::current().metadata().map(|x| x.name()) {
486-
Some(test_name) => test_name.to_owned(),
487-
None => "unknown".to_owned(),
488-
}
489-
}
490-
491-
fn attempt_to_get_test_name() -> String {
492-
let thread = std::thread::current();
493-
match thread.name() {
494-
Some(test_name) => {
495-
if test_name.eq("tokio-runtime-worker") {
496-
get_test_name_from_tracing()
497-
} else {
498-
test_name.to_owned()
499-
}
500-
}
501-
None => get_test_name_from_tracing(),
502-
}
503-
}
504-
505-
let mut servers = load_servers();
506-
servers.shuffle(&mut rand::rng());
507-
508-
// Add test name to request allow server to see which test requires a proof
509-
let mut headers = clienter::HttpHeaders::default();
510-
headers.insert(
511-
TEST_NAME_HTTP_HEADER_KEY.to_string(),
512-
attempt_to_get_test_name(),
513-
);
438+
let (file_contents, server) = try_fetch_file_from_server(filename)?;
514439

515-
for server in servers {
516-
let server_ = server.clone();
517-
let filename_ = filename.clone();
518-
let headers_ = headers.clone();
519-
let handle = std::thread::spawn(move || {
520-
let url = format!("{}{}", server_, filename_);
521-
522-
debug!("requesting: <{url}>");
523-
524-
let uri: clienter::Uri = url.into();
525-
526-
let mut http_client = clienter::HttpClient::new();
527-
http_client.timeout = Some(Duration::from_secs(10));
528-
http_client.headers = headers_;
529-
let request = http_client.request(clienter::HttpMethod::GET, uri);
530-
531-
// note: send() blocks
532-
let Ok(mut response) = http_client.send(&request) else {
533-
println!(
534-
"server '{}' failed for file '{}'; trying next ...",
535-
server_.clone(),
536-
filename_
537-
);
538-
539-
return None;
540-
};
541-
542-
// only retrieve body if we got a 2xx code.
543-
// addresses #477
544-
// https://github.com/Neptune-Crypto/neptune-core/issues/477
545-
let body = if response.status.is_success() {
546-
response.body()
547-
} else {
548-
Ok(vec![])
549-
};
550-
551-
Some((response.status, body))
552-
});
553-
554-
let Some((status_code, body)) = handle.join().unwrap() else {
555-
eprintln!("Could not connect to server {server}.");
556-
continue;
557-
};
558-
559-
if !status_code.is_success() {
560-
eprintln!("{server} responded with {status_code}");
561-
continue;
562-
}
563-
564-
let Ok(file_contents) = body else {
565-
eprintln!(
566-
"error reading file '{}' from server '{}'; trying next ...",
567-
filename, server
568-
);
569-
570-
continue;
571-
};
572-
573-
let mut proof_data = vec![];
574-
for ch in file_contents.chunks(8) {
575-
if let Ok(eight_bytes) = TryInto::<[u8; 8]>::try_into(ch) {
576-
proof_data.push(BFieldElement::new(u64::from_be_bytes(eight_bytes)));
577-
} else {
578-
eprintln!("cannot cast chunk to eight bytes. Server was: {server}");
579-
}
440+
let mut proof_data = vec![];
441+
for ch in file_contents.chunks(8) {
442+
if let Ok(eight_bytes) = TryInto::<[u8; 8]>::try_into(ch) {
443+
proof_data.push(BFieldElement::new(u64::from_be_bytes(eight_bytes)));
444+
} else {
445+
eprintln!("cannot cast chunk to eight bytes. Server was: {server}");
580446
}
581-
582-
let proof = Proof::from(proof_data);
583-
println!("got proof.");
584-
585-
return Some((proof, server));
586447
}
587448

588-
println!("No known servers serve file `{}`", filename);
449+
let proof = Proof::from(proof_data);
450+
println!("got proof.");
589451

590-
None
452+
Some((proof, server))
591453
}
592454

593455
#[apply(shared_tokio_runtime)]
@@ -622,10 +484,9 @@ pub mod tests {
622484
nondeterminism: NonDeterminism,
623485
) -> Proof {
624486
let name = proof_filename(claim);
625-
let mut path = PathBuf::new();
626-
path.push(TEST_DATA_DIR);
487+
let mut path = test_helper_data_dir();
627488
create_dir_all(&path)
628-
.unwrap_or_else(|_| panic!("cannot create '{TEST_DATA_DIR}' directory"));
489+
.unwrap_or_else(|_| panic!("cannot create '{}' directory", path.to_string_lossy()));
629490
path.push(Path::new(&name));
630491

631492
let proof: Proof = triton_vm::prove(Stark::default(), claim, program, nondeterminism)

0 commit comments

Comments
 (0)