@@ -155,7 +155,7 @@ impl ProofAggregator {
155155
156156 if self . should_send_proof_to_verify_on_chain (
157157 time_elapsed,
158- self . config . monthly_eth_budget_gwei ,
158+ self . config . monthly_budget_eth ,
159159 gas_price. into ( ) ,
160160 ) {
161161 info ! ( "Sending proof to ProofAggregationService contract..." ) ;
@@ -179,31 +179,43 @@ impl ProofAggregator {
179179 Ok ( ( ) )
180180 }
181181
182+ fn floating_eth_to_wei ( eth : f64 ) -> U256 {
183+ let wei_in_eth = 1_000_000_000_000_000_000f64 ;
184+ let wei = eth * wei_in_eth;
185+ U256 :: from ( wei as u64 )
186+ }
187+
188+ fn max_to_spend_in_wei ( time_elapsed : Duration , monthly_eth_budget : f64 ) -> U256 {
189+ const SECONDS_PER_MONTH : u64 = 30 * 24 * 60 * 60 ;
190+
191+ let monthly_budget_in_wei = Self :: floating_eth_to_wei ( monthly_eth_budget) ;
192+
193+ let elapsed_seconds = U256 :: from ( time_elapsed. as_secs ( ) ) ;
194+
195+ let budget_available_per_second_in_wei =
196+ U256 :: from ( monthly_budget_in_wei / SECONDS_PER_MONTH ) ;
197+
198+ budget_available_per_second_in_wei * elapsed_seconds
199+ }
200+
182201 /// Decides whether to send the aggregated proof to be verified on-chain based on
183202 /// time elapsed since last submission and monthly ETH budget.
184203 /// We make a linear function with the eth to spend this month and the time elapsed since last submission.
185204 /// If eth to spend / elapsed time is over the linear function, we skip the submission.
186205 fn should_send_proof_to_verify_on_chain (
187206 & self ,
188207 time_elapsed : Duration ,
189- monthly_eth_to_spend : u64 ,
190- gas_price : U256 ,
208+ monthly_eth_budget : f64 ,
209+ gas_price_in_wei : U256 ,
191210 ) -> bool {
192- const HOURS_PER_MONTH : f64 = 24.0 * 30.0 ;
193-
194- let elapsed_hours = time_elapsed. as_secs_f64 ( ) / 3600.0 ;
195- if elapsed_hours <= 0.0 {
196- return false ;
197- }
198-
199- let elapsed_hours = elapsed_hours. min ( HOURS_PER_MONTH ) ;
211+ const ON_CHAIN_COST_IN_GAS_UNITS : u64 = 600_000u64 ;
200212
201- let hourly_budget_gwei = monthly_eth_to_spend as f64 / HOURS_PER_MONTH ;
202- let budget_so_far_gwei = hourly_budget_gwei * elapsed_hours ;
213+ let on_chain_cost_in_gas : U256 = U256 :: from ( ON_CHAIN_COST_IN_GAS_UNITS ) ;
214+ let max_to_spend_in_wei = Self :: max_to_spend_in_wei ( time_elapsed , monthly_eth_budget ) ;
203215
204- let gas_price_gwei = gas_price . as_u64 ( ) as f64 / 1_000_000_000.0 ;
216+ let expected_cost_in_wei = gas_price_in_wei * on_chain_cost_in_gas ; // assuming 300,000 gas units per transaction
205217
206- gas_price_gwei <= budget_so_far_gwei
218+ expected_cost_in_wei <= max_to_spend_in_wei
207219 }
208220
209221 async fn send_proof_to_verify_on_chain (
@@ -349,9 +361,8 @@ mod tests {
349361
350362 use super :: config:: Config ;
351363
352- #[ test]
353- fn test_should_send_proof_to_verify_on_chain ( ) {
354- // Set the AGGREGATOR env variable to "sp1" or "risc0" as its needed by ProofAggregator::new
364+ fn make_aggregator ( ) -> ProofAggregator {
365+ // Set the AGGREGATOR env variable to "sp1" or "risc0" as it's needed by ProofAggregator::new
355366 std:: env:: set_var ( "AGGREGATOR" , "sp1" ) ;
356367
357368 let current_dir = env ! ( "CARGO_MANIFEST_DIR" ) ;
@@ -377,44 +388,53 @@ mod tests {
377388 } ,
378389 proofs_per_chunk : 512 ,
379390 total_proofs_limit : 3968 ,
380- monthly_eth_budget_gwei : 15_000_000_000 ,
391+ monthly_budget_eth : 15.0 ,
381392 } ;
382393
383- let aggregator = ProofAggregator :: new ( config) ;
394+ ProofAggregator :: new ( config)
395+ }
396+
397+ #[ test]
398+ fn test_should_send_proof_to_verify_on_chain_updated_cases ( ) {
399+ let aggregator = make_aggregator ( ) ;
400+
401+ let gas_price_20gwei: U256 = U256 :: from ( 20_000_000_000u64 ) ;
384402
385- // Test case 1: Just started, should not send
386403 assert ! ( !aggregator. should_send_proof_to_verify_on_chain(
387- Duration :: from_secs( 0 ) ,
388- 15_000_000_000 ,
389- 20_000_000_000u64 . into ( ) ,
404+ Duration :: from_secs( 24 * 60 * 60 ) , // 1 day
405+ 1.0 ,
406+ gas_price_20gwei ,
390407 ) ) ;
391408
392- // Test case 2: Halfway through the month, low spend, should send
393409 assert ! ( aggregator. should_send_proof_to_verify_on_chain(
394- Duration :: from_secs( 15 * 24 * 3600 ) ,
395- 5_000_000_000 ,
396- 20_000_000_000u64 . into ( ) ,
410+ Duration :: from_secs( 24 * 3600 ) ,
411+ 1.0 ,
412+ gas_price_20gwei ,
397413 ) ) ;
398414
399- // Test case 3: Near end of month, high spend -> should send (budget_so_far >> gas_price)
400- assert ! ( aggregator. should_send_proof_to_verify_on_chain(
401- Duration :: from_secs( 28 * 24 * 3600 ) ,
402- 18_000_000_000 ,
403- 20_000_000_000u64 . into( ) ,
415+ assert ! ( !aggregator. should_send_proof_to_verify_on_chain(
416+ Duration :: from_secs( 30 * 24 * 3600 ) ,
417+ 0.001 ,
418+ gas_price_20gwei,
419+ ) ) ;
420+
421+ let gas_price_high: U256 = U256 :: from ( 2_000_000_000_000u64 ) ; // 2e12 wei (~2,000 gwei)
422+ assert ! ( !aggregator. should_send_proof_to_verify_on_chain(
423+ Duration :: from_secs( 15 * 24 * 3600 ) ,
424+ 10.0 ,
425+ gas_price_high,
404426 ) ) ;
405427
406- // Test case 5: End of month, over budget -> with these units still sends
407428 assert ! ( aggregator. should_send_proof_to_verify_on_chain(
408429 Duration :: from_secs( 30 * 24 * 3600 ) ,
409- 25_000_000_000 ,
410- 20_000_000_000u64 . into ( ) ,
430+ 0.012 ,
431+ gas_price_20gwei ,
411432 ) ) ;
412433
413- // Test case 6: Early month, budget_so_far still > gas_price -> should send
414434 assert ! ( aggregator. should_send_proof_to_verify_on_chain(
415- Duration :: from_secs( 5 * 24 * 3600 ) ,
416- 10_000_000_000 ,
417- 20_000_000_000u64 . into ( ) ,
435+ Duration :: from_secs( 2 * 24 * 3600 ) ,
436+ 5.0 ,
437+ gas_price_20gwei ,
418438 ) ) ;
419439 }
420440}
0 commit comments