Skip to content

[executor] GasOracle fetches provider on every call — no per-block cache #189

@obchain

Description

@obchain

Summary

GasOracle::fetch_params hits the provider on every invocation. In a single block, multiple liquidation opportunities can be queued by the health scanner. Each calls fetch_params independently, making N identical eth_getBlockByNumber(latest) RPC calls that all return the same base fee.

This is unnecessary latency (each call adds one RPC round-trip to opportunity evaluation time) and unnecessary RPC quota consumption.

File

crates/charon-executor/src/gas.rsGasOracle struct

Fix

Add a block-scoped cache:

pub struct GasOracle {
    cache: Mutex<Option<(u64, GasDecision)>>,  // (block_number, decision)
}

impl GasOracle {
    pub async fn fetch_params(
        &self,
        provider: &impl Provider,
        current_block: u64,
    ) -> Result<GasDecision, GasError> {
        let mut guard = self.cache.lock().await;
        if let Some((cached_block, ref decision)) = *guard {
            if cached_block == current_block {
                return Ok(decision.clone());
            }
        }
        let decision = self.fetch_from_provider(provider).await?;
        *guard = Some((current_block, decision.clone()));
        Ok(decision)
    }
}

The current_block parameter comes from the BlockListener event — the correct design since all per-block work is already block-keyed.

Refs #43

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestlayer:rustRust crates (core / scanner / protocols / executor / cli)pr-reviewFindings from PR review processpriority:p2-polishNice-to-have / polishstatus:readyScoped and ready to pick up

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions