Skip to content

Commit d70119c

Browse files
ali-behjatiReisen
authored andcommitted
Use pyth-oracle types
1 parent 15e35aa commit d70119c

File tree

10 files changed

+433
-852
lines changed

10 files changed

+433
-852
lines changed

hermes/Cargo.lock

Lines changed: 330 additions & 635 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hermes/Cargo.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,22 @@ libp2p = { version = "0.42.2", features = [
5252
]}
5353

5454
async-trait = "0.1.68"
55-
solana-client = "=1.15.2"
56-
solana-sdk = "=1.15.2"
57-
solana-account-decoder = "=1.15.2"
55+
56+
# We around bound to this version because of pyth-oracle
57+
solana-client = "=1.13.3"
58+
solana-sdk = "=1.13.3"
59+
solana-account-decoder = "=1.13.3"
60+
5861
moka = { version = "0.11.0", features = ["future"] }
5962
derive_builder = "0.12.0"
6063
byteorder = "1.4.3"
6164
serde_qs = { version = "0.12.0", features = ["axum"] }
6265

6366
serde_wormhole = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1"}
6467
wormhole-sdk = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1" }
68+
pyth-oracle = { git = "https://github.com/pyth-network/pyth-client", rev = "7d593d87e07a1e2486e7ca21597d664ee72be1ec", features = ["library"] }
69+
70+
strum = { version = "0.24", features = ["derive"] }
6571

6672
[patch.crates-io]
6773
serde_wormhole = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1" }

hermes/src/api.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ pub async fn spawn(rpc_addr: String, store: Store) -> Result<()> {
6464
// FIXME use a channel to get updates from the store
6565
tokio::spawn(async move {
6666
loop {
67-
dispatch_updates(state.store.get_price_feed_ids(), state.clone()).await;
67+
dispatch_updates(
68+
state.store.get_price_feed_ids().into_iter().collect(),
69+
state.clone(),
70+
)
71+
.await;
6872
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
6973
}
7074
});

hermes/src/api/rest.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use {
3030
},
3131
pyth_sdk::PriceIdentifier,
3232
serde_qs::axum::QsQuery,
33+
std::collections::HashSet,
3334
};
3435

3536
pub enum RestError {
@@ -59,7 +60,7 @@ impl IntoResponse for RestError {
5960

6061
pub async fn price_feed_ids(
6162
State(state): State<super::State>,
62-
) -> Result<Json<Vec<PriceIdentifier>>, RestError> {
63+
) -> Result<Json<HashSet<PriceIdentifier>>, RestError> {
6364
let price_feeds = state.store.get_price_feed_ids();
6465
Ok(Json(price_feeds))
6566
}

hermes/src/api/types.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
use {
22
crate::{
33
impl_deserialize_for_hex_string_wrapper,
4-
store::types::{
5-
PriceFeedMessage,
6-
UnixTimestamp,
7-
},
4+
store::types::UnixTimestamp,
85
},
96
derive_more::{
107
Deref,
118
DerefMut,
129
},
10+
pyth_oracle::PriceFeedMessage,
1311
pyth_sdk::{
1412
Price,
1513
PriceIdentifier,

hermes/src/network/pythnet.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use {
2222
},
2323
rpc_filter::{
2424
Memcmp,
25+
MemcmpEncodedBytes,
2526
RpcFilterType,
2627
},
2728
},
@@ -42,10 +43,11 @@ pub async fn spawn(pythnet_ws_endpoint: String, store: Store) -> Result<()> {
4243
encoding: Some(UiAccountEncoding::Base64Zstd),
4344
..Default::default()
4445
},
45-
filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new_raw_bytes(
46-
0,
47-
b"PAS1".to_vec(),
48-
))]),
46+
filters: Some(vec![RpcFilterType::Memcmp(Memcmp {
47+
offset: 0,
48+
bytes: MemcmpEncodedBytes::Bytes(b"PAS1".to_vec()),
49+
encoding: None,
50+
})]),
4951
with_context: Some(true),
5052
..Default::default()
5153
};

hermes/src/store.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use {
2020
store_wormhole_merkle_verified_message,
2121
},
2222
types::{
23-
Message,
2423
MessageState,
2524
ProofSet,
2625
WormholePayload,
@@ -32,8 +31,12 @@ use {
3231
},
3332
derive_builder::Builder,
3433
moka::future::Cache,
34+
pyth_oracle::Message,
3535
pyth_sdk::PriceIdentifier,
36-
std::time::Duration,
36+
std::{
37+
collections::HashSet,
38+
time::Duration,
39+
},
3740
wormhole_sdk::Vaa,
3841
};
3942

