Skip to content

Commit dcfb204

Browse files
maximopalopoliMarcosNicolauJuArce
authored
feat(aggregation-mode): retry bump and sending proofs on-chain after proof aggregation (#2211)
Co-authored-by: Marcos Nicolau <marcosnicolau@lambdaclass.com> Co-authored-by: JuArce <52429267+JuArce@users.noreply.github.com>
1 parent 6f2be89 commit dcfb204

File tree

6 files changed

+452
-279
lines changed

6 files changed

+452
-279
lines changed

aggregation_mode/Cargo.lock

Lines changed: 1 addition & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aggregation_mode/proof_aggregator/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ reqwest = { version = "0.12" }
2121
ciborium = "=0.2.2"
2222
lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "5f8f2cfcc8a1a22f77e8dff2d581f1166eefb80b", features = ["serde"]}
2323
rayon = "1.10.0"
24-
backon = "1.2.0"
2524
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres", "uuid", "bigdecimal" ] }
2625

2726
# zkvms
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
use alloy::primitives::{utils::parse_ether, U256};
2+
use std::time::Duration;
3+
4+
// We assume a fixed gas cost of 300,000 for each of the 2 transactions
5+
const ON_CHAIN_COST_IN_GAS_UNITS: u64 = 600_000u64;
6+
7+
/// Decides whether to send the aggregated proof to be verified on-chain based on
8+
/// time elapsed since last submission and monthly ETH budget.
9+
/// We make a linear function with the eth to spend this month and the time elapsed since last submission.
10+
/// If eth to spend / elapsed time is over the linear function, we skip the submission.
11+
pub fn should_send_proof_to_verify_on_chain(
12+
time_elapsed: Duration,
13+
monthly_eth_budget: f64,
14+
network_gas_price: U256,
15+
) -> bool {
16+
let on_chain_cost_in_gas: U256 = U256::from(ON_CHAIN_COST_IN_GAS_UNITS);
17+
let max_to_spend_wei = max_to_spend_in_wei(time_elapsed, monthly_eth_budget);
18+
19+
let expected_cost_in_wei = network_gas_price * on_chain_cost_in_gas;
20+
21+
expected_cost_in_wei <= max_to_spend_wei
22+
}
23+
24+
fn max_to_spend_in_wei(time_elapsed: Duration, monthly_eth_budget: f64) -> U256 {
25+
const SECONDS_PER_MONTH: u64 = 30 * 24 * 60 * 60;
26+
27+
// Note: this expect is safe because in case it was invalid, should have been caught at startup
28+
let monthly_budget_in_wei = parse_ether(&monthly_eth_budget.to_string())
29+
.expect("The monthly budget should be a non-negative value");
30+
31+
let elapsed_seconds = U256::from(time_elapsed.as_secs());
32+
33+
let budget_available_per_second_in_wei = monthly_budget_in_wei / U256::from(SECONDS_PER_MONTH);
34+
35+
budget_available_per_second_in_wei * elapsed_seconds
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
use super::should_send_proof_to_verify_on_chain;
41+
use alloy::primitives::U256;
42+
use std::time::Duration;
43+
44+
#[test]
45+
fn test_should_send_proof_to_verify_on_chain_updated_cases() {
46+
// The should_send_proof_to_verify_on_chain function returns true when:
47+
// gas_price * 600_000 <= (seconds_elapsed) * (monthly_eth_budget / (30 * 24 * 60 * 60))
48+
49+
const BUDGET_PER_MONTH_IN_ETH: f64 = 0.15;
50+
const ONE_DAY_SECONDS: u64 = 24 * 60 * 60;
51+
let gas_price = U256::from(1_000_000_000u64); // 1 Gwei
52+
53+
// Case 1: Base case -> should return true
54+
// Monthly Budget: 0.15 ETH -> 0.005 ETH per day -> 0.000000058 ETH per hour
55+
// Elapsed Time: 24 hours
56+
// Gas Price: 1 Gwei
57+
// Max to spend: 0.000000058 ETH/hour * 24 hours = 0.005 ETH
58+
// Expected cost: 600,000 * 1 Gwei = 0.0006 ETH
59+
// Expected cost < Max to spend, so we can send the proof
60+
assert!(should_send_proof_to_verify_on_chain(
61+
Duration::from_secs(ONE_DAY_SECONDS), // 24 hours
62+
BUDGET_PER_MONTH_IN_ETH, // 0.15 ETH monthly budget
63+
gas_price, // 1 Gwei gas price
64+
));
65+
66+
// Case 2: Slightly Increased Gas Price -> should return true
67+
// Monthly Budget: 0.15 ETH -> 0.005 ETH per day -> 0.000000058 ETH per hour
68+
// Elapsed Time: 24 hours
69+
// Gas Price: 8 Gwei
70+
// Max to spend: 0.000000058 ETH/hour * 24 hours = 0.005 ETH
71+
// Expected cost: 600,000 * 8 Gwei = 0.0048 ETH
72+
// Expected cost < Max to spend, so we can send the proof
73+
assert!(should_send_proof_to_verify_on_chain(
74+
Duration::from_secs(ONE_DAY_SECONDS), // 24 hours
75+
BUDGET_PER_MONTH_IN_ETH, // 0.15 ETH monthly budget
76+
U256::from(8_000_000_000u64), // 8 Gwei gas price
77+
));
78+
79+
// Case 3: Increased Gas Price -> should return false
80+
// Monthly Budget: 0.15 ETH -> 0.005 ETH per day -> 0.000000058 ETH per hour
81+
// Elapsed Time: 24 hours
82+
// Gas Price: 10 Gwei
83+
// Max to spend: 0.000000058 ETH/hour * 24 hours = 0.005 ETH
84+
// Expected cost: 600,000 * 10 Gwei = 0.006 ETH
85+
// Expected cost > Max to spend, so we cannot send the proof
86+
assert!(!should_send_proof_to_verify_on_chain(
87+
Duration::from_secs(ONE_DAY_SECONDS), // 24 hours
88+
BUDGET_PER_MONTH_IN_ETH, // 0.15 ETH monthly budget
89+
U256::from(10_000_000_000u64), // 10 Gwei gas price
90+
));
91+
92+
// Case 4: Slightly Reduced Time Elapsed -> should return true
93+
// Monthly Budget: 0.15 ETH -> 0.005 ETH per day -> 0.000000058 ETH per hour
94+
// Elapsed Time: 3 hours
95+
// Gas Price: 1 Gwei
96+
// Max to spend: 0.000000058 ETH/hour * 3 hours = 0.000625 ETH
97+
// Expected cost: 600,000 * 1 Gwei = 0.0006 ETH
98+
// Expected cost < Max to spend, so we can send the proof
99+
assert!(should_send_proof_to_verify_on_chain(
100+
Duration::from_secs(3 * 3600), // 3 hours
101+
BUDGET_PER_MONTH_IN_ETH, // 0.15 ETH monthly budget
102+
gas_price, // 1 Gwei gas price
103+
));
104+
105+
// Case 5: Reduced Time Elapsed -> should return false
106+
// Monthly Budget: 0.15 ETH -> 0.005 ETH per day -> 0.000000058 ETH per hour
107+
// Elapsed Time: 1.2 hours
108+
// Gas Price: 1 Gwei
109+
// Max to spend: 0.000000058 ETH/hour * 1.2 hours = 0.00025 ETH
110+
// Expected cost: 600,000 * 1 Gwei = 0.0006 ETH
111+
// Expected cost > Max to spend, so we cannot send the proof
112+
assert!(!should_send_proof_to_verify_on_chain(
113+
Duration::from_secs_f64(1.2 * 3600.0), // 1.2 hours
114+
BUDGET_PER_MONTH_IN_ETH, // 0.15 ETH monthly budget
115+
gas_price, // 1 Gwei gas price
116+
));
117+
118+
// Case 6: Slightly Reduced Monthly Budget -> should return true
119+
// Monthly Budget: 0.1 ETH -> 0.0033 ETH per day -> 0.000000038 ETH per hour
120+
// Elapsed Time: 24 hours
121+
// Gas Price: 1 Gwei
122+
// Max to spend: 0.000000038 ETH/hour * 24 hours = 0.0032832 ETH
123+
// Expected cost: 600,000 * 1 Gwei = 0.0006 ETH
124+
// Expected cost < Max to spend, so we can send the proof
125+
assert!(should_send_proof_to_verify_on_chain(
126+
Duration::from_secs(ONE_DAY_SECONDS), // 24 hours
127+
0.1, // 0.1 ETH monthly budget
128+
gas_price, // 1 Gwei gas price
129+
));
130+
131+
// Case 7: Decreased Monthly Budget -> should return false
132+
// Monthly Budget: 0.01 ETH -> 0.00033 ETH per day -> 0.0000000038 ETH per hour
133+
// Elapsed Time: 24 hours
134+
// Gas Price: 1 Gwei
135+
// Max to spend: 0.0000000038 ETH/hour * 24 hours = 0.00032832 ETH
136+
// Expected cost: 600,000 * 1 Gwei = 0.0006 ETH
137+
// Expected cost > Max to spend, so we cannot send the proof
138+
assert!(!should_send_proof_to_verify_on_chain(
139+
Duration::from_secs(ONE_DAY_SECONDS), // 24 hours
140+
0.01, // 0.01 ETH monthly budget
141+
gas_price, // 1 Gwei gas price
142+
));
143+
}
144+
}

0 commit comments

Comments
 (0)