Skip to content

Commit 7f154ba

Browse files
feat: modify PriceFeedReturn to use byte arrays and simplify parsing logic
- Change PriceFeedReturn from hex string to byte array ([u8; 32], U64, I32, I64, U64, I64, U64) - Update parse_price_feed_updates_internal to return Vec<PriceFeedReturn> instead of Vec<([u8; 32], PriceFeedReturn)> - Simplify parse_price_feed_updates_with_config by removing price_map and using direct indexing with find() - Simplify update_price_feeds_internal to avoid dual variable iteration and directly index structs - Update test data functions to use byte arrays from helper functions instead of hex strings - Add helper functions for different feed IDs used in multiple updates tests All tests pass successfully with these changes. Co-Authored-By: [email protected] <[email protected]>
1 parent 9f3d809 commit 7f154ba

File tree

3 files changed

+63
-34
lines changed

3 files changed

+63
-34
lines changed

target_chains/stylus/contracts/pyth-receiver/src/lib.rs

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ impl PythReceiver {
121121
}
122122

123123
Ok((
124+
id,
124125
price_info.publish_time.get(),
125126
price_info.expo.get(),
126127
price_info.price.get(),
@@ -136,7 +137,7 @@ impl PythReceiver {
136137
age: u64,
137138
) -> Result<PriceFeedReturn, PythReceiverError> {
138139
let price_info = self.get_price_unsafe(id)?;
139-
if !self.is_no_older_than(price_info.0, age) {
140+
if !self.is_no_older_than(price_info.1, age) {
140141
return Err(PythReceiverError::NewPriceUnavailable);
141142
}
142143
Ok(price_info)
@@ -151,6 +152,7 @@ impl PythReceiver {
151152
}
152153

153154
Ok((
155+
id,
154156
price_info.publish_time.get(),
155157
price_info.expo.get(),
156158
price_info.ema_price.get(),
@@ -166,7 +168,7 @@ impl PythReceiver {
166168
age: u64,
167169
) -> Result<PriceFeedReturn, PythReceiverError> {
168170
let price_info = self.get_ema_price_unsafe(id)?;
169-
if !self.is_no_older_than(price_info.0, age) {
171+
if !self.is_no_older_than(price_info.1, age) {
170172
return Err(PythReceiverError::NewPriceUnavailable);
171173
}
172174
Ok(price_info)
@@ -226,31 +228,31 @@ impl PythReceiver {
226228
min_publish_time: u64,
227229
max_publish_time: u64,
228230
_unique: bool,
229-
) -> Result<Vec<([u8; 32], PriceFeedReturn)>, PythReceiverError> {
230-
let price_pairs = self.parse_price_feed_updates_internal(
231+
) -> Result<Vec<PriceFeedReturn>, PythReceiverError> {
232+
let price_feeds = self.parse_price_feed_updates_internal(
231233
update_data,
232234
min_publish_time,
233235
max_publish_time,
234236
false, // check_uniqueness
235237
)?;
236238

237-
for (price_id, price_return) in price_pairs.clone() {
238-
let price_id_fb: FixedBytes<32> = FixedBytes::from(price_id);
239+
for price_return in &price_feeds {
240+
let price_id_fb: FixedBytes<32> = FixedBytes::from(price_return.0);
239241
let mut recent_price_info = self.latest_price_info.setter(price_id_fb);
240242

241-
if recent_price_info.publish_time.get() < price_return.0
243+
if recent_price_info.publish_time.get() < price_return.1
242244
|| recent_price_info.price.get() == I64::ZERO
243245
{
244-
recent_price_info.publish_time.set(price_return.0);
245-
recent_price_info.expo.set(price_return.1);
246-
recent_price_info.price.set(price_return.2);
247-
recent_price_info.conf.set(price_return.3);
248-
recent_price_info.ema_price.set(price_return.4);
249-
recent_price_info.ema_conf.set(price_return.5);
246+
recent_price_info.publish_time.set(price_return.1);
247+
recent_price_info.expo.set(price_return.2);
248+
recent_price_info.price.set(price_return.3);
249+
recent_price_info.conf.set(price_return.4);
250+
recent_price_info.ema_price.set(price_return.5);
251+
recent_price_info.ema_conf.set(price_return.6);
250252
}
251253
}
252254

253-
Ok(price_pairs)
255+
Ok(price_feeds)
254256
}
255257

256258
fn get_update_fee(&self, update_data: Vec<Vec<u8>>) -> Result<U256, PythReceiverError> {
@@ -308,18 +310,18 @@ impl PythReceiver {
308310
check_update_data_is_minimal: bool,
309311
store_updates_if_fresh: bool,
310312
) -> Result<Vec<PriceFeedReturn>, PythReceiverError> {
311-
let mut all_parsed_price_pairs = Vec::new();
313+
let mut all_parsed_price_feeds = Vec::new();
312314
for data in &update_data {
313315
if store_updates_if_fresh {
314-
all_parsed_price_pairs.extend(self.update_price_feeds_internal(
316+
all_parsed_price_feeds.extend(self.update_price_feeds_internal(
315317
data.clone(),
316318
price_ids.clone(),
317319
min_allowed_publish_time,
318320
max_allowed_publish_time,
319321
check_uniqueness,
320322
)?);
321323
} else {
322-
all_parsed_price_pairs.extend(self.parse_price_feed_updates_internal(
324+
all_parsed_price_feeds.extend(self.parse_price_feed_updates_internal(
323325
data.clone(),
324326
min_allowed_publish_time,
325327
max_allowed_publish_time,
@@ -328,22 +330,15 @@ impl PythReceiver {
328330
}
329331
}
330332

331-
if check_update_data_is_minimal && all_parsed_price_pairs.len() != price_ids.len() {
333+
if check_update_data_is_minimal && all_parsed_price_feeds.len() != price_ids.len() {
332334
return Err(PythReceiverError::InvalidUpdateData);
333335
}
334336

335337
let mut result: Vec<PriceFeedReturn> = Vec::with_capacity(price_ids.len());
336-
let mut price_map: BTreeMap<[u8; 32], PriceFeedReturn> = BTreeMap::new();
337-
338-
for (price_id, price_info) in all_parsed_price_pairs {
339-
if !price_map.contains_key(&price_id) {
340-
price_map.insert(price_id, price_info);
341-
}
342-
}
343338

344339
for price_id in price_ids {
345-
if let Some(price_info) = price_map.get(&price_id) {
346-
result.push(*price_info);
340+
if let Some(price_info) = all_parsed_price_feeds.iter().find(|feed| feed.0 == price_id) {
341+
result.push(price_info.clone());
347342
} else {
348343
return Err(PythReceiverError::PriceFeedNotFoundWithinRange);
349344
}
@@ -358,7 +353,7 @@ impl PythReceiver {
358353
min_allowed_publish_time: u64,
359354
max_allowed_publish_time: u64,
360355
check_uniqueness: bool,
361-
) -> Result<Vec<([u8; 32], PriceFeedReturn)>, PythReceiverError> {
356+
) -> Result<Vec<PriceFeedReturn>, PythReceiverError> {
362357
let update_data_array: &[u8] = &update_data;
363358
// Check the first 4 bytes of the update_data_array for the magic header
364359
if update_data_array.len() < 4 {
@@ -444,6 +439,7 @@ impl PythReceiver {
444439
}
445440

446441
let price_info_return = (
442+
price_feed_message.feed_id,
447443
U64::from(publish_time),
448444
I32::from_be_bytes(price_feed_message.exponent.to_be_bytes()),
449445
I64::from_be_bytes(price_feed_message.price.to_be_bytes()),
@@ -462,7 +458,7 @@ impl PythReceiver {
462458
}
463459
};
464460

465-
Ok(price_feeds.into_iter().collect())
461+
Ok(price_feeds.into_iter().map(|(_, price_info)| price_info).collect())
466462
}
467463

468464
pub fn parse_twap_price_feed_updates(

target_chains/stylus/contracts/pyth-receiver/src/structs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub struct PriceInfoStorage {
5757
// pub ema_conf: U64,
5858
// }
5959

60-
pub type PriceFeedReturn = (U64, I32, I64, U64, I64, U64);
60+
pub type PriceFeedReturn = ([u8; 32], U64, I32, I64, U64, I64, U64);
6161

6262
pub type PriceReturn = ([u8; 32], U64, I32, I64, U64, I64, U64);
6363

target_chains/stylus/contracts/pyth-receiver/src/test_data.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,33 @@ pub fn good_update1_feed_id() -> [u8; 32] {
2929
byte_array
3030
}
3131

32+
#[cfg(test)]
33+
pub fn multiple_updates_first_feed_id() -> [u8; 32] {
34+
[
35+
0xe6, 0x2d, 0xf6, 0xc8, 0xb4, 0xa8, 0x5f, 0xe1, 0xa6, 0x7d, 0xb4, 0x4d, 0xc1, 0x2d, 0xe5,
36+
0xdb, 0x33, 0x0f, 0x7a, 0xc6, 0x6b, 0x72, 0xdc, 0x65, 0x8a, 0xfe, 0xdf, 0x0f, 0x4a, 0x41,
37+
0x5b, 0x43,
38+
]
39+
}
40+
41+
#[cfg(test)]
42+
pub fn multiple_updates_second_feed_id() -> [u8; 32] {
43+
[
44+
0xff, 0x61, 0x49, 0x1a, 0x93, 0x11, 0x12, 0xdd, 0xf1, 0xbd, 0x81, 0x47, 0xcd, 0x1b,
45+
0x64, 0x13, 0x75, 0xf7, 0x9f, 0x58, 0x25, 0x12, 0x6d, 0x66, 0x54, 0x80, 0x87, 0x46,
46+
0x34, 0xfd, 0x0a, 0xce,
47+
]
48+
}
49+
50+
#[cfg(test)]
51+
pub fn multiple_updates_diff_first_feed_id() -> [u8; 32] {
52+
[
53+
0x3f, 0xa4, 0x25, 0x28, 0x48, 0xf9, 0xf0, 0xa1, 0x48, 0x0b, 0xe6, 0x27, 0x45, 0xa4,
54+
0x62, 0x9d, 0x9e, 0xb1, 0x32, 0x2a, 0xeb, 0xab, 0x8a, 0x79, 0x1e, 0x34, 0x4b, 0x3b,
55+
0x9c, 0x1a, 0xdc, 0xf5,
56+
]
57+
}
58+
3259
#[cfg(test)]
3360
pub fn multiple_updates_same_vaa() -> Vec<Vec<u8>> {
3461
let hex_str = "504e41550100000003b801000000040d02e57b0f291daa4d2f02f5c4a18793b278b238338f472d17897f8f0866549f77571cfe71fa55bae7f340b9124511559b73a0cf01c72adc8a8d9963cebecc5a503801039507a96b155046ab039f7c9cad17a4927e2ff34763bca9b65d572ddc7a5f019832ffbeeb5295447bfdb989efa0314865bb4571770ad8e75ae7a083288d6de232010412e7333ab5cf0f20274b0907da43b52016d5a095bb846962d13a222e4af1e7e63f7a8db49de04feb70f07a0e274dc58acc7a4c386a099369412c6813ba39916100063da672f75cf1d397829a39461e311ca366366828be8d12b19a00c552e7c8c5e7746b36d97dccc54e5b3aeae188b372ec885dc1fbd9c2285ce458764c86f0c1bb0008863aa237e9fe339683992121249a2e520b6483a3b3b60c703a1eb09ef33266312e729ff6d398e1a60be8474a95803cd1641ef6c1de2c74f3cd7e1f2510c919f9000a3bd5ec58424b21c48552c3be0f9cccd6e6c641eee2b4e550fb88cc93cfdf10c7409344ec3e81df711a293baba565a85e620d20028d9738e53939fa52f19ce622010b000f803511f89f02610fbece34fe327afb55196cc3e522bb28d71d6e4d5523ac77ca1afbbd8a28b4fe05c7f2aa1c3f428c89fe21096ba67bc505cbfa6ead9808010c315b34c9cac03647df4e12a050f8b739763498aa23999244036e09010e2a79a46d0cbabc22c535542896bc22df05dc5480db06a370dffeb0814424870fd50c21000d4a562686000b65df4e0ca00d2e00d10db9e913b481337ee1c80bb47b25553afb693d7be0c17f6fb106909a1eed52a6c27739471b719d4c450b99b066a02bd2c9010e309508bc7128030ca4b19fc34c0ee0e62eebb549c759c2e8ccfdf062793e41e935754ae1d5356ba98446fa2eaa837ae4b413d1ccdf1af6d9060a2885f18c19e1010f3e2ff50704a6ad1b491cb93a1e4678c0f58b91540ba3ce3b4424c96abbe922562c924debb3336ab2fe835237f16912d768e6e5b739f2ab44b57a1e2607c9bb89001070d0dfac758a38342b107870b4d5761df9e785c6be589317c4b1dad3c08998f11214c29201d172b278aa6f4d57171f0f05fb7a2718e6da6df4449e8897c0c2ac0011d9e885989fa2363ec311bf4e9ebd8738d4b3ecaf9a31c09ce06f9876c3ab772034c1df9ca09c847ee81de80a1f0f8592019fa60e55b02b657b8a7c99bee04701016866e28300000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa710000000008812f80014155575600000000000d8ebd6500002710f015dfd43b23aad91dcd4a7a8a113ed2d39233f202005500e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43000009fee44efa2300000000e7f6ffe3fffffff8000000006866e283000000006866e283000009fb4f364d0000000000e98d2f400c2704dab60f1b310d567acb60d77a3ce8003a6f564e8e1f567f00f004381d755e160a07372977a99288dcc9c9477cf9c1bb095403b514082aa774f7b243003e30548cbd97e8191d5ef2732796e06f84f05543a171f1e66052aa515c41a2d994a0d13e2e4016e6a28823201a52d408a5024797ec4b7629406062dd9ccc30a5d1eb4ac8b4a28a3d464bf4335ceda7646e03c29cc24b6c7c5e5924e6e69400a2c90561c9a2e4555084af13fbc7eaa0a884b75d4d1197933ac174b62c4b9b1cde3dd496f5e54cd2e01cdca0ba5c5a80a2bbd0d9d5dfb7aab5b638ef883e4e55f78a1536fe79c5c3e16cda9b53e364e3bbe95f005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000003c480c0e980000000009727f59fffffff8000000006866e283000000006866e2830000003c3597da300000000007d3439a0ccf5f10d7559e184107e994663aa0fc8f81718c0b281162b77eb09c774da30e2db5674df62494b3da820f6c986a0f32d1a195b6bc4676891d4e28cdb4e2f09dd47db3243547b37bdbb9799c82a42d6f1f18f8e17d7bed68408ef26e184f21e9b640e2c9f0416d91987acbe6fa8e72c2c99fa548f83c0eb5dd3c269ef52101521ef0b3d26f50b07dae68311bd138338881b20b78f8d21d2bfc27e9ac849b4c659d61c9a2e4555084af13fbc7eaa0a884b75d4d1197933ac174b62c4b9b1cde3dd496f5e54cd2e01cdca0ba5c5a80a2bbd0d9d5dfb7aab5b638ef883e4e55f78a1536fe79c5c3e16cda9b53e364e3bbe95f";
@@ -47,9 +74,10 @@ pub fn multiple_updates_diff_vaa() -> Vec<Vec<u8>> {
4774
}
4875

4976
#[cfg(test)]
50-
pub fn multiple_updates_diff_vaa_results() -> [(U64, I32, I64, U64, I64, U64); 2] {
77+
pub fn multiple_updates_diff_vaa_results() -> [([u8; 32], U64, I32, I64, U64, I64, U64); 2] {
5178
[
5279
(
80+
multiple_updates_diff_first_feed_id(),
5381
U64::from(1752094858u64),
5482
I32::from_le_bytes((-8i32).to_le_bytes()),
5583
I64::from_le_bytes(35134945i64.to_le_bytes()),
@@ -58,6 +86,7 @@ pub fn multiple_updates_diff_vaa_results() -> [(U64, I32, I64, U64, I64, U64); 2
5886
U64::from(35632u64),
5987
),
6088
(
89+
multiple_updates_first_feed_id(),
6190
U64::from(1751573860u64),
6291
I32::from_le_bytes((-8i32).to_le_bytes()),
6392
I64::from_le_bytes(10985663592646i64.to_le_bytes()),
@@ -69,8 +98,9 @@ pub fn multiple_updates_diff_vaa_results() -> [(U64, I32, I64, U64, I64, U64); 2
6998
}
7099

71100
#[cfg(test)]
72-
pub fn good_update1_results() -> (U64, I32, I64, U64, I64, U64) {
101+
pub fn good_update1_results() -> ([u8; 32], U64, I32, I64, U64, I64, U64) {
73102
(
103+
good_update1_feed_id(),
74104
U64::from(1752170378u64),
75105
I32::from_le_bytes((-8i32).to_le_bytes()),
76106
I64::from_le_bytes(6512459i64.to_le_bytes()),
@@ -81,8 +111,9 @@ pub fn good_update1_results() -> (U64, I32, I64, U64, I64, U64) {
81111
}
82112

83113
#[cfg(test)]
84-
pub fn good_update2_results() -> (U64, I32, I64, U64, I64, U64) {
114+
pub fn good_update2_results() -> ([u8; 32], U64, I32, I64, U64, I64, U64) {
85115
(
116+
good_update1_feed_id(),
86117
U64::from(1752171074u64),
87118
I32::from_le_bytes((-8i32).to_le_bytes()),
88119
I64::from_le_bytes(6468786i64.to_le_bytes()),
@@ -93,9 +124,10 @@ pub fn good_update2_results() -> (U64, I32, I64, U64, I64, U64) {
93124
}
94125

95126
#[cfg(test)]
96-
pub fn multiple_updates_results() -> [(U64, I32, I64, U64, I64, U64); 2] {
127+
pub fn multiple_updates_results() -> [([u8; 32], U64, I32, I64, U64, I64, U64); 2] {
97128
[
98129
(
130+
multiple_updates_first_feed_id(),
99131
U64::from(1751573123u64),
100132
I32::from_le_bytes((-8i32).to_le_bytes()),
101133
I64::from_le_bytes(10990356724259i64.to_le_bytes()),
@@ -104,6 +136,7 @@ pub fn multiple_updates_results() -> [(U64, I32, I64, U64, I64, U64); 2] {
104136
U64::from(3918344000u64),
105137
),
106138
(
139+
multiple_updates_second_feed_id(),
107140
U64::from(1751573123u64),
108141
I32::from_le_bytes((-8i32).to_le_bytes()),
109142
I64::from_le_bytes(258906787480i64.to_le_bytes()),

0 commit comments

Comments
 (0)