Skip to content

Commit ca16af0

Browse files
committed
feat: enforce min max fee
1 parent f8b33ac commit ca16af0

2 files changed

Lines changed: 49 additions & 5 deletions

File tree

crates/batcher/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub struct Batcher {
9797
disabled_verifiers: Mutex<U256>,
9898
aggregator_fee_percentage_multiplier: u128,
9999
aggregator_gas_cost: u128,
100+
latest_block_gas_price: RwLock<U256>,
100101
pub metrics: metrics::BatcherMetrics,
101102
pub telemetry: TelemetrySender,
102103
}
@@ -276,6 +277,7 @@ impl Batcher {
276277
posting_batch: Mutex::new(false),
277278
batch_state: Mutex::new(batch_state),
278279
disabled_verifiers: Mutex::new(disabled_verifiers),
280+
latest_block_gas_price: RwLock::new(U256::zero()),
279281
metrics,
280282
telemetry,
281283
}
@@ -767,6 +769,22 @@ impl Batcher {
767769
let mut batch_state_lock = self.batch_state.lock().await;
768770

769771
let msg_max_fee = nonced_verification_data.max_fee;
772+
773+
// Verify that the max fee is enough to cover a batch of 32 proofs at least
774+
// TODO move number to config file
775+
let gas_price = *self.latest_block_gas_price.read().await;
776+
let min_max_fee_per_proof =
777+
aligned_sdk::verification_layer::compute_fee_per_proof_formula(32, gas_price);
778+
if msg_max_fee < min_max_fee_per_proof {
779+
std::mem::drop(batch_state_lock);
780+
send_message(
781+
ws_conn_sink.clone(),
782+
SubmitProofResponseMessage::UnderpricedProof,
783+
)
784+
.await;
785+
return Ok(());
786+
}
787+
770788
let Some(user_last_max_fee_limit) =
771789
batch_state_lock.get_user_last_max_fee_limit(&addr).await
772790
else {
@@ -1502,6 +1520,9 @@ impl Batcher {
15021520
let gas_price = gas_price.map_err(|_| BatcherError::GasPriceError)?;
15031521

15041522
{
1523+
let mut latest_block_gas_price = self.latest_block_gas_price.write().await;
1524+
*latest_block_gas_price = gas_price;
1525+
15051526
let new_disable_verifiers = disable_verifiers
15061527
.map_err(|e| BatcherError::DisabledVerifiersError(e.to_string()))?;
15071528
let mut disabled_verifiers_lock = self.disabled_verifiers.lock().await;

crates/sdk/src/verification_layer/mod.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,43 @@ pub async fn calculate_fee_per_proof_for_batch_of_size(
171171
})?;
172172
let gas_price = fetch_gas_price(&eth_rpc_provider).await?;
173173

174-
// Cost for estimate `num_proofs_per_batch` proofs
174+
let fee_per_proof = compute_fee_per_proof_formula(num_proofs_in_batch, gas_price);
175+
Ok(fee_per_proof)
176+
}
177+
178+
/// Estimates the fee per proof based on the given batch size and gas price.
179+
///
180+
/// This function models the cost of submitting a batch of proofs to the network
181+
/// by computing an estimated gas cost per proof. The total gas cost is composed of:
182+
/// - a constant base gas cost for any batch submission (`DEFAULT_CONSTANT_GAS_COST`)
183+
/// - an additional gas cost that scales linearly with the number of proofs in the batch
184+
/// (`ADDITIONAL_SUBMISSION_GAS_COST_PER_PROOF * num_proofs_in_batch`)
185+
///
186+
/// The final fee per proof is calculated by:
187+
/// (estimated_gas_per_proof * gas_price * GAS_PRICE_PERCENTAGE_MULTIPLIER) / PERCENTAGE_DIVIDER
188+
///
189+
///
190+
/// # Arguments
191+
/// * `num_proofs_in_batch` - Number of proofs in the batch (must be > 0).
192+
/// * `gas_price` - Current gas price (in wei).
193+
///
194+
/// # Returns
195+
/// * Estimated fee per individual proof (in wei).
196+
///
197+
/// # Panics
198+
/// This function panics if `num_proofs_in_batch` is 0 due to division by zero.
199+
pub fn compute_fee_per_proof_formula(num_proofs_in_batch: usize, gas_price: U256) -> U256 {
200+
// Gas cost for `num_proofs_per_batch` proofs
175201
let estimated_gas_per_proof = (DEFAULT_CONSTANT_GAS_COST
176202
+ ADDITIONAL_SUBMISSION_GAS_COST_PER_PROOF * num_proofs_in_batch as u128)
177203
/ num_proofs_in_batch as u128;
178204

179-
// Price of 1 proof in a batch of size `num_proofs_in_batch` i.e. (1 / `num_proofs_in_batch`).
180-
// The computed price is adjusted with respect to the percentage multiplier from:
181-
// https://github.com/yetanotherco/aligned_layer/blob/staging/crates/batcher/src/lib.rs#L1401
182205
let fee_per_proof = (U256::from(estimated_gas_per_proof)
183206
* gas_price
184207
* U256::from(GAS_PRICE_PERCENTAGE_MULTIPLIER))
185208
/ U256::from(PERCENTAGE_DIVIDER);
186209

187-
Ok(fee_per_proof)
210+
fee_per_proof
188211
}
189212

190213
async fn fetch_gas_price(

0 commit comments

Comments
 (0)