Skip to content

Commit d36b40c

Browse files
committed
Add risc0 to task sender
1 parent 7e2161c commit d36b40c

File tree

2 files changed

+162
-63
lines changed

2 files changed

+162
-63
lines changed

crates/task-sender/src/commands.rs

Lines changed: 124 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use tokio::join;
1919
use tokio_tungstenite::connect_async;
2020

2121
use crate::structs::{
22-
GenerateAndFundWalletsArgs, GenerateProofsArgs, ProofType, SendInfiniteProofsArgs,
22+
GenerateAndFundWalletsArgs, GenerateProofsArgs, InfiniteProofType, ProofType, SendInfiniteProofsArgs,
2323
TestConnectionsArgs,
2424
};
2525

@@ -253,81 +253,60 @@ struct Sender {
253253
wallet: Wallet<SigningKey>,
254254
}
255255

256-
pub async fn send_infinite_proofs(args: SendInfiniteProofsArgs) {
257-
if matches!(args.network.clone().into(), Network::Holesky) {
258-
error!("Network not supported this infinite proof sender");
259-
return;
260-
}
256+
async fn load_senders_from_file(
257+
eth_rpc_url: &str,
258+
private_keys_filepath: &str,
259+
) -> Result<Vec<Sender>, String> {
260+
let eth_rpc_provider = Provider::<Http>::try_from(eth_rpc_url)
261+
.map_err(|_| "Could not connect to eth rpc".to_string())?;
262+
let chain_id = eth_rpc_provider
263+
.get_chainid()
264+
.await
265+
.map_err(|_| "Could not get chain id".to_string())?;
261266

262-
info!("Loading wallets");
263-
let mut senders = vec![];
264-
let Ok(eth_rpc_provider) = Provider::<Http>::try_from(args.eth_rpc_url.clone()) else {
265-
error!("Could not connect to eth rpc");
266-
return;
267-
};
268-
let Ok(chain_id) = eth_rpc_provider.get_chainid().await else {
269-
error!("Could not get chain id");
270-
return;
271-
};
272-
273-
let file = match File::open(&args.private_keys_filepath) {
274-
Ok(file) => file,
275-
Err(err) => {
276-
error!("Could not open private keys file: {}", err);
277-
return;
278-
}
279-
};
267+
let file = File::open(private_keys_filepath)
268+
.map_err(|err| format!("Could not open private keys file: {}", err))?;
280269

281270
let reader = BufReader::new(file);
271+
let mut senders = vec![];
282272

283-
// now here we need to load the senders from the provided files
284273
for line in reader.lines() {
285-
let private_key_str = match line {
286-
Ok(line) => line,
287-
Err(err) => {
288-
error!("Could not read line from private keys file: {}", err);
289-
return;
290-
}
291-
};
292-
let wallet = Wallet::from_str(private_key_str.trim()).expect("Invalid private key");
293-
let wallet = wallet.with_chain_id(chain_id.as_u64());
274+
let private_key_str = line
275+
.map_err(|err| format!("Could not read line from private keys file: {}", err))?;
276+
let wallet = Wallet::from_str(private_key_str.trim())
277+
.map_err(|_| "Invalid private key".to_string())?
278+
.with_chain_id(chain_id.as_u64());
294279
let sender = Sender { wallet };
295-
296-
// info!("Wallet {} loaded", i);
297280
senders.push(sender);
298281
}
299282

300283
if senders.is_empty() {
301-
error!("No wallets in file");
302-
return;
303-
}
304-
info!("All wallets loaded");
305-
306-
info!("Loading proofs verification data");
307-
let verification_data =
308-
get_verification_data_from_proofs_folder(args.proofs_dir, senders[0].wallet.address());
309-
if verification_data.is_empty() {
310-
error!("Verification data empty, not continuing");
311-
return;
284+
return Err("No wallets in file".to_string());
312285
}
313-
info!("Proofs loaded!");
314286

315-
let max_fee = U256::from_dec_str(&args.max_fee).expect("Invalid max fee");
287+
Ok(senders)
288+
}
316289

290+
async fn run_infinite_proof_sender(
291+
senders: Vec<Sender>,
292+
verification_data: Vec<VerificationData>,
293+
network: Network,
294+
burst_size: usize,
295+
burst_time_secs: u64,
296+
max_fee: U256,
297+
random_address: bool,
298+
) {
317299
let mut handles = vec![];
318-
let network: Network = args.network.into();
319-
info!("Starting senders!");
300+
320301
for (i, sender) in senders.iter().enumerate() {
321-
// this clones are necessary because of the move
322302
let wallet = sender.wallet.clone();
323303
let verification_data = verification_data.clone();
324304
let network_clone = network.clone();
325305

326-
// a thread to send tasks from each loaded wallet:
327306
let handle = tokio::spawn(async move {
328307
loop {
329308
let n = network_clone.clone();
330-
let mut result = Vec::with_capacity(args.burst_size);
309+
let mut result = Vec::with_capacity(burst_size);
331310
let nonce = get_nonce_from_batcher(n.clone(), wallet.address())
332311
.await
333312
.inspect_err(|e| {
@@ -338,16 +317,25 @@ pub async fn send_infinite_proofs(args: SendInfiniteProofsArgs) {
338317
)
339318
})
340319
.unwrap();
341-
while result.len() < args.burst_size {
320+
while result.len() < burst_size {
342321
let samples = verification_data
343-
.choose_multiple(&mut thread_rng(), args.burst_size - result.len());
344-
result.extend(samples.cloned());
322+
.choose_multiple(&mut thread_rng(), burst_size - result.len());
323+
for mut sample in samples.cloned() {
324+
// Randomize proof generator address if requested
325+
if random_address {
326+
sample.proof_generator_addr = Address::random();
327+
} else if sample.proof_generator_addr == Address::zero() {
328+
// If it was set to zero (template), use wallet address
329+
sample.proof_generator_addr = wallet.address();
330+
}
331+
result.push(sample);
332+
}
345333
}
346334
let verification_data_to_send = result;
347335

348336
info!(
349337
"Sending {:?} Proofs to Aligned Batcher on {:?} from sender {}, nonce: {}, address: {:?}",
350-
args.burst_size, n, i, nonce, wallet.address(),
338+
burst_size, n, i, nonce, wallet.address(),
351339
);
352340

353341
let aligned_verification_data = submit_multiple(
@@ -374,7 +362,7 @@ pub async fn send_infinite_proofs(args: SendInfiniteProofsArgs) {
374362
}
375363
info!("All responses received for sender {}", i);
376364

377-
tokio::time::sleep(Duration::from_secs(args.burst_time_secs)).await;
365+
tokio::time::sleep(Duration::from_secs(burst_time_secs)).await;
378366
}
379367
});
380368

@@ -386,6 +374,82 @@ pub async fn send_infinite_proofs(args: SendInfiniteProofsArgs) {
386374
}
387375
}
388376

377+
pub async fn send_infinite_proofs(args: SendInfiniteProofsArgs) {
378+
if matches!(args.network.clone().into(), Network::Holesky) {
379+
error!("Network not supported this infinite proof sender");
380+
return;
381+
}
382+
383+
// Load wallets using shared function
384+
info!("Loading wallets");
385+
let senders = match load_senders_from_file(&args.eth_rpc_url, &args.private_keys_filepath).await {
386+
Ok(senders) => senders,
387+
Err(err) => {
388+
error!("{}", err);
389+
return;
390+
}
391+
};
392+
info!("All wallets loaded");
393+
394+
// Load verification data based on proof type
395+
let verification_data = match &args.proof_type {
396+
InfiniteProofType::GnarkGroth16 { proofs_dir } => {
397+
info!("Loading Groth16 proofs from directory structure");
398+
let data = get_verification_data_from_proofs_folder(
399+
proofs_dir.clone(),
400+
senders[0].wallet.address()
401+
);
402+
if data.is_empty() {
403+
error!("Verification data empty, not continuing");
404+
return;
405+
}
406+
data
407+
}
408+
InfiniteProofType::Risc0 { proof_path, bin_path, pub_path } => {
409+
info!("Loading RISC Zero proof files");
410+
let Ok(proof) = std::fs::read(proof_path) else {
411+
error!("Could not read proof file: {}", proof_path);
412+
return;
413+
};
414+
let Ok(vm_program) = std::fs::read(bin_path) else {
415+
error!("Could not read bin file: {}", bin_path);
416+
return;
417+
};
418+
let pub_input = if let Some(pub_path) = pub_path {
419+
std::fs::read(pub_path).ok()
420+
} else {
421+
None
422+
};
423+
424+
// Create template verification data (without proof_generator_addr)
425+
vec![VerificationData {
426+
proving_system: ProvingSystemId::Risc0,
427+
proof,
428+
pub_input,
429+
verification_key: None,
430+
vm_program_code: Some(vm_program),
431+
proof_generator_addr: Address::zero(), // Will be set randomly in the loop
432+
}]
433+
}
434+
};
435+
436+
info!("Proofs loaded!");
437+
438+
let max_fee = U256::from_dec_str(&args.max_fee).expect("Invalid max fee");
439+
let network: Network = args.network.into();
440+
441+
info!("Starting senders!");
442+
run_infinite_proof_sender(
443+
senders,
444+
verification_data,
445+
network,
446+
args.burst_size,
447+
args.burst_time_secs,
448+
max_fee,
449+
args.random_address,
450+
).await;
451+
}
452+
389453
/// Returns the corresponding verification data for the generated proofs directory
390454
fn get_verification_data_from_proofs_folder(
391455
dir_path: String,
@@ -448,3 +512,4 @@ fn get_verification_data_from_proofs_folder(
448512

449513
verifications_data
450514
}
515+

crates/task-sender/src/structs.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,47 @@ pub struct SendInfiniteProofsArgs {
126126
)]
127127
pub private_keys_filepath: String,
128128
#[arg(
129-
name = "The generated proofs directory",
130-
long = "proofs-dirpath",
131-
default_value = "devnet"
129+
name = "Use random addresses for proof generator",
130+
long = "random-address",
131+
action = clap::ArgAction::SetTrue
132132
)]
133-
pub proofs_dir: String,
133+
pub random_address: bool,
134+
#[clap(subcommand)]
135+
pub proof_type: InfiniteProofType,
134136
}
135137

138+
#[derive(Parser, Debug)]
139+
pub enum InfiniteProofType {
140+
#[clap(about = "Send infinite Gnark Groth16 proofs from directory")]
141+
GnarkGroth16 {
142+
#[arg(
143+
name = "The generated proofs directory",
144+
long = "proofs-dir",
145+
default_value = "scripts/test_files/task_sender/proofs"
146+
)]
147+
proofs_dir: String,
148+
},
149+
#[clap(about = "Send infinite RISC Zero proofs from file paths")]
150+
Risc0 {
151+
#[arg(
152+
name = "Path to RISC Zero proof file (.proof)",
153+
long = "proof-path"
154+
)]
155+
proof_path: String,
156+
#[arg(
157+
name = "Path to RISC Zero binary file (.bin)",
158+
long = "bin-path"
159+
)]
160+
bin_path: String,
161+
#[arg(
162+
name = "Path to RISC Zero public input file (.pub) - optional",
163+
long = "pub-path"
164+
)]
165+
pub_path: Option<String>,
166+
},
167+
}
168+
169+
136170
#[derive(Debug, Clone, Copy)]
137171
enum NetworkNameArg {
138172
Devnet,

0 commit comments

Comments
 (0)