From 87f155c1ac1f5b4450057e67a93e8944e5cccb5e Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 16:59:17 +0100 Subject: [PATCH 01/13] go --- apps/hermes/server/src/api.rs | 1 + apps/hermes/server/src/api/rest.rs | 2 ++ apps/hermes/server/src/state/aggregate.rs | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/apps/hermes/server/src/api.rs b/apps/hermes/server/src/api.rs index 64c22907e5..2e03286444 100644 --- a/apps/hermes/server/src/api.rs +++ b/apps/hermes/server/src/api.rs @@ -150,6 +150,7 @@ where .route("/api/get_price_feed", get(rest::get_price_feed)) .route("/api/get_vaa", get(rest::get_vaa)) .route("/api/get_vaa_ccip", get(rest::get_vaa_ccip)) + .route("/api/get_publisher_stake_caps_message", get(rest::get_publisher_stake_caps_message)) .route("/api/latest_price_feeds", get(rest::latest_price_feeds)) .route("/api/latest_vaas", get(rest::latest_vaas)) .route("/api/price_feed_ids", get(rest::price_feed_ids)) diff --git a/apps/hermes/server/src/api/rest.rs b/apps/hermes/server/src/api/rest.rs index cdc3584226..928947e601 100644 --- a/apps/hermes/server/src/api/rest.rs +++ b/apps/hermes/server/src/api/rest.rs @@ -14,6 +14,7 @@ use { mod get_price_feed; mod get_vaa; mod get_vaa_ccip; +mod get_publisher_stake_caps_message; mod index; mod latest_price_feeds; mod latest_vaas; @@ -27,6 +28,7 @@ pub use { get_price_feed::*, get_vaa::*, get_vaa_ccip::*, + get_publisher_stake_caps_message::*, index::*, latest_price_feeds::*, latest_vaas::*, diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index 7c2cb2591d..215979abba 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -3,6 +3,7 @@ use mock_instant::{ SystemTime, UNIX_EPOCH, }; +use pythnet_sdk::messages::PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID; #[cfg(not(test))] use std::time::{ SystemTime, @@ -242,6 +243,10 @@ where price_ids: &[PriceIdentifier], request_time: RequestTime, ) -> Result; + async fn get_publisher_stake_caps_update_data( + &self + ) -> Result>>; + } /// Allow downcasting State into CacheState for functions that depend on the `Cache` service. @@ -403,6 +408,21 @@ where } } + async fn get_publisher_stake_caps_update_data( + &self + ) -> Result>> { + let messages = self + .fetch_message_states( + vec![PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID], + RequestTime::Latest, + MessageStateFilter::Only(MessageType::PublisherStakeCapsMessage), + ) + .await?; + + let update_data = construct_update_data(messages.into_iter().map(|m| m.into()).collect())?; + Ok(update_data) + } + async fn get_price_feed_ids(&self) -> HashSet { Cache::message_state_keys(self) .await From 7872ba40f7e3664307e517ba50ceaa61fa2bc4ae Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 17:00:05 +0100 Subject: [PATCH 02/13] go --- apps/hermes/server/src/api.rs | 5 +- apps/hermes/server/src/api/rest.rs | 4 +- .../rest/get_publisher_stake_caps_message.rs | 80 +++++++++++++++++++ apps/hermes/server/src/state/aggregate.rs | 27 +++---- 4 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs diff --git a/apps/hermes/server/src/api.rs b/apps/hermes/server/src/api.rs index 2e03286444..d1a7936e44 100644 --- a/apps/hermes/server/src/api.rs +++ b/apps/hermes/server/src/api.rs @@ -150,7 +150,10 @@ where .route("/api/get_price_feed", get(rest::get_price_feed)) .route("/api/get_vaa", get(rest::get_vaa)) .route("/api/get_vaa_ccip", get(rest::get_vaa_ccip)) - .route("/api/get_publisher_stake_caps_message", get(rest::get_publisher_stake_caps_message)) + .route( + "/api/get_publisher_stake_caps_message", + get(rest::get_publisher_stake_caps_message), + ) .route("/api/latest_price_feeds", get(rest::latest_price_feeds)) .route("/api/latest_vaas", get(rest::latest_vaas)) .route("/api/price_feed_ids", get(rest::price_feed_ids)) diff --git a/apps/hermes/server/src/api/rest.rs b/apps/hermes/server/src/api/rest.rs index 928947e601..3c10f4d830 100644 --- a/apps/hermes/server/src/api/rest.rs +++ b/apps/hermes/server/src/api/rest.rs @@ -12,9 +12,9 @@ use { }; mod get_price_feed; +mod get_publisher_stake_caps_message; mod get_vaa; mod get_vaa_ccip; -mod get_publisher_stake_caps_message; mod index; mod latest_price_feeds; mod latest_vaas; @@ -26,9 +26,9 @@ mod v2; pub use { get_price_feed::*, + get_publisher_stake_caps_message::*, get_vaa::*, get_vaa_ccip::*, - get_publisher_stake_caps_message::*, index::*, latest_price_feeds::*, latest_vaas::*, diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs new file mode 100644 index 0000000000..36dda19f8b --- /dev/null +++ b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs @@ -0,0 +1,80 @@ +use { + crate::{ + api::{ + rest::RestError, + types::{ + BinaryPriceUpdate, + EncodingType, + }, + ApiState, + }, + state::Aggregates, + }, + anyhow::Result, + axum::{ + extract::State, + Json, + }, + base64::{ + engine::general_purpose::STANDARD as base64_standard_engine, + Engine as _, + }, + serde::Deserialize, + serde_qs::axum::QsQuery, + utoipa::IntoParams, +}; + +#[derive(Debug, Deserialize, IntoParams)] +#[into_params(parameter_in=Query)] +pub struct GetPublisherStakeCapsMessageQueryParams { + /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. + #[serde(default)] + encoding: EncodingType, +} + +/// Get the publisher stake caps message +/// +#[utoipa::path( + get, + path = "/api/get_publisher_stake_caps_message", + responses( + (status = 200, description = "Publisher stake caps message retrieved succesfully", body = Vec) + ), + params( + GetPublisherStakeCapsMessageQueryParams + ) +)] +pub async fn get_publisher_stake_caps_message( + State(state): State>, + QsQuery(params): QsQuery, +) -> Result, RestError> +where + S: Aggregates, +{ + let state = &state.state; + let publisher_update_caps_data = + state + .get_publisher_stake_caps_update_data() + .await + .map_err(|e| { + tracing::warn!("RPC connection error: {}", e); + RestError::RpcConnectionError { + message: format!("RPC connection error: {}", e), + } + })?; + + let encoded_data: Vec = publisher_update_caps_data + .into_iter() + .map(|data| match params.encoding { + EncodingType::Base64 => base64_standard_engine.encode(data), + EncodingType::Hex => hex::encode(data), + }) + .collect(); + + let binary_price_update = BinaryPriceUpdate { + encoding: params.encoding, + data: encoded_data, + }; + + Ok(Json(binary_price_update)) +} diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index 215979abba..440bc965db 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -3,7 +3,6 @@ use mock_instant::{ SystemTime, UNIX_EPOCH, }; -use pythnet_sdk::messages::PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID; #[cfg(not(test))] use std::time::{ SystemTime, @@ -46,6 +45,7 @@ use { messages::{ Message, MessageType, + PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID, }, wire::{ from_slice, @@ -243,10 +243,7 @@ where price_ids: &[PriceIdentifier], request_time: RequestTime, ) -> Result; - async fn get_publisher_stake_caps_update_data( - &self - ) -> Result>>; - + async fn get_publisher_stake_caps_update_data(&self) -> Result>>; } /// Allow downcasting State into CacheState for functions that depend on the `Cache` service. @@ -408,19 +405,17 @@ where } } - async fn get_publisher_stake_caps_update_data( - &self - ) -> Result>> { + async fn get_publisher_stake_caps_update_data(&self) -> Result>> { let messages = self - .fetch_message_states( - vec![PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID], - RequestTime::Latest, - MessageStateFilter::Only(MessageType::PublisherStakeCapsMessage), - ) - .await?; + .fetch_message_states( + vec![PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID], + RequestTime::Latest, + MessageStateFilter::Only(MessageType::PublisherStakeCapsMessage), + ) + .await?; - let update_data = construct_update_data(messages.into_iter().map(|m| m.into()).collect())?; - Ok(update_data) + let update_data = construct_update_data(messages.into_iter().map(|m| m.into()).collect())?; + Ok(update_data) } async fn get_price_feed_ids(&self) -> HashSet { From 7dc0c8a580901f5ffdc6ca1d96a3201427f916ed Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 21:28:00 +0100 Subject: [PATCH 03/13] works --- apps/hermes/server/Cargo.lock | 51 +++++++++++++++-- apps/hermes/server/Cargo.toml | 1 + .../rest/get_publisher_stake_caps_message.rs | 29 ++++++++-- apps/hermes/server/src/api/types.rs | 9 +++ apps/hermes/server/src/state/aggregate.rs | 55 +++++++++++++++++-- 5 files changed, 131 insertions(+), 14 deletions(-) diff --git a/apps/hermes/server/Cargo.lock b/apps/hermes/server/Cargo.lock index de2e07082d..147db2f6af 100644 --- a/apps/hermes/server/Cargo.lock +++ b/apps/hermes/server/Cargo.lock @@ -557,6 +557,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -1218,6 +1224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1832,6 +1839,7 @@ dependencies = [ "serde", "serde_json", "serde_qs", + "serde_with 3.9.0", "serde_wormhole", "sha3 0.10.8", "solana-account-decoder", @@ -2097,6 +2105,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -3893,7 +3902,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" dependencies = [ "serde", - "serde_with_macros", + "serde_with_macros 2.3.3", +] + +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.6", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros 3.9.0", + "time", ] [[package]] @@ -3908,6 +3935,18 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "serde_with_macros" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +dependencies = [ + "darling", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.55", +] + [[package]] name = "serde_wormhole" version = "0.1.0" @@ -4608,7 +4647,7 @@ dependencies = [ "serde_bytes", "serde_derive", "serde_json", - "serde_with", + "serde_with 2.3.3", "sha2 0.10.8", "sha3 0.10.8", "solana-frozen-abi", @@ -5243,9 +5282,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -5264,9 +5303,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", diff --git a/apps/hermes/server/Cargo.toml b/apps/hermes/server/Cargo.toml index 2f376d1b6e..6401570791 100644 --- a/apps/hermes/server/Cargo.toml +++ b/apps/hermes/server/Cargo.toml @@ -55,6 +55,7 @@ wormhole-sdk = { git = "https://github.com/wormhole-foundation/wormhol solana-client = { version = "=1.16.19" } solana-sdk = { version = "=1.16.19" } solana-account-decoder = { version = "=1.16.19" } +serde_with = "3.9.0" [build-dependencies] diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs index 36dda19f8b..ead28247a3 100644 --- a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs +++ b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs @@ -5,10 +5,14 @@ use { types::{ BinaryPriceUpdate, EncodingType, + PublisherStakeCapsUpdateResponse, }, ApiState, }, - state::Aggregates, + state::{ + aggregate::PublisherStakeCapsUpdate, + Aggregates, + }, }, anyhow::Result, axum::{ @@ -24,14 +28,24 @@ use { utoipa::IntoParams, }; + #[derive(Debug, Deserialize, IntoParams)] #[into_params(parameter_in=Query)] pub struct GetPublisherStakeCapsMessageQueryParams { /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. #[serde(default)] encoding: EncodingType, + + /// If true, include the parsed price update in the `parsed` field of each returned feed. Default is `true`. + #[serde(default = "default_true")] + parsed: bool, +} + +fn default_true() -> bool { + true } + /// Get the publisher stake caps message /// #[utoipa::path( @@ -47,7 +61,7 @@ pub struct GetPublisherStakeCapsMessageQueryParams { pub async fn get_publisher_stake_caps_message( State(state): State>, QsQuery(params): QsQuery, -) -> Result, RestError> +) -> Result, RestError> where S: Aggregates, { @@ -64,6 +78,7 @@ where })?; let encoded_data: Vec = publisher_update_caps_data + .update_data .into_iter() .map(|data| match params.encoding { EncodingType::Base64 => base64_standard_engine.encode(data), @@ -71,10 +86,16 @@ where }) .collect(); - let binary_price_update = BinaryPriceUpdate { + let binary = BinaryPriceUpdate { encoding: params.encoding, data: encoded_data, }; - Ok(Json(binary_price_update)) + let parsed: Option> = if params.parsed { + Some(publisher_update_caps_data.publisher_stake_caps) + } else { + None + }; + + Ok(Json(PublisherStakeCapsUpdateResponse { binary, parsed })) } diff --git a/apps/hermes/server/src/api/types.rs b/apps/hermes/server/src/api/types.rs index 5096c2a619..9882012abd 100644 --- a/apps/hermes/server/src/api/types.rs +++ b/apps/hermes/server/src/api/types.rs @@ -3,6 +3,7 @@ use { crate::state::aggregate::{ PriceFeedUpdate, PriceFeedsWithUpdateData, + PublisherStakeCapsUpdate, Slot, UnixTimestamp, }, @@ -40,6 +41,7 @@ use { wormhole_sdk::Chain, }; + /// A price id is a 32-byte hex string, optionally prefixed with "0x". /// Price ids are case insensitive. /// @@ -271,6 +273,13 @@ impl From for ParsedPriceUpdate { } } +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct PublisherStakeCapsUpdateResponse { + pub binary: BinaryPriceUpdate, + #[serde(skip_serializing_if = "Option::is_none")] + pub parsed: Option>, +} + #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct PriceUpdate { pub binary: BinaryPriceUpdate, diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index 440bc965db..70842c9e60 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -56,6 +56,11 @@ use { }, }, serde::Serialize, + serde_with::{ + serde_as, + DisplayFromStr, + }, + solana_sdk::pubkey::Pubkey, std::{ collections::HashSet, time::Duration, @@ -69,7 +74,6 @@ use { }, wormhole_sdk::Vaa, }; - pub mod metrics; pub mod wormhole_merkle; @@ -210,12 +214,31 @@ pub struct PriceFeedUpdate { pub prev_publish_time: Option, } +#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] +pub struct PublisherStakeCapsUpdate { + pub publisher_stake_caps: Vec, +} + +#[serde_as] +#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] +pub struct SerdePublisherStakeCap { + #[serde_as(as = "DisplayFromStr")] + pub publisher: Pubkey, + pub cap: u64, +} + #[derive(Debug, PartialEq)] pub struct PriceFeedsWithUpdateData { pub price_feeds: Vec, pub update_data: Vec>, } +#[derive(Debug, PartialEq)] +pub struct PublisherStakeCapsWithUpdateData { + pub publisher_stake_caps: Vec, + pub update_data: Vec>, +} + #[derive(Debug, Serialize)] pub struct ReadinessMetadata { pub has_completed_recently: bool, @@ -243,7 +266,9 @@ where price_ids: &[PriceIdentifier], request_time: RequestTime, ) -> Result; - async fn get_publisher_stake_caps_update_data(&self) -> Result>>; + async fn get_publisher_stake_caps_update_data( + &self, + ) -> Result; } /// Allow downcasting State into CacheState for functions that depend on the `Cache` service. @@ -405,7 +430,9 @@ where } } - async fn get_publisher_stake_caps_update_data(&self) -> Result>> { + async fn get_publisher_stake_caps_update_data( + &self, + ) -> Result { let messages = self .fetch_message_states( vec![PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID], @@ -414,8 +441,28 @@ where ) .await?; + let publisher_stake_caps = messages + .iter() + .map(|message_state| match message_state.message.clone() { + Message::PublisherStakeCapsMessage(message) => Ok(PublisherStakeCapsUpdate { + publisher_stake_caps: message + .caps + .iter() + .map(|cap| SerdePublisherStakeCap { + publisher: Pubkey::from(cap.publisher), + cap: cap.cap, + }) + .collect(), + }), + _ => Err(anyhow!("Invalid message state type")), + }) + .collect::>>()?; + let update_data = construct_update_data(messages.into_iter().map(|m| m.into()).collect())?; - Ok(update_data) + Ok(PublisherStakeCapsWithUpdateData { + publisher_stake_caps, + update_data, + }) } async fn get_price_feed_ids(&self) -> HashSet { From 49cc664b0ebe80a9feb0a11be760c74b59b888a8 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 21:31:23 +0100 Subject: [PATCH 04/13] go --- apps/hermes/server/src/api.rs | 4 +- apps/hermes/server/src/api/rest.rs | 4 +- .../rest/get_publisher_stake_caps_message.rs | 101 ------------------ 3 files changed, 4 insertions(+), 105 deletions(-) delete mode 100644 apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs diff --git a/apps/hermes/server/src/api.rs b/apps/hermes/server/src/api.rs index d1a7936e44..e7cbbf84e3 100644 --- a/apps/hermes/server/src/api.rs +++ b/apps/hermes/server/src/api.rs @@ -151,8 +151,8 @@ where .route("/api/get_vaa", get(rest::get_vaa)) .route("/api/get_vaa_ccip", get(rest::get_vaa_ccip)) .route( - "/api/get_publisher_stake_caps_message", - get(rest::get_publisher_stake_caps_message), + "/api/get_publisher_stake_caps_update_data", + get(rest::get_publisher_stake_caps_update_data), ) .route("/api/latest_price_feeds", get(rest::latest_price_feeds)) .route("/api/latest_vaas", get(rest::latest_vaas)) diff --git a/apps/hermes/server/src/api/rest.rs b/apps/hermes/server/src/api/rest.rs index 3c10f4d830..a40e5608c3 100644 --- a/apps/hermes/server/src/api/rest.rs +++ b/apps/hermes/server/src/api/rest.rs @@ -12,7 +12,7 @@ use { }; mod get_price_feed; -mod get_publisher_stake_caps_message; +mod get_publisher_stake_caps_update_data; mod get_vaa; mod get_vaa_ccip; mod index; @@ -26,7 +26,7 @@ mod v2; pub use { get_price_feed::*, - get_publisher_stake_caps_message::*, + get_publisher_stake_caps_update_data::*, get_vaa::*, get_vaa_ccip::*, index::*, diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs deleted file mode 100644 index ead28247a3..0000000000 --- a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_message.rs +++ /dev/null @@ -1,101 +0,0 @@ -use { - crate::{ - api::{ - rest::RestError, - types::{ - BinaryPriceUpdate, - EncodingType, - PublisherStakeCapsUpdateResponse, - }, - ApiState, - }, - state::{ - aggregate::PublisherStakeCapsUpdate, - Aggregates, - }, - }, - anyhow::Result, - axum::{ - extract::State, - Json, - }, - base64::{ - engine::general_purpose::STANDARD as base64_standard_engine, - Engine as _, - }, - serde::Deserialize, - serde_qs::axum::QsQuery, - utoipa::IntoParams, -}; - - -#[derive(Debug, Deserialize, IntoParams)] -#[into_params(parameter_in=Query)] -pub struct GetPublisherStakeCapsMessageQueryParams { - /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. - #[serde(default)] - encoding: EncodingType, - - /// If true, include the parsed price update in the `parsed` field of each returned feed. Default is `true`. - #[serde(default = "default_true")] - parsed: bool, -} - -fn default_true() -> bool { - true -} - - -/// Get the publisher stake caps message -/// -#[utoipa::path( - get, - path = "/api/get_publisher_stake_caps_message", - responses( - (status = 200, description = "Publisher stake caps message retrieved succesfully", body = Vec) - ), - params( - GetPublisherStakeCapsMessageQueryParams - ) -)] -pub async fn get_publisher_stake_caps_message( - State(state): State>, - QsQuery(params): QsQuery, -) -> Result, RestError> -where - S: Aggregates, -{ - let state = &state.state; - let publisher_update_caps_data = - state - .get_publisher_stake_caps_update_data() - .await - .map_err(|e| { - tracing::warn!("RPC connection error: {}", e); - RestError::RpcConnectionError { - message: format!("RPC connection error: {}", e), - } - })?; - - let encoded_data: Vec = publisher_update_caps_data - .update_data - .into_iter() - .map(|data| match params.encoding { - EncodingType::Base64 => base64_standard_engine.encode(data), - EncodingType::Hex => hex::encode(data), - }) - .collect(); - - let binary = BinaryPriceUpdate { - encoding: params.encoding, - data: encoded_data, - }; - - let parsed: Option> = if params.parsed { - Some(publisher_update_caps_data.publisher_stake_caps) - } else { - None - }; - - Ok(Json(PublisherStakeCapsUpdateResponse { binary, parsed })) -} From b031a34067f211ddc38c8a038e2fbfad8874fd47 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 21:33:10 +0100 Subject: [PATCH 05/13] add this file too --- .../get_publisher_stake_caps_update_data.rs | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs new file mode 100644 index 0000000000..45dfb39984 --- /dev/null +++ b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs @@ -0,0 +1,101 @@ +use { + crate::{ + api::{ + rest::RestError, + types::{ + BinaryPriceUpdate, + EncodingType, + PublisherStakeCapsUpdateResponse, + }, + ApiState, + }, + state::{ + aggregate::PublisherStakeCapsUpdate, + Aggregates, + }, + }, + anyhow::Result, + axum::{ + extract::State, + Json, + }, + base64::{ + engine::general_purpose::STANDARD as base64_standard_engine, + Engine as _, + }, + serde::Deserialize, + serde_qs::axum::QsQuery, + utoipa::IntoParams, +}; + + +#[derive(Debug, Deserialize, IntoParams)] +#[into_params(parameter_in=Query)] +pub struct GetPublisherStakeCapsMessageQueryParams { + /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. + #[serde(default)] + encoding: EncodingType, + + /// If true, include the parsed price update in the `parsed` field of each returned feed. Default is `true`. + #[serde(default = "default_true")] + parsed: bool, +} + +fn default_true() -> bool { + true +} + + +/// Get the publisher stake caps message +/// +#[utoipa::path( + get, + path = "/api/get_publisher_stake_caps_update_data", + responses( + (status = 200, description = "Publisher stake caps message retrieved succesfully", body = Vec) + ), + params( + GetPublisherStakeCapsMessageQueryParams + ) +)] +pub async fn get_publisher_stake_caps_update_data( + State(state): State>, + QsQuery(params): QsQuery, +) -> Result, RestError> +where + S: Aggregates, +{ + let state = &state.state; + let publisher_update_caps_data = + state + .get_publisher_stake_caps_update_data() + .await + .map_err(|e| { + tracing::warn!("RPC connection error: {}", e); + RestError::RpcConnectionError { + message: format!("RPC connection error: {}", e), + } + })?; + + let encoded_data: Vec = publisher_update_caps_data + .update_data + .into_iter() + .map(|data| match params.encoding { + EncodingType::Base64 => base64_standard_engine.encode(data), + EncodingType::Hex => hex::encode(data), + }) + .collect(); + + let binary = BinaryPriceUpdate { + encoding: params.encoding, + data: encoded_data, + }; + + let parsed: Option> = if params.parsed { + Some(publisher_update_caps_data.publisher_stake_caps) + } else { + None + }; + + Ok(Json(PublisherStakeCapsUpdateResponse { binary, parsed })) +} From bb71c4bd57d00083eab40272cf7f318de5b0c016 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 21:42:53 +0100 Subject: [PATCH 06/13] rename --- apps/hermes/server/src/api.rs | 2 +- .../get_publisher_stake_caps_update_data.rs | 46 ++++++++++--------- .../src/api/rest/v2/latest_price_updates.rs | 4 +- apps/hermes/server/src/api/rest/v2/sse.rs | 4 +- .../api/rest/v2/timestamp_price_updates.rs | 4 +- apps/hermes/server/src/api/types.rs | 8 ++-- apps/hermes/server/src/state/aggregate.rs | 4 +- 7 files changed, 37 insertions(+), 35 deletions(-) diff --git a/apps/hermes/server/src/api.rs b/apps/hermes/server/src/api.rs index e7cbbf84e3..b71bd27540 100644 --- a/apps/hermes/server/src/api.rs +++ b/apps/hermes/server/src/api.rs @@ -127,7 +127,7 @@ where types::RpcPriceIdentifier, types::EncodingType, types::PriceUpdate, - types::BinaryPriceUpdate, + types::BinaryUpdate, types::ParsedPriceUpdate, types::RpcPriceFeedMetadataV2, types::PriceFeedMetadata, diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs index 45dfb39984..34bf67f95e 100644 --- a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs +++ b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs @@ -3,9 +3,9 @@ use { api::{ rest::RestError, types::{ - BinaryPriceUpdate, + BinaryUpdate, EncodingType, - PublisherStakeCapsUpdateResponse, + GetPublisherStakeCapsUpdateDataResponse, }, ApiState, }, @@ -31,12 +31,12 @@ use { #[derive(Debug, Deserialize, IntoParams)] #[into_params(parameter_in=Query)] -pub struct GetPublisherStakeCapsMessageQueryParams { +pub struct GetPublisherStakeCapsUpdateData { /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. #[serde(default)] encoding: EncodingType, - /// If true, include the parsed price update in the `parsed` field of each returned feed. Default is `true`. + /// If true, include the parsed update in the `parsed` field of each returned feed. Default is `true`. #[serde(default = "default_true")] parsed: bool, } @@ -46,38 +46,37 @@ fn default_true() -> bool { } -/// Get the publisher stake caps message -/// +/// Get the publisher stake caps update data #[utoipa::path( get, path = "/api/get_publisher_stake_caps_update_data", responses( - (status = 200, description = "Publisher stake caps message retrieved succesfully", body = Vec) + (status = 200, description = "Publisher stake caps update data retrieved succesfully", body = Vec) ), params( - GetPublisherStakeCapsMessageQueryParams + GetPublisherStakeCapsUpdateData ) )] pub async fn get_publisher_stake_caps_update_data( State(state): State>, - QsQuery(params): QsQuery, -) -> Result, RestError> + QsQuery(params): QsQuery, +) -> Result, RestError> where S: Aggregates, { - let state = &state.state; - let publisher_update_caps_data = - state - .get_publisher_stake_caps_update_data() + let state = &*state.state; + let publisher_stake_caps_with_update_data = + Aggregates::get_publisher_stake_caps_with_update_data(state) .await .map_err(|e| { - tracing::warn!("RPC connection error: {}", e); - RestError::RpcConnectionError { - message: format!("RPC connection error: {}", e), - } + tracing::warn!( + "Error getting publisher stake caps with update data: {:?}", + e + ); + RestError::UpdateDataNotFound })?; - let encoded_data: Vec = publisher_update_caps_data + let encoded_data: Vec = publisher_stake_caps_with_update_data .update_data .into_iter() .map(|data| match params.encoding { @@ -86,16 +85,19 @@ where }) .collect(); - let binary = BinaryPriceUpdate { + let binary = BinaryUpdate { encoding: params.encoding, data: encoded_data, }; let parsed: Option> = if params.parsed { - Some(publisher_update_caps_data.publisher_stake_caps) + Some(publisher_stake_caps_with_update_data.publisher_stake_caps) } else { None }; - Ok(Json(PublisherStakeCapsUpdateResponse { binary, parsed })) + Ok(Json(GetPublisherStakeCapsUpdateDataResponse { + binary, + parsed, + })) } diff --git a/apps/hermes/server/src/api/rest/v2/latest_price_updates.rs b/apps/hermes/server/src/api/rest/v2/latest_price_updates.rs index f5ff341074..e0dbe68f1d 100644 --- a/apps/hermes/server/src/api/rest/v2/latest_price_updates.rs +++ b/apps/hermes/server/src/api/rest/v2/latest_price_updates.rs @@ -6,7 +6,7 @@ use { RestError, }, types::{ - BinaryPriceUpdate, + BinaryUpdate, EncodingType, ParsedPriceUpdate, PriceIdInput, @@ -108,7 +108,7 @@ where EncodingType::Hex => hex::encode(data), }) .collect(); - let binary_price_update = BinaryPriceUpdate { + let binary_price_update = BinaryUpdate { encoding: params.encoding, data: encoded_data, }; diff --git a/apps/hermes/server/src/api/rest/v2/sse.rs b/apps/hermes/server/src/api/rest/v2/sse.rs index 782cae3534..818bd689c5 100644 --- a/apps/hermes/server/src/api/rest/v2/sse.rs +++ b/apps/hermes/server/src/api/rest/v2/sse.rs @@ -6,7 +6,7 @@ use { RestError, }, types::{ - BinaryPriceUpdate, + BinaryUpdate, EncodingType, ParsedPriceUpdate, PriceIdInput, @@ -211,7 +211,7 @@ where .into_iter() .map(|data| encoding.encode_str(&data)) .collect(); - let binary_price_update = BinaryPriceUpdate { + let binary_price_update = BinaryUpdate { encoding, data: encoded_data, }; diff --git a/apps/hermes/server/src/api/rest/v2/timestamp_price_updates.rs b/apps/hermes/server/src/api/rest/v2/timestamp_price_updates.rs index 618227fc5a..7d5cdff09a 100644 --- a/apps/hermes/server/src/api/rest/v2/timestamp_price_updates.rs +++ b/apps/hermes/server/src/api/rest/v2/timestamp_price_updates.rs @@ -7,7 +7,7 @@ use { RestError, }, types::{ - BinaryPriceUpdate, + BinaryUpdate, EncodingType, ParsedPriceUpdate, PriceIdInput, @@ -123,7 +123,7 @@ where .into_iter() .map(|data| query_params.encoding.encode_str(&data)) .collect(); - let binary_price_update = BinaryPriceUpdate { + let binary_price_update = BinaryUpdate { encoding: query_params.encoding, data: encoded_data, }; diff --git a/apps/hermes/server/src/api/types.rs b/apps/hermes/server/src/api/types.rs index 9882012abd..c04490ebf2 100644 --- a/apps/hermes/server/src/api/types.rs +++ b/apps/hermes/server/src/api/types.rs @@ -233,7 +233,7 @@ impl EncodingType { } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] -pub struct BinaryPriceUpdate { +pub struct BinaryUpdate { pub encoding: EncodingType, pub data: Vec, } @@ -274,15 +274,15 @@ impl From for ParsedPriceUpdate { } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] -pub struct PublisherStakeCapsUpdateResponse { - pub binary: BinaryPriceUpdate, +pub struct GetPublisherStakeCapsUpdateDataResponse { + pub binary: BinaryUpdate, #[serde(skip_serializing_if = "Option::is_none")] pub parsed: Option>, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct PriceUpdate { - pub binary: BinaryPriceUpdate, + pub binary: BinaryUpdate, #[serde(skip_serializing_if = "Option::is_none")] pub parsed: Option>, } diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index 70842c9e60..a2bf2cc60a 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -266,7 +266,7 @@ where price_ids: &[PriceIdentifier], request_time: RequestTime, ) -> Result; - async fn get_publisher_stake_caps_update_data( + async fn get_publisher_stake_caps_with_update_data( &self, ) -> Result; } @@ -430,7 +430,7 @@ where } } - async fn get_publisher_stake_caps_update_data( + async fn get_publisher_stake_caps_with_update_data( &self, ) -> Result { let messages = self From 0a23da585081f929a0a69cd1b427897c16755499 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 22:02:49 +0100 Subject: [PATCH 07/13] cleanup --- .../get_publisher_stake_caps_update_data.rs | 8 +++--- apps/hermes/server/src/api/types.rs | 16 +++++++++-- apps/hermes/server/src/state/aggregate.rs | 27 +++++-------------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs index 34bf67f95e..09cb52cc15 100644 --- a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs +++ b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs @@ -6,13 +6,11 @@ use { BinaryUpdate, EncodingType, GetPublisherStakeCapsUpdateDataResponse, + ParsedPublisherStakeCapsUpdate, }, ApiState, }, - state::{ - aggregate::PublisherStakeCapsUpdate, - Aggregates, - }, + state::Aggregates, }, anyhow::Result, axum::{ @@ -90,7 +88,7 @@ where data: encoded_data, }; - let parsed: Option> = if params.parsed { + let parsed: Option> = if params.parsed { Some(publisher_stake_caps_with_update_data.publisher_stake_caps) } else { None diff --git a/apps/hermes/server/src/api/types.rs b/apps/hermes/server/src/api/types.rs index c04490ebf2..a0cf318428 100644 --- a/apps/hermes/server/src/api/types.rs +++ b/apps/hermes/server/src/api/types.rs @@ -3,7 +3,6 @@ use { crate::state::aggregate::{ PriceFeedUpdate, PriceFeedsWithUpdateData, - PublisherStakeCapsUpdate, Slot, UnixTimestamp, }, @@ -29,6 +28,7 @@ use { Deserialize, Serialize, }, + solana_sdk::pubkey::Pubkey, std::{ collections::BTreeMap, fmt::{ @@ -273,11 +273,23 @@ impl From for ParsedPriceUpdate { } } +#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] +pub struct ParsedPublisherStakeCapsUpdate { + pub publisher_stake_caps: Vec, +} + +#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] +pub struct ParsedPublisherStakeCap { + #[serde(with = "pyth_sdk::utils::as_string")] + pub publisher: Pubkey, + pub cap: u64, +} + #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct GetPublisherStakeCapsUpdateDataResponse { pub binary: BinaryUpdate, #[serde(skip_serializing_if = "Option::is_none")] - pub parsed: Option>, + pub parsed: Option>, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index a2bf2cc60a..e965164d28 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -17,6 +17,10 @@ use { WormholeMerkleState, }, crate::{ + api::types::{ + ParsedPublisherStakeCap, + ParsedPublisherStakeCapsUpdate, + }, network::wormhole::VaaBytes, state::{ benchmarks::Benchmarks, @@ -56,10 +60,6 @@ use { }, }, serde::Serialize, - serde_with::{ - serde_as, - DisplayFromStr, - }, solana_sdk::pubkey::Pubkey, std::{ collections::HashSet, @@ -214,19 +214,6 @@ pub struct PriceFeedUpdate { pub prev_publish_time: Option, } -#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] -pub struct PublisherStakeCapsUpdate { - pub publisher_stake_caps: Vec, -} - -#[serde_as] -#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] -pub struct SerdePublisherStakeCap { - #[serde_as(as = "DisplayFromStr")] - pub publisher: Pubkey, - pub cap: u64, -} - #[derive(Debug, PartialEq)] pub struct PriceFeedsWithUpdateData { pub price_feeds: Vec, @@ -235,7 +222,7 @@ pub struct PriceFeedsWithUpdateData { #[derive(Debug, PartialEq)] pub struct PublisherStakeCapsWithUpdateData { - pub publisher_stake_caps: Vec, + pub publisher_stake_caps: Vec, pub update_data: Vec>, } @@ -444,11 +431,11 @@ where let publisher_stake_caps = messages .iter() .map(|message_state| match message_state.message.clone() { - Message::PublisherStakeCapsMessage(message) => Ok(PublisherStakeCapsUpdate { + Message::PublisherStakeCapsMessage(message) => Ok(ParsedPublisherStakeCapsUpdate { publisher_stake_caps: message .caps .iter() - .map(|cap| SerdePublisherStakeCap { + .map(|cap| ParsedPublisherStakeCap { publisher: Pubkey::from(cap.publisher), cap: cap.cap, }) From d4066bf499233519d4bbb486d30c2fee580c633a Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Tue, 3 Sep 2024 22:03:39 +0100 Subject: [PATCH 08/13] udno dependency update --- apps/hermes/server/Cargo.lock | 51 +++++------------------------------ apps/hermes/server/Cargo.toml | 1 - 2 files changed, 6 insertions(+), 46 deletions(-) diff --git a/apps/hermes/server/Cargo.lock b/apps/hermes/server/Cargo.lock index 147db2f6af..de2e07082d 100644 --- a/apps/hermes/server/Cargo.lock +++ b/apps/hermes/server/Cargo.lock @@ -557,12 +557,6 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "base64ct" version = "1.6.0" @@ -1224,7 +1218,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", - "serde", ] [[package]] @@ -1839,7 +1832,6 @@ dependencies = [ "serde", "serde_json", "serde_qs", - "serde_with 3.9.0", "serde_wormhole", "sha3 0.10.8", "solana-account-decoder", @@ -2105,7 +2097,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -3902,25 +3893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" dependencies = [ "serde", - "serde_with_macros 2.3.3", -] - -[[package]] -name = "serde_with" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.6", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros 3.9.0", - "time", + "serde_with_macros", ] [[package]] @@ -3935,18 +3908,6 @@ dependencies = [ "syn 2.0.55", ] -[[package]] -name = "serde_with_macros" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" -dependencies = [ - "darling", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", -] - [[package]] name = "serde_wormhole" version = "0.1.0" @@ -4647,7 +4608,7 @@ dependencies = [ "serde_bytes", "serde_derive", "serde_json", - "serde_with 2.3.3", + "serde_with", "sha2 0.10.8", "sha3 0.10.8", "solana-frozen-abi", @@ -5282,9 +5243,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", @@ -5303,9 +5264,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ "num-conv", "time-core", diff --git a/apps/hermes/server/Cargo.toml b/apps/hermes/server/Cargo.toml index 6401570791..2f376d1b6e 100644 --- a/apps/hermes/server/Cargo.toml +++ b/apps/hermes/server/Cargo.toml @@ -55,7 +55,6 @@ wormhole-sdk = { git = "https://github.com/wormhole-foundation/wormhol solana-client = { version = "=1.16.19" } solana-sdk = { version = "=1.16.19" } solana-account-decoder = { version = "=1.16.19" } -serde_with = "3.9.0" [build-dependencies] From e6ca3c8818197e34d0f3359056e22e8a3935ef6c Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 4 Sep 2024 17:17:11 +0100 Subject: [PATCH 09/13] fix: use v2 routes --- apps/hermes/server/src/api.rs | 9 +- apps/hermes/server/src/api/rest.rs | 3 +- .../get_publisher_stake_caps_update_data.rs | 101 ------------------ apps/hermes/server/src/api/rest/v2/mod.rs | 1 + 4 files changed, 7 insertions(+), 107 deletions(-) delete mode 100644 apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs diff --git a/apps/hermes/server/src/api.rs b/apps/hermes/server/src/api.rs index b71bd27540..9b63a20186 100644 --- a/apps/hermes/server/src/api.rs +++ b/apps/hermes/server/src/api.rs @@ -111,6 +111,7 @@ where rest::latest_vaas, rest::price_feed_ids, rest::latest_price_updates, + rest::latest_publisher_stake_caps, rest::timestamp_price_updates, rest::price_feeds_metadata, rest::price_stream_sse_handler, @@ -150,10 +151,6 @@ where .route("/api/get_price_feed", get(rest::get_price_feed)) .route("/api/get_vaa", get(rest::get_vaa)) .route("/api/get_vaa_ccip", get(rest::get_vaa_ccip)) - .route( - "/api/get_publisher_stake_caps_update_data", - get(rest::get_publisher_stake_caps_update_data), - ) .route("/api/latest_price_feeds", get(rest::latest_price_feeds)) .route("/api/latest_vaas", get(rest::latest_vaas)) .route("/api/price_feed_ids", get(rest::price_feed_ids)) @@ -162,6 +159,10 @@ where get(rest::price_stream_sse_handler), ) .route("/v2/updates/price/latest", get(rest::latest_price_updates)) + .route( + "/v2/updates/publisher_stake_caps/latest", + get(rest::latest_publisher_stake_caps), + ) .route( "/v2/updates/price/:publish_time", get(rest::timestamp_price_updates), diff --git a/apps/hermes/server/src/api/rest.rs b/apps/hermes/server/src/api/rest.rs index a40e5608c3..51288825f2 100644 --- a/apps/hermes/server/src/api/rest.rs +++ b/apps/hermes/server/src/api/rest.rs @@ -12,7 +12,6 @@ use { }; mod get_price_feed; -mod get_publisher_stake_caps_update_data; mod get_vaa; mod get_vaa_ccip; mod index; @@ -26,7 +25,6 @@ mod v2; pub use { get_price_feed::*, - get_publisher_stake_caps_update_data::*, get_vaa::*, get_vaa_ccip::*, index::*, @@ -37,6 +35,7 @@ pub use { ready::*, v2::{ latest_price_updates::*, + latest_publisher_stake_caps::*, price_feeds_metadata::*, sse::*, timestamp_price_updates::*, diff --git a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs b/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs deleted file mode 100644 index 09cb52cc15..0000000000 --- a/apps/hermes/server/src/api/rest/get_publisher_stake_caps_update_data.rs +++ /dev/null @@ -1,101 +0,0 @@ -use { - crate::{ - api::{ - rest::RestError, - types::{ - BinaryUpdate, - EncodingType, - GetPublisherStakeCapsUpdateDataResponse, - ParsedPublisherStakeCapsUpdate, - }, - ApiState, - }, - state::Aggregates, - }, - anyhow::Result, - axum::{ - extract::State, - Json, - }, - base64::{ - engine::general_purpose::STANDARD as base64_standard_engine, - Engine as _, - }, - serde::Deserialize, - serde_qs::axum::QsQuery, - utoipa::IntoParams, -}; - - -#[derive(Debug, Deserialize, IntoParams)] -#[into_params(parameter_in=Query)] -pub struct GetPublisherStakeCapsUpdateData { - /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. - #[serde(default)] - encoding: EncodingType, - - /// If true, include the parsed update in the `parsed` field of each returned feed. Default is `true`. - #[serde(default = "default_true")] - parsed: bool, -} - -fn default_true() -> bool { - true -} - - -/// Get the publisher stake caps update data -#[utoipa::path( - get, - path = "/api/get_publisher_stake_caps_update_data", - responses( - (status = 200, description = "Publisher stake caps update data retrieved succesfully", body = Vec) - ), - params( - GetPublisherStakeCapsUpdateData - ) -)] -pub async fn get_publisher_stake_caps_update_data( - State(state): State>, - QsQuery(params): QsQuery, -) -> Result, RestError> -where - S: Aggregates, -{ - let state = &*state.state; - let publisher_stake_caps_with_update_data = - Aggregates::get_publisher_stake_caps_with_update_data(state) - .await - .map_err(|e| { - tracing::warn!( - "Error getting publisher stake caps with update data: {:?}", - e - ); - RestError::UpdateDataNotFound - })?; - - let encoded_data: Vec = publisher_stake_caps_with_update_data - .update_data - .into_iter() - .map(|data| match params.encoding { - EncodingType::Base64 => base64_standard_engine.encode(data), - EncodingType::Hex => hex::encode(data), - }) - .collect(); - - let binary = BinaryUpdate { - encoding: params.encoding, - data: encoded_data, - }; - - let parsed: Option> = if params.parsed { - Some(publisher_stake_caps_with_update_data.publisher_stake_caps) - } else { - None - }; - - Ok(Json(GetPublisherStakeCapsUpdateDataResponse { - binary, - parsed, - })) -} diff --git a/apps/hermes/server/src/api/rest/v2/mod.rs b/apps/hermes/server/src/api/rest/v2/mod.rs index a02ddbc482..4777e0ebbc 100644 --- a/apps/hermes/server/src/api/rest/v2/mod.rs +++ b/apps/hermes/server/src/api/rest/v2/mod.rs @@ -1,4 +1,5 @@ pub mod latest_price_updates; +pub mod latest_publisher_stake_caps; pub mod price_feeds_metadata; pub mod sse; pub mod timestamp_price_updates; From 37c33d3102e52c6e537c7b6da9d2c6b54cc9fcaf Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 4 Sep 2024 17:27:12 +0100 Subject: [PATCH 10/13] fix: move response struct --- apps/hermes/server/src/api/types.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/hermes/server/src/api/types.rs b/apps/hermes/server/src/api/types.rs index a0cf318428..ab72bbb273 100644 --- a/apps/hermes/server/src/api/types.rs +++ b/apps/hermes/server/src/api/types.rs @@ -285,13 +285,6 @@ pub struct ParsedPublisherStakeCap { pub cap: u64, } -#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] -pub struct GetPublisherStakeCapsUpdateDataResponse { - pub binary: BinaryUpdate, - #[serde(skip_serializing_if = "Option::is_none")] - pub parsed: Option>, -} - #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct PriceUpdate { pub binary: BinaryUpdate, From 863c5e8d1bae5e36208e899153828d83ef7f6d42 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 4 Sep 2024 17:33:46 +0100 Subject: [PATCH 11/13] fix: some renames --- .../rest/v2/latest_publisher_stake_caps.rs | 114 ++++++++++++++++++ apps/hermes/server/src/state/aggregate.rs | 4 +- 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 apps/hermes/server/src/api/rest/v2/latest_publisher_stake_caps.rs diff --git a/apps/hermes/server/src/api/rest/v2/latest_publisher_stake_caps.rs b/apps/hermes/server/src/api/rest/v2/latest_publisher_stake_caps.rs new file mode 100644 index 0000000000..480caf4e76 --- /dev/null +++ b/apps/hermes/server/src/api/rest/v2/latest_publisher_stake_caps.rs @@ -0,0 +1,114 @@ +use { + crate::{ + api::{ + rest::RestError, + types::{ + BinaryUpdate, + EncodingType, + ParsedPublisherStakeCapsUpdate, + }, + ApiState, + }, + state::Aggregates, + }, + anyhow::Result, + axum::{ + extract::State, + Json, + }, + base64::{ + engine::general_purpose::STANDARD as base64_standard_engine, + Engine as _, + }, + serde::{ + Deserialize, + Serialize, + }, + serde_qs::axum::QsQuery, + utoipa::{ + IntoParams, + ToSchema, + }, +}; + + +#[derive(Debug, Deserialize, IntoParams)] +#[into_params(parameter_in=Query)] +pub struct LatestPublisherStakeCapsUpdateData { + /// Get the most recent publisher stake caps update data. + + /// Optional encoding type. If true, return the message in the encoding specified by the encoding parameter. Default is `hex`. + #[serde(default)] + encoding: EncodingType, + + /// If true, include the parsed update in the `parsed` field of each returned feed. Default is `true`. + #[serde(default = "default_true")] + parsed: bool, +} + +fn default_true() -> bool { + true +} + +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct LatestPublisherStakeCapsUpdateDataResponse { + pub binary: BinaryUpdate, + #[serde(skip_serializing_if = "Option::is_none")] + pub parsed: Option>, +} + +/// Get the most recent publisher stake caps update data. +#[utoipa::path( + get, + path = "/v2/updates/publisher_stake_caps/latest", + responses( + (status = 200, description = "Publisher stake caps update data retrieved succesfully", body = Vec) + ), + params( + LatestPublisherStakeCapsUpdateData + ) +)] +pub async fn latest_publisher_stake_caps( + State(state): State>, + QsQuery(params): QsQuery, +) -> Result, RestError> +where + S: Aggregates, +{ + let state = &*state.state; + let publisher_stake_caps_with_update_data = + Aggregates::get_latest_publisher_stake_caps_with_update_data(state) + .await + .map_err(|e| { + tracing::warn!( + "Error getting publisher stake caps with update data: {:?}", + e + ); + RestError::UpdateDataNotFound + })?; + + let encoded_data: Vec = publisher_stake_caps_with_update_data + .update_data + .into_iter() + .map(|data| match params.encoding { + EncodingType::Base64 => base64_standard_engine.encode(data), + EncodingType::Hex => hex::encode(data), + }) + .collect(); + + let binary = BinaryUpdate { + encoding: params.encoding, + data: encoded_data, + }; + + let parsed: Option> = if params.parsed { + Some(publisher_stake_caps_with_update_data.publisher_stake_caps) + } else { + None + }; + + Ok(Json(LatestPublisherStakeCapsUpdateDataResponse { + binary, + parsed, + })) +} diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index e965164d28..e227fa4522 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -253,7 +253,7 @@ where price_ids: &[PriceIdentifier], request_time: RequestTime, ) -> Result; - async fn get_publisher_stake_caps_with_update_data( + async fn get_latest_publisher_stake_caps_with_update_data( &self, ) -> Result; } @@ -417,7 +417,7 @@ where } } - async fn get_publisher_stake_caps_with_update_data( + async fn get_latest_publisher_stake_caps_with_update_data( &self, ) -> Result { let messages = self From c4dbd1a436b93280519018b1f5d701bcd1407fd8 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 4 Sep 2024 17:45:19 +0100 Subject: [PATCH 12/13] fix: get_price_feed_ids --- apps/hermes/server/src/state/aggregate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/hermes/server/src/state/aggregate.rs b/apps/hermes/server/src/state/aggregate.rs index e227fa4522..84fd74ce89 100644 --- a/apps/hermes/server/src/state/aggregate.rs +++ b/apps/hermes/server/src/state/aggregate.rs @@ -456,6 +456,7 @@ where Cache::message_state_keys(self) .await .iter() + .filter(|key| key.feed_id != PUBLISHER_STAKE_CAPS_MESSAGE_FEED_ID) .map(|key| PriceIdentifier::new(key.feed_id)) .collect() } From 86197508ea9391c16297574ad4feb8ffd1b643e6 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 4 Sep 2024 17:48:17 +0100 Subject: [PATCH 13/13] bump: hermes --- apps/hermes/server/Cargo.lock | 2 +- apps/hermes/server/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/hermes/server/Cargo.lock b/apps/hermes/server/Cargo.lock index de2e07082d..aca82cb4ce 100644 --- a/apps/hermes/server/Cargo.lock +++ b/apps/hermes/server/Cargo.lock @@ -1796,7 +1796,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermes" -version = "0.5.17" +version = "0.6.0" dependencies = [ "anyhow", "async-trait", diff --git a/apps/hermes/server/Cargo.toml b/apps/hermes/server/Cargo.toml index 2f376d1b6e..0324e57ddb 100644 --- a/apps/hermes/server/Cargo.toml +++ b/apps/hermes/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hermes" -version = "0.5.17" +version = "0.6.0" description = "Hermes is an agent that provides Verified Prices from the Pythnet Pyth Oracle." edition = "2021"