apollo_l1_gas_price,apollo_l1_gas_price_types: hold Chainlink query failures for the retry interval - #14992
Draft
asaf-sw wants to merge 1 commit into
Draft
Conversation
This was referenced Aug 18, 2026
apollo_consensus_orchestrator,apollo_l1_gas_price: bound the per-block eth to fri rate change
#14973
Open
Contributor
Author
This was referenced Aug 18, 2026
…ailures for the retry interval
asaf-sw
force-pushed
the
asaf/l1-oracle-a9a-client-lifecycle
branch
from
August 18, 2026 20:57
09068b0 to
a47b43d
Compare
asaf-sw
force-pushed
the
asaf/l1-oracle-a9b-negative-caching
branch
from
August 18, 2026 20:57
c50e226 to
c2af008
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #14991. Part of the L1 price oracle replacement split of #14942.
What
Negative caching for the Chainlink client: a failed query's error is held in
OracleState::last_errorand served to callers with nothing better, and the next query is spawned oncefailure_retry_interval_secondselapses instead of on every call.Why hold a failure
Without it, every
fetch_rateagainst a failing feed spawns a fresh query: two view calls per feed per attempt, on every proposal, for as long as the feed stays broken. A hostile or broken feed would otherwise cost blocking VM executions per block. Holding the failure bounds the retry cadence to one query per retry interval, which is also why the interval is its own config key rather than the sampling interval: a transient failure costs one retry interval, not the rest of the sampling interval.The precedence rule
A held failure is served only when no valid read is held. Bugbot's first review of #14942 caught an availability regression in exactly this spot: the one call that observed a failing query finish was returned that failure directly, without consulting the rate the client already held.
no_call_is_denied_a_rate_the_client_holdsis the regression test, asserting every call through the failure's harvest is served the held rate;a_held_failure_does_not_mask_the_last_valid_ratepins the steady state after the failure is held.A success clears
last_error, so the client never reports a failure older than its newest read.Landing state
metrics().register()runs under apollo_l1_gas_price: register each oracle metric set once #14977'sOnceguard.[Temporary comment]aboveRateKindinapollo_l1_gas_price_typesis deleted, which is why the title carries two scopes: apollo_l1_gas_price,apollo_l1_gas_price_config: ChainlinkOracleClient query lifecycle #14991'sChainlinkRate: RateKindsupertrait bound is the cross-crate justification for itspubthat the marker existed to promise.no_call_is_denied_a_rate_the_client_holds.Testing
4 new tests (82 total). A failing feed is queried once per retry interval, with the batcher call counter flat across ten calls inside the interval; the retry fires exactly at the interval and not one second earlier; a held failure does not mask the last valid rate, including on the very call that harvests the failure.
🤖 Generated with Claude Code