apollo_l1_gas_price_config: Chainlink oracle config - #14983
Conversation
|
Artifacts upload workflows: |
9237143 to
f22a080
Compare
a3b3e4a to
6bb9294
Compare
f22a080 to
1577910
Compare
1577910 to
7dc6952
Compare
matanl-starkware
left a comment
There was a problem hiding this comment.
@matanl-starkware made 2 comments.
Reviewable status: 0 of 4 files reviewed, 2 unresolved discussions (waiting on asaf-sw).
crates/apollo_l1_gas_price_config/src/config.rs line 297 at r2 (raw file):
/// Catches exchanged bounds: the forward bound covers only clock skew, so it must sit strictly /// below the backward one, which covers a full heartbeat.
Please explain with respect to the member names in plain English
Code quote:
/// Catches exchanged bounds: the forward bound covers only clock skew, so it must sit strictly
/// below the backward one, which covers a full heartbeat.crates/apollo_l1_gas_price_config/src/config.rs line 342 at r2 (raw file):
pub struct ChainlinkOracleConfig { /// Quotes USD per ETH. pub eth_usd_feed_address: ContractAddress,
I don't understand why we don't have this type of struct:
pub struct PairConfig (choose appropriate name):
{
pub address: ContractAddress,
pub bounds: RateBounds,
}
Code quote:
pub eth_usd_feed_address: ContractAddress,6bb9294 to
f474fcb
Compare
7dc6952 to
00dcd79
Compare
|
Migrated review comment from #14944, closed in favor of this split. @matanl-starkware wrote on
This PR owns the Chainlink cadence param the comment landed on. It is |
|
Migrated review comment from #14944, closed in favor of this split. @matanl-starkware wrote on
This PR owns the addresses and the common params: |
00dcd79 to
dc4d488
Compare
f474fcb to
32735ed
Compare
dc4d488 to
2a1b5b4
Compare
8af1f17 to
1cfb7da
Compare
2a1b5b4 to
07b3c1e
Compare
1cfb7da to
b2a46b1
Compare
07b3c1e to
8c3e021
Compare
b2a46b1 to
429f80e
Compare
8c3e021 to
28d1bc4
Compare
asaf-sw
left a comment
There was a problem hiding this comment.
@asaf-sw+AGNT made 2 comments.
Reviewable status: 0 of 4 files reviewed, 2 unresolved discussions (waiting on matanl-starkware).
crates/apollo_l1_gas_price_config/src/config.rs line 297 at r2 (raw file):
Previously, matanl-starkware (Matan Lior) wrote…
Please explain with respect to the member names in plain English
Done, rewritten to name the fields:
/// Rejects a window whose two bounds are swapped: `max_future_updated_at_seconds` covers clock
/// skew, so it must sit strictly below `max_staleness_seconds`, which covers a full feed heartbeat.
crates/apollo_l1_gas_price_config/src/config.rs line 342 at r2 (raw file):
Previously, matanl-starkware (Matan Lior) wrote…
I don't understand why we don't have this type of struct:
pub struct PairConfig (choose appropriate name):
{
pub address: ContractAddress,
pub bounds: RateBounds,
}
Grouping address with bounds does not fit, for one concrete reason: there are three bounded pairs and only two feeds. AllRateBoundsConfig bounds eth_usd, strk_usd and the derived eth_strk, which has no feed address and never will, since it is computed from the two USD legs. A PairConfig { address, bounds } has no value to put in address for that pair.
The two also have different lifetimes and owners, which is why #14982 split them out in the first place: the bounds describe the rate ("ETH is plausibly $20 to $50,000" is true whoever reports it) and survive the HTTP oracle removal untouched, while the feed addresses are Chainlink-specific and die with Chainlink. Folding them back means moving live config keys the day either one goes.
The grouping you are describing does exist, one layer up, at the point of use. ChainlinkFeeds::eth_usd_feed(&bounds_config) / strk_usd_feed(&bounds_config) assemble exactly that struct per pair, in #14990:
pub(super) struct PairFeed {
feed_address: ContractAddress,
bounds: RateBounds,
freshness: FreshnessWindow,
}So read_feed takes one value carrying the address, the bounds and the pair, and there is one method per pair Chainlink actually quotes, which makes a read for the derived pair unrepresentable. I added a line to ChainlinkOracleConfig's doc pointing at this, since the split is not obvious from the struct alone:
/// Holds only what is Chainlink-specific: the bounds a feed's answer is judged against describe
/// the rate rather than the source, so they live in `AllRateBoundsConfig`, which also bounds the
/// derived ETH/STRK pair that has no feed of its own.
Happy to group the per-feed Chainlink settings if more of them ever appear, but today the address is the only one, so the struct would be a one-field wrapper.
matanl-starkware
left a comment
There was a problem hiding this comment.
@matanl-starkware reviewed 4 files and all commit messages, and resolved 2 discussions.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on asaf-sw).
429f80e to
d24c00c
Compare
28d1bc4 to
b55e49f
Compare
asaf-sw
left a comment
There was a problem hiding this comment.
@asaf-sw reviewed 4 files and all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on asaf-sw).
d24c00c to
cc9f8cf
Compare
b55e49f to
194eef0
Compare
194eef0 to
7bf91db
Compare
Merge activity
|

