apollo_dashboard: exclude observers from strk_to_usd_rate_frozen alert - #14934
Conversation
PR SummaryLow Risk Overview
Reviewed by Cursor Bugbot for commit 51204e2. Bugbot is set up for automated code reviews on this repo. Configure here. |
asaf-sw
left a comment
There was a problem hiding this comment.
@asaf-sw reviewed 2 files and all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on matanl-starkware).
asaf-sw
left a comment
There was a problem hiding this comment.
@asaf-sw+AGNT made 1 comment.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on matanl-starkware).
crates/apollo_dashboard/src/alert_scenarios/l1_gas_prices.rs line 197 at r1 (raw file):
/// "frozen"); only a present-but-flat gauge trips this. /// /// Observer applicability depends on which consensus path queries the oracle. Eth to Strk is
Suggestion, take it or leave it, your call.
These lines explain the two specific oracles, but they sit on the generic helper, which after this change takes applicability from the caller and does not care which oracle it is given. The same explanation is also in the PR description, almost word for word.
One option is to leave the helper's existing doc as it was and put one line at each call site, which have none today:
/// Eth to Strk is queried on the validate path too, so every node's gauge moves.
pub(crate) fn get_eth_to_strk_rate_frozen_alert() -> Alert {/// Strk to Usd is queried only when building a proposal; observers never propose, so their gauge
/// stays flat and the alert excludes them.
pub(crate) fn get_strk_to_usd_rate_frozen_alert() -> Alert {That puts each fact next to the code it applies to, and drops the "must exclude them" and "by construction" phrasing, which argues for the change rather than saying what the code does.
|
Previously, asaf-sw wrote…
PTAL |
|
Previously, asaf-sw wrote…
bug |
asaf-sw
left a comment
There was a problem hiding this comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on matanl-starkware).
The frozen-rate alert hardcoded ObserverApplicability::Applicable for both exchange-rate oracles. That is correct for eth_to_strk, which every node queries when validating a proposal, but wrong for strk_to_usd, which is queried only on the proposer build path (SNIP-35 fee proposal). An observer never proposes, so its snip35_strk_usd_rate gauge is registered at 0 and never updated — present-but-flat by construction — making the alert a permanent false positive on observer nodes (seen on apollo-sepolia-alpha-0). Parameterize oracle_rate_frozen_alert with ObserverApplicability and pass NotApplicable for strk_to_usd, matching the oracle success/error-count alerts which already exclude observers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0211d16 to
51204e2
Compare
matanl-starkware
left a comment
There was a problem hiding this comment.
@matanl-starkware reviewed 2 files and all commit messages, and resolved 1 discussion.
Reviewable status: 0 of 2 files reviewed, all discussions resolved (waiting on asaf-sw).
matanl-starkware
left a comment
There was a problem hiding this comment.
@matanl-starkware reviewed 2 files and all commit messages, and made 1 comment.
Reviewable status: 0 of 2 files reviewed, all discussions resolved (waiting on asaf-sw).
asaf-sw
left a comment
There was a problem hiding this comment.
@asaf-sw reviewed 2 files and all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on matanl-starkware).
Problem
strk_to_usd_rate_frozenfires permanently on observer nodes (seen onapollo-sepolia-alpha-0, the one sepolia-alpha node whosevalidator_idis outside the committee).Root cause:
oracle_rate_frozen_alerthardcodesObserverApplicability::Applicablefor both exchange-rate oracles, but the two oracles are queried on different consensus paths:validate_proposal.rs→get_l1_prices_in_fri_and_wei), so every node — observers included — keeps its gauge moving.Applicableis correct.build_proposal→compute_proposer_fee_proposal→resolve_fee_target), for the SNIP-35 fee proposal. Validation bounds-checks the proposer'sfee_proposal_friagainst the local median without an oracle read. An observer never proposes, so itssnip35_strk_usd_rategauge is registered at 0 (ExchangeRateOracleClient::newregisters metrics unconditionally) and never updated — present-but-flat by construction, sosum(changes(...[1h])) < 1is permanently true.Not an outage: on the observer,
snip35_strk_usd_success_countand_error_countare both flat 0 (zero attempts), while all validators read the rate normally via round-robin proposership.Fix
Parameterize
oracle_rate_frozen_alertwithObserverApplicabilityand passNotApplicablefor strk_to_usd (Applicablefor eth_to_strk, unchanged behavior). This matches the oracle success/error-count alerts, which already exclude observers. Regenerateddev_grafana_alerts.json; the only expression change isstrk_to_usd_rate_frozengaining theand on() (is_observer == 0)clause.Verification
SEED=0 cargo test -p apollo_dashboard— 16 passed (includes the generated-JSON drift test)cargo clippy -p apollo_dashboard --all-targets -- -D warnings— cleanscripts/rust_fmt.sh— clean🤖 Generated with Claude Code