-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Rename oracle to slinky, refactor mm provider factory #272
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #272 +/- ##
==========================================
+ Coverage 62.11% 62.34% +0.22%
==========================================
Files 215 215
Lines 9503 9475 -28
==========================================
+ Hits 5903 5907 +4
+ Misses 3055 3023 -32
Partials 545 545 ☔ View full report in Codecov by Sentry. |
apiDataHandler, err = dydx.NewAPIHandler(cfg.API) | ||
ids = []types.Chain{{ChainID: dydx.ChainID}} | ||
default: | ||
return nil, fmt.Errorf("unknown provider: %s", cfg.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case should return the default marketmap API handler that hits x/marketemap
right?
or is the idea that we'll fill this info out later after the refactor?
@@ -132,6 +132,10 @@ func runOracle() error { | |||
orchestrator.WithMarketMap(marketCfg), | |||
orchestrator.WithPriceAPIQueryHandlerFactory(oraclefactory.APIQueryHandlerFactory), // Replace with custom API query handler factory. | |||
orchestrator.WithPriceWebSocketQueryHandlerFactory(oraclefactory.WebSocketQueryHandlerFactory), // Replace with custom websocket query handler factory. | |||
orchestrator.WithMarketMapperFactory(oraclefactory.MarketMapProviderFactory), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need the marketmap provider factory to only be included in the dYdX options because it will either run the mm provider and update based on what is on dYdX main-net or it will fail to be constructed if the market map provider is not included in the oracle config. There is probably a cleaner way with dealing how to run this based per chain and whether the mm provider is desired. But I'm assuming this isnt desired behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused why this even needs to be an option? Shouldn't we be able to have casing logic like websocket / api, and have the default be a nop updater (no mm-provider? Or a mm provider that never updates)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an option that lets the orchestrator know how to construct a market map provider if one is included in the oracle.json. Reading through this again I think this looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The factories take care of casing based on the API/Websocket implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
given that the mm provider is only going to be utilized by dYdX for the time being, we need to move back into dYdXOptions
switch cfg.Name { | ||
case dydx.Name: | ||
apiDataHandler, err = dydx.NewAPIHandler(cfg.API) | ||
ids = []types.Chain{{ChainID: dydx.ChainID}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how this is used right now, but it feels like we don't really need the chain-id as long as we point the mm provider at the correct node?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya, how would our configs work if we have a market-map for multiple chains? Have we even resolved this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea this is currently hard coded based on the desired chain but it doesnt really matter since all you have to do is point it to the correct URL. The providers were purposfully designed to assume you have inputs when constructing URLs, but in the future we can probably make it allow static or no entries.
Approach I ended up with:
Slinky requires a valid oracle.json path. Has optional flags,
|
@@ -132,6 +132,10 @@ func runOracle() error { | |||
orchestrator.WithMarketMap(marketCfg), | |||
orchestrator.WithPriceAPIQueryHandlerFactory(oraclefactory.APIQueryHandlerFactory), // Replace with custom API query handler factory. | |||
orchestrator.WithPriceWebSocketQueryHandlerFactory(oraclefactory.WebSocketQueryHandlerFactory), // Replace with custom websocket query handler factory. | |||
orchestrator.WithMarketMapperFactory(oraclefactory.MarketMapProviderFactory), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused why this even needs to be an option? Shouldn't we be able to have casing logic like websocket / api, and have the default be a nop updater (no mm-provider? Or a mm provider that never updates)
@@ -129,29 +123,33 @@ func runOracle() error { | |||
} | |||
|
|||
metrics := oraclemetrics.NewMetricsFromConfig(cfg.Metrics) | |||
aggregator, err := oraclemath.NewMedianAggregator( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we agreed to have a single aggregation strat in the oracle (the dydx one)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the dydx aggregation.
switch cfg.Name { | ||
case dydx.Name: | ||
apiDataHandler, err = dydx.NewAPIHandler(cfg.API) | ||
ids = []types.Chain{{ChainID: dydx.ChainID}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya, how would our configs work if we have a market-map for multiple chains? Have we even resolved this?
tickersToPaths[tickerStr] = mmtypes.Paths{} | ||
} | ||
paths := tickersToPaths[tickerStr].Paths | ||
paths = append(paths, mmtypes.Path{Operations: []mmtypes.Operation{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're medianizing over all paths, no? This would give extra weight to the raw feed if it alr existed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just a pure median over all feeds with optional 1 hop inversion.
) | ||
rootCmd.Flags().StringVarP( | ||
&nodeURL, | ||
"node-http-url", | ||
"", | ||
"", | ||
"http endpoint of the cosmos sdk node corresponding to the chain id (typically something like localhost:1317). this should only be specified if required by the chain.", | ||
"Http endpoint of the cosmos sdk node corresponding to the chain (typically localhost:1317 or a remote API). This should only be specified if required by the chain.", | ||
) | ||
rootCmd.Flags().StringVarP( | ||
&host, | ||
"host", | ||
"", | ||
"0.0.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we checking that the default value isn't used if no chain is given here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is only used if dydx chain is specified otherwise it's ignored at the moment.
@@ -38,11 +38,6 @@ func NewMedianAggregator( | |||
return nil, err | |||
} | |||
|
|||
if cfg.AggregationType != mmtypes.AggregationType_INDEX_PRICE_AGGREGATION { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we can't remove the agg-type from the config, now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left it since we're rewriting all of the mm stuff and deleting all the proto and tests didn't seem worth it at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason we need to remove this rn? From my perspective I put this in the case where operators accidentally use the wrong market.json file. this was an easy way to make sure things were configured correctly. the dYdX market params API constructs the market.json to include the field to be set correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supporting multiple aggregation types seems like a really bad idea in general. It will make it even harder to reason about how a price was determined and introduce potential for multi-modal behavior in our on chain prices based on a bug in one place but not another.
I also removed it because it was the one stateful piece of validation that was preventing us from bootstrapping the oracle without a market.json
config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea agree, multiple not gud. im fine making this change now
Co-authored-by: David Terpay <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're going to need to update the local market.json if we want to enforce that the single aggregation type is utilized otherwise any build is going to fail on start.
@davidterpay It's updated in this PR |
) | ||
rootCmd.Flags().DurationVarP( | ||
&updateInterval, | ||
"update-interval", | ||
"", | ||
500*time.Millisecond, | ||
"interval at which the oracle will update the prices. this should be set to the interval desired by the chain.", | ||
"Interval at which the oracle will update the prices. This should be set to the interval desired by the chain.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make sure that this is set to 500 milliseconds
This PR renames
./build/oracle => ./build/slinky
.It also refactors the marketmap provider factory to be more in line with the other factories (websocket and API). The idea being that once we remove the
aggregator
bit, we can get rid of all of the special casing for dYdX and rely on the factory to construct the proper marketmap provider for any chain we support.I've pointed this PR at the
eric/convert-everything-to-cobra
branch since it made sense to change these in the context of the cobra refactor.