@@ -43,6 +43,12 @@ pub mod sp1;
4343pub mod types;
4444mod zk_utils;
4545
46+ const AGGREGATOR_COST : u128 = 400000 ;
47+ const BATCHER_SUBMISSION_BASE_COST : u128 = 100000 ;
48+ const ADDITIONAL_SUBMISSION_COST_PER_PROOF : u128 = 13_000 ;
49+ const CONSTANT_COST : u128 = AGGREGATOR_COST + BATCHER_SUBMISSION_BASE_COST ;
50+ const MIN_BALANCE_PER_PROOF : u128 = ADDITIONAL_SUBMISSION_COST_PER_PROOF * 100_000_000_000 ; // 100 Gwei = 0.0000001 ether (high gas price)
51+
4652pub struct Batcher {
4753 s3_client : S3Client ,
4854 s3_bucket_name : String ,
@@ -57,6 +63,7 @@ pub struct Batcher {
5763 pre_verification_is_enabled : bool ,
5864 non_paying_config : Option < NonPayingConfig > ,
5965 user_nonces : Mutex < HashMap < Address , U256 > > ,
66+ user_proof_count_in_batch : Mutex < HashMap < Address , u64 > > ,
6067}
6168
6269impl Batcher {
@@ -120,6 +127,7 @@ impl Batcher {
120127 pre_verification_is_enabled : config. batcher . pre_verification_is_enabled ,
121128 non_paying_config,
122129 user_nonces,
130+ user_proof_count_in_batch : Mutex :: new ( HashMap :: new ( ) ) ,
123131 }
124132 }
125133
@@ -211,16 +219,14 @@ impl Batcher {
211219 . handle_nonpaying_msg ( ws_conn_sink. clone ( ) , client_msg)
212220 . await ;
213221 } else {
214- let user_balance = self . get_user_balance ( & addr) . await ;
215-
216- if user_balance == U256 :: from ( 0 ) {
217- error ! ( "Insufficient funds for address {:?}" , addr) ;
222+ if !self . check_user_balance ( & addr) . await {
218223 send_error_message (
219224 ws_conn_sink. clone ( ) ,
220225 ResponseMessage :: InsufficientBalanceError ( addr) ,
221226 )
222227 . await ;
223- return Ok ( ( ) ) ; // Send error message to the client and return
228+
229+ return Ok ( ( ) ) ;
224230 }
225231
226232 let nonce = U256 :: from_big_endian ( client_msg. verification_data . nonce . as_slice ( ) ) ;
@@ -277,6 +283,23 @@ impl Batcher {
277283 }
278284 }
279285
286+ // Checks user has sufficient balance
287+ // If user has sufficient balance, increments the user's proof count in the batch
288+ async fn check_user_balance ( & self , addr : & Address ) -> bool {
289+ let mut user_proof_counts = self . user_proof_count_in_batch . lock ( ) . await ;
290+ let user_proofs_in_batch = user_proof_counts. get ( addr) . unwrap_or ( & 0 ) . clone ( ) + 1 ;
291+
292+ let user_balance = self . get_user_balance ( addr) . await ;
293+
294+ let min_balance = U256 :: from ( user_proofs_in_batch) * U256 :: from ( MIN_BALANCE_PER_PROOF ) ;
295+ if user_balance < min_balance {
296+ return false ;
297+ }
298+
299+ user_proof_counts. insert ( * addr, user_proofs_in_batch) ;
300+ true
301+ }
302+
280303 async fn check_nonce_and_increment ( & self , addr : Address , nonce : U256 ) -> bool {
281304 let mut user_nonces = self . user_nonces . lock ( ) . await ;
282305
@@ -388,6 +411,9 @@ impl Batcher {
388411 let finalized_batch = batch_queue_lock. clone ( ) ;
389412 batch_queue_lock. clear ( ) ;
390413
414+ // Clear the user proofs in batch as well
415+ self . user_proof_count_in_batch . lock ( ) . await . clear ( ) ;
416+
391417 Some ( finalized_batch)
392418 }
393419
@@ -511,12 +537,6 @@ impl Batcher {
511537
512538 let num_proofs_in_batch = leaves. len ( ) ;
513539
514- // FIXME: This constants should be aggregated into one constants file
515- const AGGREGATOR_COST : u128 = 400000 ;
516- const BATCHER_SUBMISSION_BASE_COST : u128 = 100000 ;
517- const ADDITIONAL_SUBMISSION_COST_PER_PROOF : u128 = 1325 ;
518- const CONSTANT_COST : u128 = AGGREGATOR_COST + BATCHER_SUBMISSION_BASE_COST ;
519-
520540 let gas_per_proof = ( CONSTANT_COST
521541 + ADDITIONAL_SUBMISSION_COST_PER_PROOF * num_proofs_in_batch as u128 )
522542 / num_proofs_in_batch as u128 ;
0 commit comments