@@ -882,4 +882,196 @@ mod test {
882882 max_fee_1
883883 ) ;
884884 }
885+
886+ #[ test]
887+ fn test_batch_size_limit_enforcement_with_real_sp1_proofs ( ) {
888+ use aligned_sdk:: communication:: serialization:: cbor_serialize;
889+ use aligned_sdk:: common:: types:: VerificationData ;
890+ use std:: fs;
891+
892+ let proof_generator_addr = Address :: random ( ) ;
893+ let payment_service_addr = Address :: random ( ) ;
894+ let chain_id = U256 :: from ( 42 ) ;
895+ let dummy_signature = Signature {
896+ r : U256 :: from ( 1 ) ,
897+ s : U256 :: from ( 2 ) ,
898+ v : 3 ,
899+ } ;
900+
901+ // Load actual SP1 proof files
902+ let proof_path = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof" ;
903+ let elf_path = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf" ;
904+ let pub_input_path = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub" ;
905+
906+ let proof_data = match fs:: read ( proof_path) {
907+ Ok ( data) => data,
908+ Err ( _) => return , // Skip test if files not found
909+ } ;
910+
911+ let elf_data = match fs:: read ( elf_path) {
912+ Ok ( data) => data,
913+ Err ( _) => return ,
914+ } ;
915+
916+ let pub_input_data = match fs:: read ( pub_input_path) {
917+ Ok ( data) => data,
918+ Err ( _) => return ,
919+ } ;
920+
921+ let verification_data = VerificationData {
922+ proving_system : ProvingSystemId :: SP1 ,
923+ proof : proof_data,
924+ pub_input : Some ( pub_input_data) ,
925+ verification_key : None ,
926+ vm_program_code : Some ( elf_data) ,
927+ proof_generator_addr,
928+ } ;
929+
930+ // Create 10 entries using the same SP1 proof data
931+ let mut batch_queue = BatchQueue :: new ( ) ;
932+ let max_fee = U256 :: from ( 1_000_000_000_000_000u128 ) ;
933+
934+ for i in 0 ..10 {
935+ let sender_addr = Address :: random ( ) ;
936+ let nonce = U256 :: from ( i + 1 ) ;
937+
938+ let nonced_verification_data = NoncedVerificationData :: new (
939+ verification_data. clone ( ) ,
940+ nonce,
941+ max_fee,
942+ chain_id,
943+ payment_service_addr,
944+ ) ;
945+
946+ let vd_commitment: VerificationDataCommitment = nonced_verification_data. clone ( ) . into ( ) ;
947+ let entry = BatchQueueEntry :: new_for_testing (
948+ nonced_verification_data,
949+ vd_commitment,
950+ dummy_signature,
951+ sender_addr,
952+ ) ;
953+ let batch_priority = BatchQueueEntryPriority :: new ( max_fee, nonce) ;
954+ batch_queue. push ( entry, batch_priority) ;
955+ }
956+
957+ // Test with a 5MB batch size limit
958+ let batch_size_limit = 5_000_000 ; // 5MB
959+ let gas_price = U256 :: from ( 1 ) ;
960+
961+ let finalized_batch = try_build_batch (
962+ batch_queue. clone ( ) ,
963+ gas_price,
964+ batch_size_limit,
965+ 50 , // max proof qty
966+ DEFAULT_CONSTANT_GAS_COST ,
967+ ) . unwrap ( ) ;
968+
969+ // Verify the finalized batch respects the size limit
970+ let finalized_verification_data: Vec < VerificationData > = finalized_batch
971+ . iter ( )
972+ . map ( |entry| entry. nonced_verification_data . verification_data . clone ( ) )
973+ . collect ( ) ;
974+
975+ let finalized_serialized = cbor_serialize ( & finalized_verification_data) . unwrap ( ) ;
976+ let finalized_actual_size = finalized_serialized. len ( ) ;
977+
978+ // Assert the batch respects the limit
979+ assert ! ( finalized_actual_size <= batch_size_limit,
980+ "Finalized batch size {} exceeds limit {}" , finalized_actual_size, batch_size_limit) ;
981+
982+ // Verify some entries were included (not empty batch)
983+ assert ! ( !finalized_batch. is_empty( ) , "Batch should not be empty" ) ;
984+
985+ // Verify not all entries were included (some should be rejected due to size limit)
986+ assert ! ( finalized_batch. len( ) < 10 , "Batch should not include all entries due to size limit" ) ;
987+ }
988+
989+ #[ test]
990+ fn test_cbor_size_upper_bound_accuracy ( ) {
991+ use aligned_sdk:: communication:: serialization:: cbor_serialize;
992+ use aligned_sdk:: common:: types:: VerificationData ;
993+ use std:: fs;
994+
995+ let proof_generator_addr = Address :: random ( ) ;
996+ let payment_service_addr = Address :: random ( ) ;
997+ let chain_id = U256 :: from ( 42 ) ;
998+
999+ // Load actual SP1 proof files
1000+ let proof_path = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.proof" ;
1001+ let elf_path = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.elf" ;
1002+ let pub_input_path = "../../scripts/test_files/sp1/sp1_fibonacci_5_0_0.pub" ;
1003+
1004+ let proof_data = match fs:: read ( proof_path) {
1005+ Ok ( data) => data,
1006+ Err ( _) => return , // Skip test if files not found
1007+ } ;
1008+
1009+ let elf_data = match fs:: read ( elf_path) {
1010+ Ok ( data) => data,
1011+ Err ( _) => return ,
1012+ } ;
1013+
1014+ let pub_input_data = match fs:: read ( pub_input_path) {
1015+ Ok ( data) => data,
1016+ Err ( _) => return ,
1017+ } ;
1018+
1019+ let verification_data = VerificationData {
1020+ proving_system : ProvingSystemId :: SP1 ,
1021+ proof : proof_data,
1022+ pub_input : Some ( pub_input_data) ,
1023+ verification_key : None ,
1024+ vm_program_code : Some ( elf_data) ,
1025+ proof_generator_addr,
1026+ } ;
1027+
1028+ let nonced_verification_data = NoncedVerificationData :: new (
1029+ verification_data. clone ( ) ,
1030+ U256 :: from ( 1 ) ,
1031+ U256 :: from ( 1_000_000_000_000_000u128 ) ,
1032+ chain_id,
1033+ payment_service_addr,
1034+ ) ;
1035+
1036+ // Test cbor_size_upper_bound() accuracy
1037+ let estimated_size = nonced_verification_data. cbor_size_upper_bound ( ) ;
1038+
1039+ // Compare with actual CBOR serialization of the inner VerificationData
1040+ let actual_serialized = cbor_serialize ( & verification_data) . unwrap ( ) ;
1041+ let actual_size = actual_serialized. len ( ) ;
1042+
1043+ // Also test serializing the NoncedVerificationData
1044+ let actual_nonced_serialized = cbor_serialize ( & nonced_verification_data) . unwrap ( ) ;
1045+ let actual_nonced_size = actual_nonced_serialized. len ( ) ;
1046+
1047+ // Verify CBOR encodes binary data efficiently (with serde_bytes fix)
1048+ let raw_total = verification_data. proof . len ( ) +
1049+ verification_data. vm_program_code . as_ref ( ) . unwrap ( ) . len ( ) +
1050+ verification_data. pub_input . as_ref ( ) . unwrap ( ) . len ( ) ;
1051+
1052+ let cbor_efficiency_ratio = actual_size as f64 / raw_total as f64 ;
1053+
1054+ // With serde_bytes, CBOR should be very efficient (close to 1.0x)
1055+ assert ! ( cbor_efficiency_ratio < 1.1 ,
1056+ "CBOR serialization should be efficient with serde_bytes. Ratio: {:.3}x" ,
1057+ cbor_efficiency_ratio) ;
1058+
1059+ // Verify CBOR uses byte strings, not arrays
1060+ let proof_cbor = cbor_serialize ( & verification_data. proof ) . unwrap ( ) ;
1061+ let first_byte = proof_cbor[ 0 ] ;
1062+ let major_type = ( first_byte >> 5 ) & 0x07 ;
1063+
1064+ assert_eq ! ( major_type, 2 , "Proof should be encoded as CBOR byte string (major type 2), got {}" , major_type) ;
1065+
1066+ // The estimation should be an upper bound
1067+ assert ! ( estimated_size >= actual_size,
1068+ "cbor_size_upper_bound() should be an upper bound. Estimated: {}, Actual: {}" ,
1069+ estimated_size, actual_size) ;
1070+
1071+ // The estimation should also be reasonable (not wildly over-estimated)
1072+ let estimation_overhead = estimated_size as f64 / actual_size as f64 ;
1073+ assert ! ( estimation_overhead < 2.0 ,
1074+ "Estimation should be reasonable, not wildly over-estimated. Overhead: {:.3}x" ,
1075+ estimation_overhead) ;
1076+ }
8851077}
0 commit comments