@@ -19,7 +19,7 @@ use tokio::join;
1919use tokio_tungstenite:: connect_async;
2020
2121use 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
390454fn 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+
0 commit comments