@@ -146,7 +146,8 @@ pub(crate) fn calculate_batch_size(batch_queue: &BatchQueue) -> Result<usize, Ba
146146pub ( crate ) fn try_build_batch (
147147 batch_queue : BatchQueue ,
148148 gas_price : U256 ,
149- max_batch_size : usize ,
149+ max_batch_byte_size : usize ,
150+ max_batch_proof_qty : usize ,
150151) -> Result < ( BatchQueue , Vec < BatchQueueEntry > ) , BatcherError > {
151152 let mut batch_queue = batch_queue;
152153 let mut batch_size = calculate_batch_size ( & batch_queue) ?;
@@ -156,7 +157,10 @@ pub(crate) fn try_build_batch(
156157 let batch_len = batch_queue. len ( ) ;
157158 let fee_per_proof = calculate_fee_per_proof ( batch_len, gas_price) ;
158159
159- if batch_size > max_batch_size || fee_per_proof > entry. nonced_verification_data . max_fee {
160+ if batch_size > max_batch_byte_size
161+ || fee_per_proof > entry. nonced_verification_data . max_fee
162+ || batch_len > max_batch_proof_qty
163+ {
160164 // Update the state for the next iteration:
161165 // * Subtract this entry size to the size of the batch size.
162166 // * Push the current entry to the resulting batch queue.
@@ -298,7 +302,7 @@ mod test {
298302
299303 let gas_price = U256 :: from ( 1 ) ;
300304 let ( resulting_batch_queue, batch) =
301- try_build_batch ( batch_queue, gas_price, 5000000 ) . unwrap ( ) ;
305+ try_build_batch ( batch_queue, gas_price, 5000000 , 50 ) . unwrap ( ) ;
302306
303307 assert ! ( resulting_batch_queue. is_empty( ) ) ;
304308
@@ -401,7 +405,7 @@ mod test {
401405
402406 let gas_price = U256 :: from ( 1 ) ;
403407 let ( resulting_batch_queue, finalized_batch) =
404- try_build_batch ( batch_queue, gas_price, 5000000 ) . unwrap ( ) ;
408+ try_build_batch ( batch_queue, gas_price, 5000000 , 50 ) . unwrap ( ) ;
405409
406410 // The resulting batch queue (entries from the old batch queue that were not willing to pay
407411 // in this batch), should be empty and hence, all entries from the batch queue should be in
@@ -512,7 +516,7 @@ mod test {
512516
513517 let gas_price = U256 :: from ( 1 ) ;
514518 let ( resulting_batch_queue, finalized_batch) =
515- try_build_batch ( batch_queue, gas_price, 5000000 ) . unwrap ( ) ;
519+ try_build_batch ( batch_queue, gas_price, 5000000 , 50 ) . unwrap ( ) ;
516520
517521 // The resulting batch queue (entries from the old batch queue that were not willing to pay
518522 // in this batch), should be empty and hence, all entries from the batch queue should be in
@@ -529,4 +533,113 @@ mod test {
529533 max_fee_1
530534 ) ;
531535 }
536+
537+ #[ test]
538+ fn batch_finalization_algorithm_works_not_bigger_than_max_batch_proof_qty ( ) {
539+ // The following information will be the same for each entry, it is just some dummy data to see
540+ // algorithm working.
541+
542+ let proof_generator_addr = Address :: random ( ) ;
543+ let payment_service_addr = Address :: random ( ) ;
544+ let sender_addr = Address :: random ( ) ;
545+ let bytes_for_verification_data = vec ! [ 42_u8 ; 10 ] ;
546+ let dummy_signature = Signature {
547+ r : U256 :: from ( 1 ) ,
548+ s : U256 :: from ( 2 ) ,
549+ v : 3 ,
550+ } ;
551+ let verification_data = VerificationData {
552+ proving_system : ProvingSystemId :: Risc0 ,
553+ proof : bytes_for_verification_data. clone ( ) ,
554+ pub_input : Some ( bytes_for_verification_data. clone ( ) ) ,
555+ verification_key : Some ( bytes_for_verification_data. clone ( ) ) ,
556+ vm_program_code : Some ( bytes_for_verification_data) ,
557+ proof_generator_addr,
558+ } ;
559+ let chain_id = U256 :: from ( 42 ) ;
560+
561+ // Here we create different entries for the batch queue.
562+ // Since we are sending with the same address, the low nonces should have higher max fees.
563+
564+ // Entry 1
565+ let nonce_1 = U256 :: from ( 1 ) ;
566+ let max_fee_1 = U256 :: from ( 1_300_000_000_000_002u128 ) ;
567+ let nonced_verification_data_1 = NoncedVerificationData :: new (
568+ verification_data. clone ( ) ,
569+ nonce_1,
570+ max_fee_1,
571+ chain_id,
572+ payment_service_addr,
573+ ) ;
574+ let vd_commitment_1: VerificationDataCommitment = nonced_verification_data_1. clone ( ) . into ( ) ;
575+ let entry_1 = BatchQueueEntry :: new_for_testing (
576+ nonced_verification_data_1,
577+ vd_commitment_1,
578+ dummy_signature,
579+ sender_addr,
580+ ) ;
581+ let batch_priority_1 = BatchQueueEntryPriority :: new ( max_fee_1, nonce_1) ;
582+
583+ // Entry 2
584+ let nonce_2 = U256 :: from ( 2 ) ;
585+ let max_fee_2 = U256 :: from ( 1_300_000_000_000_001u128 ) ;
586+ let nonced_verification_data_2 = NoncedVerificationData :: new (
587+ verification_data. clone ( ) ,
588+ nonce_2,
589+ max_fee_2,
590+ chain_id,
591+ payment_service_addr,
592+ ) ;
593+ let vd_commitment_2: VerificationDataCommitment = nonced_verification_data_2. clone ( ) . into ( ) ;
594+ let entry_2 = BatchQueueEntry :: new_for_testing (
595+ nonced_verification_data_2,
596+ vd_commitment_2,
597+ dummy_signature,
598+ sender_addr,
599+ ) ;
600+ let batch_priority_2 = BatchQueueEntryPriority :: new ( max_fee_2, nonce_2) ;
601+
602+ // Entry 3
603+ let nonce_3 = U256 :: from ( 3 ) ;
604+ let max_fee_3 = U256 :: from ( 1_300_000_000_000_000u128 ) ;
605+ let nonced_verification_data_3 = NoncedVerificationData :: new (
606+ verification_data. clone ( ) ,
607+ nonce_3,
608+ max_fee_3,
609+ chain_id,
610+ payment_service_addr,
611+ ) ;
612+ let vd_commitment_3: VerificationDataCommitment = nonced_verification_data_3. clone ( ) . into ( ) ;
613+ let entry_3 = BatchQueueEntry :: new_for_testing (
614+ nonced_verification_data_3,
615+ vd_commitment_3,
616+ dummy_signature,
617+ sender_addr,
618+ ) ;
619+ let batch_priority_3 = BatchQueueEntryPriority :: new ( max_fee_3, nonce_3) ;
620+
621+ let mut batch_queue = BatchQueue :: new ( ) ;
622+ batch_queue. push ( entry_1, batch_priority_1) ;
623+ batch_queue. push ( entry_2, batch_priority_2) ;
624+ batch_queue. push ( entry_3, batch_priority_3) ;
625+
626+ let gas_price = U256 :: from ( 1 ) ;
627+
628+ // The max batch len is 2, so the algorithm should stop at the second entry.
629+ let max_batch_proof_qty = 2 ;
630+
631+ let ( resulting_batch_queue, finalized_batch) =
632+ try_build_batch ( batch_queue, gas_price, 5000000 , max_batch_proof_qty) . unwrap ( ) ;
633+
634+ assert_eq ! ( resulting_batch_queue. len( ) , 1 ) ;
635+ assert_eq ! ( finalized_batch. len( ) , 2 ) ;
636+ assert_eq ! (
637+ finalized_batch[ 0 ] . nonced_verification_data. max_fee,
638+ max_fee_2
639+ ) ;
640+ assert_eq ! (
641+ finalized_batch[ 1 ] . nonced_verification_data. max_fee,
642+ max_fee_1
643+ ) ;
644+ }
532645}
0 commit comments