apollo_l1_gas_price: register each oracle metric set once - #14977
Open
asaf-sw wants to merge 1 commit into
Open
Conversation
asaf-sw
marked this pull request as ready for review
August 17, 2026 22:12
|
Artifacts upload workflows: |
matanl-starkware
requested changes
Aug 18, 2026
matanl-starkware
left a comment
Collaborator
There was a problem hiding this comment.
@matanl-starkware reviewed 4 files and all commit messages, and made 3 comments.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on asaf-sw).
crates/apollo_l1_gas_price/src/metrics.rs line 51 at r1 (raw file):
pub last_success_timestamp: &'static MetricGauge, /// Guards this set's registration. Private so that every set is one of the constants below, /// each of which owns a distinct guard.
Suggestion:
/// Guards this set's registration.crates/apollo_l1_gas_price/src/metrics.rs line 58 at r1 (raw file):
/// Runs the registration calls once per process per metric set. `MetricCounter::register` /// republishes the initial value through `Counter::absolute`, whose semantics the `metrics` /// facade leaves to the recorder; the guard removes the dependency on them.
crates/apollo_l1_gas_price/src/metrics.rs line 79 at r1 (raw file):
.field("error_count", &self.error_count.get_name()) .field("last_success_timestamp", &self.last_success_timestamp.get_name()) .finish_non_exhaustive()
To be honest, I don't think that's necessary. A closing } is fine, silently omitting the guard.
Code quote:
.finish_non_exhaustive()
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.

ExchangeRateOracleMetrics::registeris called fromExchangeRateOracleClient::new, so every constructed client re-registers the static metric bundle for its pair (ETH_TO_STRK_ORACLE_METRICS,STRK_TO_USD_ORACLE_METRICS). This adds a per-bundleOnceso each set registers exactly once per process.Reachable path
A deployed node constructs one client per pair and never re-registers. The in-process multi-node path does:
create_node_modules, the production composition function, is called once per simulated node inside a single test process bycrates/apollo_integration_tests/src/flow_test_setup.rs:336. Each call rebuilds the per-pair clients against the same two static bundles, so node N's construction re-registers what node 1 already registered. The guard is insurance for exactly that in-process repeat construction.Registering from
ComponentStarter::start()instead (the wayregister_provider_metricsdoes) would not help: the flow-test harness starts each in-process node too.On the strength of the claim
Worth being precise, because I checked it rather than assuming it. With the metrics stack actually in use, re-registration is currently harmless:
MetricCounter::registerpublishes the initial value viacounter!(name).absolute(init), andCounterFn for AtomicU64(metrics-0.24.2/src/atomics.rs:27) implementsabsoluteasfetch_max. Withinit = 0for all four oracle counters, a secondregistercannot lower an incremented counter.MetricGauge::registeronly creates the handle and callsdescribe_gauge!; it sets no value.I confirmed this empirically: with the
Onceremoved, an incremented counter still survives a secondregister. So this PR is hardening, not a bug fix. What it buys is thatregisterno longer depends onCounter::absolutebeing monotonic, which is a backend-defined detail (metricsleaves the semantics to the implementation), and it makes "registration happens once per process" an explicit property rather than an accident of the atomic storage backend.If reviewers would rather not carry a guard for a latent-only issue, the alternative is to drop this PR. Flagging it rather than overselling the justification.
Changes
crates/apollo_l1_gas_price/src/metrics.rs: privateregistration_guard: &'static Oncefield onExchangeRateOracleMetrics,registerwrapped incall_once, one distinctOncestatic per bundle.Debugswitches tofinish_non_exhaustivesince the guard is not printed.crates/apollo_l1_gas_price/src/metrics_test.rs: constructs two clients for the same pair with an increment between, asserts the set's guard is uncompleted before the first construction and completed after it, and asserts the count survives the second construction. The guard is a test-ownedOnceso the state assertions do not depend on other tests in the process. Deleting thecall_oncewrapper makes the test fail. The test comment names the flow-test path it models.crates/apollo_l1_gas_price/Cargo.toml:metrics,metrics-exporter-prometheus, andapollo_metricswithtestingadded as dev-dependencies for the new test.Verification
./scripts/rust_fmt.shcleanRUSTFLAGS="-D warnings" cargo clippy -p apollo_l1_gas_price --all-targets --all-featurescleanSEED=0 cargo nextest run -p apollo_l1_gas_price: 20 passed, 0 skippedcall_oncewrapper removed,repeated_client_construction_registers_metrics_oncefails onassertion failed: TEST_REGISTRATION.is_completed()scripts/taplo.shandcargo macheteclean