@@ -137,7 +140,7 @@ impl Store {
137140
.iter()
138141
.enumerate()
139142
.map(|(idx, raw_message)| {
140-
let message = Message::from_bytes(raw_message)?;
143+
let message = Message::try_from_bytes(raw_message)?;
141144

142145
Ok(MessageState::new(
143146
message,
@@ -168,18 +171,15 @@ impl Store {
168171
request_time: RequestTime,
169172
) -> Result<PriceFeedsWithUpdateData> {
170173
let messages = self.storage.retrieve_message_states(
171-
price_ids
172-
.iter()
173-
.map(|price_id| price_id.to_bytes())
174-
.collect(),
175-
types::RequestType::Some(vec![MessageType::PriceFeed]),
174+
price_ids,
176175
request_time,
176+
Some(&|message_type| *message_type == MessageType::PriceFeedMessage),
177177
)?;
178178

179179
let price_feeds = messages
180180
.iter()
181181
.map(|message_state| match message_state.message {
182-
Message::PriceFeed(price_feed) => Ok(price_feed),
182+
Message::PriceFeedMessage(price_feed) => Ok(price_feed),
183183
_ => Err(anyhow!("Invalid message state type")),
184184
})
185185
.collect::<Result<Vec<_>>>()?;
@@ -191,11 +191,7 @@ impl Store {
191191
})
192192
}
193193

194-
pub fn get_price_feed_ids(&self) -> Vec<PriceIdentifier> {
195-
self.storage
196-
.keys()
197-
.iter()
198-
.map(|key| PriceIdentifier::new(key.id))
199-
.collect()
194+
pub fn get_price_feed_ids(&self) -> HashSet<PriceIdentifier> {
195+
self.storage.keys().iter().map(|key| key.price_id).collect()
200196
}
201197
}

hermes/src/store/storage.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use {
22
super::types::{
33
MessageIdentifier,
4-
MessageKey,
54
MessageState,
5+
MessageType,
66
RequestTime,
7-
RequestType,
87
},
98
anyhow::Result,
9+
pyth_sdk::PriceIdentifier,
1010
std::sync::Arc,
1111
};
1212

@@ -23,11 +23,11 @@ pub trait Storage: Send + Sync {
2323
fn store_message_states(&self, message_states: Vec<MessageState>) -> Result<()>;
2424
fn retrieve_message_states(
2525
&self,
26-
ids: Vec<MessageIdentifier>,
27-
request_type: RequestType,
26+
ids: Vec<PriceIdentifier>,
2827
request_time: RequestTime,
28+
filter: Option<&dyn Fn(&MessageType) -> bool>,
2929
) -> Result<Vec<MessageState>>;
30-
fn keys(&self) -> Vec<MessageKey>;
30+
fn keys(&self) -> Vec<MessageIdentifier>;
3131
}
3232

3333
pub type StorageInstance = Arc<Box<dyn Storage>>;

hermes/src/store/storage/local_storage.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use {
22
super::{
33
MessageIdentifier,
4-
MessageKey,
54
MessageState,
65
RequestTime,
7-
RequestType,
86
Storage,
97
StorageInstance,
108
},
@@ -14,15 +12,17 @@ use {
1412
Result,
1513
},
1614
dashmap::DashMap,
15+
pyth_sdk::PriceIdentifier,
1716
std::{
1817
collections::VecDeque,
1918
sync::Arc,
2019
},
20+
strum::IntoEnumIterator,
2121
};
2222

2323
#[derive(Clone)]
2424
pub struct LocalStorage {
25-
cache: Arc<DashMap<MessageKey, VecDeque<MessageState>>>,
25+
cache: Arc<DashMap<MessageIdentifier, VecDeque<MessageState>>>,
2626
max_size_per_key: usize,
2727
}
2828

@@ -36,7 +36,7 @@ impl LocalStorage {
3636

3737
fn retrieve_message_state(
3838
&self,
39-
key: MessageKey,
39+
key: MessageIdentifier,
4040
request_time: RequestTime,
4141
) -> Option<MessageState> {
4242
match self.cache.get(&key) {
@@ -109,19 +109,22 @@ impl Storage for LocalStorage {
109109

110110
fn retrieve_message_states(
111111
&self,
112-
ids: Vec<MessageIdentifier>,
113-
request_type: RequestType,
112+
ids: Vec<PriceIdentifier>,
114113
request_time: RequestTime,
114+
filter: Option<&dyn Fn(&MessageType) -> bool>,
115115
) -> Result<Vec<MessageState>> {
116116
// TODO: Should we return an error if any of the ids are not found?
117-
let types: Vec<MessageType> = request_type.into();
118117
ids.into_iter()
119118
.flat_map(|id| {
120119
let request_time = request_time.clone();
121-
types.iter().map(move |message_type| {
122-
let key = MessageKey {
123-
id,
124-
type_: message_type.clone(),
120+
let message_types: Vec<MessageType> = match filter {
121+
Some(filter) => MessageType::iter().filter(filter).collect(),
122+
None => MessageType::iter().collect(),
123+
};
124+
message_types.into_iter().map(move |message_type| {
125+
let key = MessageIdentifier {
126+
price_id: id,
127+
type_: message_type,
125128
};
126129
self.retrieve_message_state(key, request_time.clone())
127130
.ok_or(anyhow!("Message not found"))
@@ -130,7 +133,7 @@ impl Storage for LocalStorage {
130133
.collect()
131134
}
132135

133-
fn keys(&self) -> Vec<MessageKey> {
136+
fn keys(&self) -> Vec<MessageIdentifier> {
134137
self.cache.iter().map(|entry| entry.key().clone()).collect()
135138
}
136139
}

0 commit comments

Comments
 (0)