Adds
ChainlinkOracleConfig, the mechanics half of the Chainlink feed source: the two mainnet proxyfeed_addresses, theFreshnessWindowa round'supdated_atmust fall in, a 900 secondsampling_interval_secondsand a 60 secondfailure_retry_interval_seconds, with a validator keeping the forward freshness bound strictly below the backward one.A6b of the split of #14942. The rate bounds that sit alongside these fields on the source branch were extracted into
RateBoundsConfigin the base PR, so this carries only Chainlink-specific fields.sampling_interval_secondsis deliberately a new field: the source branch read the HTTP source'slag_interval_secondsinstead, so the Chainlink path no longer reaches into the HTTP config and deleting that source later stays a pure deletion.config_schema.jsonand the app configs are untouched until B2 (apollo_l1_gas_price_config,apollo_deployments,apollo_node: nest the Chainlink config #14994).Detailed Summary for AI Bots
Adds
ChainlinkOracleConfig, the mechanics half of the Chainlink price-feed source: the two mainnet proxyfeed_addresses, theFreshnessWindowa round'supdated_atmust fall in, and the two intervals the source is read on.The rate bounds that live alongside these fields in the original branch were already extracted into
RateBoundsConfigin the base PR, so this one carries only the Chainlink-specific fields.Fields
eth_usd_feed_address/strk_usd_feed_address: Chainlink proxy addresses on Starknet mainnet. The proxies rather than the aggregators behind them, because aggregators are rotated without notice.freshness:max_staleness_seconds(the 24h feed heartbeat plus an hour of margin) andmax_future_updated_at_seconds(300s of clock skew). A schema-level validator keeps the forward bound strictly below the backward one, since both are plain second counts and exchanging them would otherwise pass every per-field check.sampling_interval_seconds: 900 by default,range(min = 1).failure_retry_interval_seconds: 60 by default,range(min = 1).sampling_interval_secondsis deliberately newIn the source branch, the Chainlink factory read the sampling interval off the HTTP source's
ExchangeRateOracleConfig::lag_interval_seconds. This PR replaces that read with a field of its own, for two reasons:It is one field on
ChainlinkOracleConfig, not one per feed, since both feeds are sampled on the same interval.Scope
Nothing reads this config yet; the client that reads the feeds arrives in a later PR, and the source is wired in after that.
config_schema.jsonand theapollo_deploymentsapp configs are untouched here as well: the config is still un-nested, and it reaches the schema and the app configs when it is nested underL1GasPriceProviderConfig.Tests cover the default validating, the two zero-interval rejections, the
sampling_interval_secondsrange at 0 and 1, the default freshness window pinned by direction, and an inverted or equal freshness window.