fix(near): sdk compat 2.0

This commit is contained in:
Reisen 2023-12-06 13:00:09 +00:00 committed by Reisen
parent bbd3d1add3
commit 5b7ada59bd
3 changed files with 98 additions and 45 deletions

View File

@ -464,12 +464,12 @@ impl Pyth {
pub fn get_price_no_older_than(&self, price_id: PriceIdentifier, age: u64) -> Option<Price> {
self.prices.get(&price_id).and_then(|feed| {
let block_timestamp = env::block_timestamp() / 1_000_000_000;
let price_timestamp = feed.price.timestamp;
let price_timestamp = feed.price.publish_time;
// - If Price older than STALENESS_THRESHOLD, set status to Unknown.
// - If Price newer than now by more than STALENESS_THRESHOLD, set status to Unknown.
// - Any other price around the current time is considered valid.
if u64::abs_diff(block_timestamp, price_timestamp.into()) > age {
if u64::abs_diff(block_timestamp, price_timestamp.try_into().unwrap()) > age {
return None;
}
@ -495,12 +495,12 @@ impl Pyth {
) -> Option<Price> {
self.prices.get(&price_id).and_then(|feed| {
let block_timestamp = env::block_timestamp();
let price_timestamp = feed.ema_price.timestamp;
let price_timestamp = feed.ema_price.publish_time;
// - If Price older than STALENESS_THRESHOLD, set status to Unknown.
// - If Price newer than now by more than STALENESS_THRESHOLD, set status to Unknown.
// - Any other price around the current time is considered valid.
if u64::abs_diff(block_timestamp, price_timestamp.into()) > age {
if u64::abs_diff(block_timestamp, price_timestamp.try_into().unwrap()) > age {
return None;
}
@ -538,7 +538,7 @@ impl Pyth {
fn update_price_feed_if_new(&mut self, price_feed: PriceFeed) -> bool {
match self.prices.get(&price_feed.id) {
Some(stored_price_feed) => {
let update = price_feed.price.timestamp > stored_price_feed.price.timestamp;
let update = price_feed.price.publish_time > stored_price_feed.price.publish_time;
update.then(|| self.prices.insert(&price_feed.id, &price_feed));
update
}

View File

@ -88,13 +88,13 @@ impl near_sdk::serde::Serialize for PriceIdentifier {
#[derive(BorshDeserialize, BorshSerialize, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(crate = "near_sdk::serde")]
pub struct Price {
pub price: I64,
pub price: I64,
/// Confidence interval around the price
pub conf: U64,
pub conf: U64,
/// The exponent
pub expo: i32,
pub expo: i32,
/// Unix timestamp of when this price was computed
pub timestamp: U64,
pub publish_time: i64,
}
/// The PriceFeed structure is stored in the contract under a Price Feed Identifier.
@ -117,20 +117,16 @@ impl From<&PriceAttestation> for PriceFeed {
Self {
id: PriceIdentifier(price_attestation.price_id.to_bytes()),
price: Price {
price: price_attestation.price.into(),
conf: price_attestation.conf.into(),
expo: price_attestation.expo,
timestamp: TryInto::<u64>::try_into(price_attestation.publish_time)
.unwrap()
.into(),
price: price_attestation.price.into(),
conf: price_attestation.conf.into(),
expo: price_attestation.expo,
publish_time: price_attestation.publish_time,
},
ema_price: Price {
price: price_attestation.ema_price.into(),
conf: price_attestation.ema_conf.into(),
expo: price_attestation.expo,
timestamp: TryInto::<u64>::try_into(price_attestation.publish_time)
.unwrap()
.into(),
price: price_attestation.ema_price.into(),
conf: price_attestation.ema_conf.into(),
expo: price_attestation.expo,
publish_time: price_attestation.publish_time,
},
}
}
@ -141,20 +137,16 @@ impl From<&PriceFeedMessage> for PriceFeed {
Self {
id: PriceIdentifier(price_feed_message.feed_id),
price: Price {
price: price_feed_message.price.into(),
conf: price_feed_message.conf.into(),
expo: price_feed_message.exponent,
timestamp: TryInto::<u64>::try_into(price_feed_message.publish_time)
.unwrap()
.into(),
price: price_feed_message.price.into(),
conf: price_feed_message.conf.into(),
expo: price_feed_message.exponent,
publish_time: price_feed_message.publish_time,
},
ema_price: Price {
price: price_feed_message.ema_price.into(),
conf: price_feed_message.ema_conf.into(),
expo: price_feed_message.exponent,
timestamp: TryInto::<u64>::try_into(price_feed_message.publish_time)
.unwrap()
.into(),
price: price_feed_message.ema_price.into(),
conf: price_feed_message.ema_conf.into(),
expo: price_feed_message.exponent,
publish_time: price_feed_message.publish_time,
},
}
}

View File

@ -500,10 +500,10 @@ async fn test_stale_threshold() {
// timestamp and price should be unchanged.
assert_eq!(
Price {
price: 100.into(),
conf: 1.into(),
expo: 8,
timestamp: now.into(),
price: 100.into(),
conf: 1.into(),
expo: 8,
publish_time: now as i64,
},
serde_json::from_slice::<Price>(
&contract
@ -560,10 +560,10 @@ async fn test_stale_threshold() {
// [ref:failed_price_check]
assert_eq!(
Some(Price {
price: 100.into(),
conf: 1.into(),
expo: 8,
timestamp: now.into(),
price: 100.into(),
conf: 1.into(),
expo: 8,
publish_time: now as i64,
}),
serde_json::from_slice::<Option<Price>>(
&contract
@ -1128,10 +1128,10 @@ async fn test_accumulator_updates() {
assert_eq!(
Some(Price {
price: 100.into(),
conf: 100.into(),
expo: 100,
timestamp: 100.into(),
price: 100.into(),
conf: 100.into(),
expo: 100,
publish_time: 100,
}),
serde_json::from_slice::<Option<Price>>(
&contract
@ -1144,3 +1144,64 @@ async fn test_accumulator_updates() {
.unwrap(),
);
}
#[tokio::test]
async fn test_sdk_compat() {
let price = pyth_sdk::Price {
price: i64::MAX,
conf: u64::MAX,
expo: 100,
publish_time: 100,
};
let encoded = serde_json::to_string(&price).unwrap();
let decoded_price: Price = serde_json::from_str(&encoded).unwrap();
assert_eq!(
decoded_price,
Price {
price: i64::MAX.into(),
conf: u64::MAX.into(),
expo: 100,
publish_time: 100,
}
);
}
#[tokio::test]
async fn test_borsh_field_cmopat() {
use near_sdk::borsh::{
self,
BorshDeserialize,
BorshSerialize,
};
let price = pyth_sdk::Price {
price: i64::MAX,
conf: u64::MAX,
expo: 100,
publish_time: 100,
};
// Verify that we can still BorshDeserialize a struct with a different field name. Confirms
// we don't have to migrate the state.
#[derive(Eq, PartialEq, Debug, BorshSerialize, BorshDeserialize)]
struct PriceTester {
price: i64,
conf: u64,
expo: u32,
bad_field_name: u64,
}
let encoded = near_sdk::borsh::BorshSerialize::try_to_vec(&price).unwrap();
let decoded_price: PriceTester =
near_sdk::borsh::BorshDeserialize::try_from_slice(&encoded).unwrap();
assert_eq!(
decoded_price,
PriceTester {
price: i64::MAX.into(),
conf: u64::MAX.into(),
expo: 100,
bad_field_name: 100,
}
);
}