-
Notifications
You must be signed in to change notification settings - Fork 183
Publish native price estimates to the event bus #4688
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| use {crate::Event, schemars::JsonSchema, serde::Serialize}; | ||
|
|
||
| /// Emitted once per estimator taking part in a native price competition, as | ||
| /// soon as that estimator returns. Because the native price cache absorbs the | ||
| /// vast majority of lookups, these events describe the price *refreshes* that | ||
| /// actually reached an estimator, not every native price the protocol used. | ||
| #[derive(Serialize, JsonSchema)] | ||
| #[serde(rename_all = "camelCase")] | ||
| pub struct NativePriceEstimateEvent { | ||
| /// Token the price was estimated for (hex-encoded, including the `0x` | ||
| /// prefix). For tokens configured to be approximated by another token this | ||
| /// is the approximation token, i.e. the one actually priced. | ||
| pub token: String, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addresses are serialized correctly and take less space than the string, replace the type |
||
| /// Timeout granted to the estimator's competition stage, in milliseconds. | ||
| pub timeout: u64, | ||
| /// Wall-clock time the estimator actually spent, in milliseconds. | ||
| pub elapsed: u64, | ||
| pub estimator: String, | ||
| pub result: NativePriceResult, | ||
| } | ||
|
|
||
| impl Event for NativePriceEstimateEvent { | ||
| const SUBJECT: &'static str = "nativePriceEstimate"; | ||
| } | ||
|
|
||
| #[derive(Serialize, JsonSchema)] | ||
| #[serde(untagged)] | ||
| pub enum NativePriceResult { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the regular Result<f64, Error> would work here Don't forget to assign this to an estimator 🤔 |
||
| Ok { | ||
| /// Amount of native token needed to buy 1 unit of the token. Always a | ||
| /// normal, positive float: malformed prices are reported as errors. | ||
| price: f64, | ||
| }, | ||
| Err { | ||
| error: String, | ||
| }, | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use {super::*, serde_json::json}; | ||
|
|
||
| #[test] | ||
| fn matches_wire_format() { | ||
| let event = NativePriceEstimateEvent { | ||
| token: "0x01".into(), | ||
| timeout: 5000, | ||
| elapsed: 12, | ||
| estimator: "CoinGecko".into(), | ||
| result: NativePriceResult::Ok { price: 1.5e-13 }, | ||
| }; | ||
| assert_eq!( | ||
| serde_json::to_value(&event).unwrap(), | ||
| json!({ | ||
| "token": "0x01", | ||
| "timeout": 5000, | ||
| "elapsed": 12, | ||
| "estimator": "CoinGecko", | ||
| "result": { | ||
| "price": 1.5e-13, | ||
| }, | ||
| }), | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn error_variant_is_untagged() { | ||
| let result = NativePriceResult::Err { | ||
| error: "boom".into(), | ||
| }; | ||
| assert_eq!( | ||
| serde_json::to_value(&result).unwrap(), | ||
| json!({ "error": "boom" }), | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| use {crate::Event, schemars::JsonSchema, serde::Serialize}; | ||
|
|
||
| /// Emitted once a native price competition has picked the winning estimate, | ||
| /// i.e. the price that gets cached and used to price orders. Its job is | ||
| /// correlation: among the [`crate::NativePriceEstimateEvent`]s emitted for the | ||
| /// same token around the same time, the winning one is the one whose | ||
| /// `estimator` matches this event. | ||
| /// | ||
| /// At most one is emitted per competition, as all estimators may have errored | ||
| /// in which case there is no winner. | ||
| #[derive(Serialize, JsonSchema)] | ||
| #[serde(rename_all = "camelCase")] | ||
| pub struct WinningNativePriceEstimateEvent { | ||
| /// Token the price was estimated for (hex-encoded, including the `0x` | ||
| /// prefix). | ||
| pub token: String, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto on the token/address thing |
||
| /// Name of the estimator whose price estimate won the competition. | ||
| pub estimator: String, | ||
| } | ||
|
|
||
| impl Event for WinningNativePriceEstimateEvent { | ||
| const SUBJECT: &'static str = "winningNativePriceEstimate"; | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use {super::*, serde_json::json}; | ||
|
|
||
| #[test] | ||
| fn matches_wire_format() { | ||
| let event = WinningNativePriceEstimateEvent { | ||
| token: "0x01".into(), | ||
| estimator: "CoinGecko".into(), | ||
| }; | ||
| assert_eq!( | ||
| serde_json::to_value(&event).unwrap(), | ||
| json!({ | ||
| "token": "0x01", | ||
| "estimator": "CoinGecko", | ||
| }), | ||
| ); | ||
| } | ||
| } | ||
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.
For now, we should just publish and filter later, so this should be removed