pyth2wormhole: Add compatible metadata, handle EVM fwd-compat (#165)

* pyth2wormhole: Add compatible metadata, handle EVM fwd-compat

commit-id:d92b42b5

* EVM unit tests: test the non-breaking format change fields

commit-id:3a26e554
This commit is contained in:
Stanisław Drozd 2022-04-15 20:09:20 +01:00 committed by GitHub
parent ded0fb37bd
commit b41708e863
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 147 additions and 61 deletions

View File

@ -106,65 +106,87 @@ contract Pyth is PythGetters, PythSetters, AbstractPyth {
// Deserialize each attestation
for (uint j=0; j < bpa.nAttestations; j++) {
// NOTE: We don't advance the global index immediately.
// attestationIndex is an attestation-local offset used
// for readability and easier debugging.
uint attestationIndex = 0;
// Header
bpa.attestations[j].header.magic = encoded.toUint32(index);
index += 4;
bpa.attestations[j].header.magic = encoded.toUint32(index + attestationIndex);
attestationIndex += 4;
require(bpa.attestations[j].header.magic == 0x50325748, "invalid magic value");
bpa.attestations[j].header.version = encoded.toUint16(index);
index += 2;
bpa.attestations[j].header.version = encoded.toUint16(index + attestationIndex);
attestationIndex += 2;
require(bpa.attestations[j].header.version == 2, "invalid version");
bpa.attestations[j].header.payloadId = encoded.toUint8(index);
index += 1;
bpa.attestations[j].header.payloadId = encoded.toUint8(index + attestationIndex);
attestationIndex += 1;
// Payload ID of 1 required for individual attestation
require(bpa.attestations[j].header.payloadId == 1, "invalid payload ID");
// Attestation
bpa.attestations[j].productId = encoded.toBytes32(index);
index += 32;
bpa.attestations[j].productId = encoded.toBytes32(index + attestationIndex);
attestationIndex += 32;
bpa.attestations[j].priceId = encoded.toBytes32(index);
index += 32;
bpa.attestations[j].priceType = encoded.toUint8(index);
index += 1;
bpa.attestations[j].priceId = encoded.toBytes32(index + attestationIndex);
attestationIndex += 32;
bpa.attestations[j].priceType = encoded.toUint8(index + attestationIndex);
attestationIndex += 1;
bpa.attestations[j].price = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].price = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].exponent = int32(encoded.toUint32(index));
index += 4;
bpa.attestations[j].exponent = int32(encoded.toUint32(index + attestationIndex));
attestationIndex += 4;
bpa.attestations[j].emaPrice.value = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].emaPrice.numerator = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].emaPrice.denominator = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].emaPrice.value = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].emaPrice.numerator = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].emaPrice.denominator = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].emaConf.value = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].emaConf.numerator = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].emaConf.denominator = int64(encoded.toUint64(index));
index += 8;
bpa.attestations[j].emaConf.value = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].emaConf.numerator = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].emaConf.denominator = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].confidenceInterval = encoded.toUint64(index);
index += 8;
bpa.attestations[j].confidenceInterval = encoded.toUint64(index + attestationIndex);
attestationIndex += 8;
bpa.attestations[j].status = encoded.toUint8(index);
index += 1;
bpa.attestations[j].corpAct = encoded.toUint8(index);
index += 1;
bpa.attestations[j].status = encoded.toUint8(index + attestationIndex);
attestationIndex += 1;
bpa.attestations[j].corpAct = encoded.toUint8(index + attestationIndex);
attestationIndex += 1;
bpa.attestations[j].timestamp = encoded.toUint64(index);
index += 8;
bpa.attestations[j].timestamp = encoded.toUint64(index + attestationIndex);
attestationIndex += 8;
bpa.attestations[j].num_publishers = encoded.toUint32(index);
index += 4;
bpa.attestations[j].num_publishers = encoded.toUint32(index + attestationIndex);
attestationIndex += 4;
bpa.attestations[j].max_num_publishers = encoded.toUint32(index);
index += 4;
bpa.attestations[j].max_num_publishers = encoded.toUint32(index + attestationIndex);
attestationIndex += 4;
bpa.attestations[j].publish_time = encoded.toUint64(index + attestationIndex);
attestationIndex += 8;
bpa.attestations[j].prev_publish_time = encoded.toUint64(index + attestationIndex);
attestationIndex += 8;
bpa.attestations[j].prev_price = int64(encoded.toUint64(index + attestationIndex));
attestationIndex += 8;
bpa.attestations[j].prev_conf = encoded.toUint64(index + attestationIndex);
attestationIndex += 8;
require(attestationIndex <= bpa.attestationSize, "INTERNAL: Consumed more than `attestationSize` bytes");
// Respect specified attestation size for forward-compat
index += bpa.attestationSize;
}
}

View File

@ -44,6 +44,10 @@ contract PythInternalStructs {
uint64 timestamp;
uint32 num_publishers;
uint32 max_num_publishers;
uint64 publish_time;
uint64 prev_publish_time;
int64 prev_price;
uint64 prev_conf;
}
struct Rational {

View File

@ -123,8 +123,9 @@ contract("Pyth", function () {
// 3rd price = "0xFCFCFC[...]"
const RAW_BATCH_TIMESTAMP_REGEX = /DEADBEEFFADEDEED/g;
const RAW_BATCH_PRICE_REGEX = /0000002BAD2FEED7/g;
const RAW_PRICE_ATTESTATION_SIZE = 190;
const RAW_BATCH_ATTESTATION_COUNT = 10;
const rawBatchPriceAttestation = "0x" + "50325748000202000A009E503257480002010101010101010101010101010101010101010101010101010101010101010101FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010202020202020202020202020202020202020202020202020202020202020202FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010303030303030303030303030303030303030303030303030303030303030303FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010404040404040404040404040404040404040404040404040404040404040404FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010505050505050505050505050505050505050505050505050505050505050505FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010606060606060606060606060606060606060606060606060606060606060606F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010707070707070707070707070707070707070707070707070707070707070707F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010808080808080808080808080808080808080808080808080808080808080808F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010909090909090909090909090909090909090909090909090909090909090909F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0503257480002010A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0AF5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D0";
const rawBatchPriceAttestation = "0x" + "50325748000202000A00BE503257480002010101010101010101010101010101010101010101010101010101010101010101FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010202020202020202020202020202020202020202020202020202020202020202FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010303030303030303030303030303030303030303030303030303030303030303FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010404040404040404040404040404040404040404040404040404040404040404FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010505050505050505050505050505050505050505050505050505050505050505FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010606060606060606060606060606060606060606060606060606060606060606F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010707070707070707070707070707070707070707070707070707070707070707F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010808080808080808080808080808080808080808080808080808080808080808F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010909090909090909090909090909090909090909090909090909090909090909F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF503257480002010A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0AF5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5010000002BAD2FEED7FFFFFFFDFFFFFFFFFFFFFFD6000000000000000F0000000000000025000000000000002A000000000000045700000000000008AE00000000000000650100DEADBEEFFADEDEED0001E14C0004E6D000000000DEADBEEF00000000DEADBABE0000DEADFACEBEEF000000BADBADBEEF";
// Takes an unsigned 64-bit integer, converts it to hex with 0-padding
function u64ToHex(timestamp) {
@ -156,7 +157,7 @@ contract("Pyth", function () {
assert.equal(parsed.header.payloadId, 2);
assert.equal(parsed.nAttestations, RAW_BATCH_ATTESTATION_COUNT);
assert.equal(parsed.attestationSize, 158);
assert.equal(parsed.attestationSize, RAW_PRICE_ATTESTATION_SIZE);
assert.equal(parsed.attestations.length, parsed.nAttestations);
@ -186,6 +187,10 @@ contract("Pyth", function () {
assert.equal(parsed.attestations[i].timestamp, timestamp);
assert.equal(parsed.attestations[i].num_publishers, 123212);
assert.equal(parsed.attestations[i].max_num_publishers, 321232);
assert.equal(parsed.attestations[i].publish_time, 0xdeadbeef);
assert.equal(parsed.attestations[i].prev_publish_time, 0xdeadbabe);
assert.equal(parsed.attestations[i].prev_price, 0xdeadfacebeef);
assert.equal(parsed.attestations[i].prev_conf, 0xbadbadbeef);
console.debug(`attestation ${i + 1}/${parsed.attestations.length} parsed OK`);
}

8
terra/Cargo.lock generated
View File

@ -1378,9 +1378,9 @@ dependencies = [
[[package]]
name = "pyth-sdk"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c610102a39fc4bae29a3b5a628ee134d25afb3dca3937692f5e634f1287fe0b4"
checksum = "cb06993b8c8ad7f50042e8b6b6ae4ed2a98722495845b12efc9a12f4301b901b"
dependencies = [
"borsh",
"borsh-derive",
@ -1390,9 +1390,9 @@ dependencies = [
[[package]]
name = "pyth-sdk-solana"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1fdc94592a28fa829b0d6fa619392b1a1744048e5b78a74a4ba93cf541eddae"
checksum = "b83f33cbdeccc350e021f6b4bc714655aa38352fac80a93b16b1902863aedb62"
dependencies = [
"borsh",
"borsh-derive",

View File

@ -33,7 +33,7 @@ lazy_static = "1.4.0"
bigint = "4"
p2w-sdk = { path = "../../../third_party/pyth/p2w-sdk/rust" }
solana-program = "=1.8.16"
pyth-sdk = { version = "0.2.0" }
pyth-sdk = "0.3.0"
[dev-dependencies]
cosmwasm-vm = { version = "0.16.0", default-features = false }

View File

@ -130,6 +130,7 @@ fn process_batch_attestation(
let price_feed = PriceFeed::new(
price_attestation.price_id.to_bytes(),
price_attestation.status,
price_attestation.publish_time,
price_attestation.expo,
price_attestation.max_num_publishers, // max_num_publishers data is currently unavailable
price_attestation.num_publishers, // num_publishers data is currently unavailable
@ -138,6 +139,9 @@ fn process_batch_attestation(
price_attestation.confidence_interval,
price_attestation.ema_price.val,
price_attestation.ema_conf.val as u64,
price_attestation.prev_price,
price_attestation.prev_conf,
price_attestation.prev_publish_time,
);
let attestation_time = Timestamp::from_seconds(price_attestation.timestamp as u64);

View File

@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1.2
# Wormhole-specific setup for pyth
FROM pythfoundation/pyth-client:devnet-v2.10.1
FROM pythfoundation/pyth-client:devnet-v2.11.1
USER root

View File

@ -631,9 +631,9 @@ dependencies = [
[[package]]
name = "pyth-sdk"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c610102a39fc4bae29a3b5a628ee134d25afb3dca3937692f5e634f1287fe0b4"
checksum = "cb06993b8c8ad7f50042e8b6b6ae4ed2a98722495845b12efc9a12f4301b901b"
dependencies = [
"borsh",
"borsh-derive",
@ -643,9 +643,9 @@ dependencies = [
[[package]]
name = "pyth-sdk-solana"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1fdc94592a28fa829b0d6fa619392b1a1744048e5b78a74a4ba93cf541eddae"
checksum = "b83f33cbdeccc350e021f6b4bc714655aa38352fac80a93b16b1902863aedb62"
dependencies = [
"borsh",
"borsh-derive",

View File

@ -15,7 +15,7 @@ wasm = ["wasm-bindgen", "solana"]
[dependencies]
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
pyth-sdk-solana = { version = "0.2.0" }
pyth-sdk-solana = "0.3.0"
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"], optional = true}
solitaire = { path = "../../../../solana/solitaire/program", optional = true }
solana-program = "1.8.16"

View File

@ -32,7 +32,6 @@ use solana_program::pubkey::Pubkey;
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
pub mod wasm;
/// Quality of life type alias for wrapping up boxed errors.
pub type ErrBox = Box<dyn std::error::Error>;
/// Precedes every message implementing the p2w serialization format
@ -73,9 +72,17 @@ pub struct PriceAttestation {
pub confidence_interval: u64,
pub status: PriceStatus,
pub corp_act: CorpAction,
// TODO(2022-04-07) format v3: Rename this aptly named timestamp
// field to attestation_time (it's a grey area in terms of
// compatibility and v3 is due very soon either way)
/// NOTE: SOL on-chain time of attestation
pub timestamp: UnixTimestamp,
pub num_publishers: u32,
pub max_num_publishers: u32,
pub publish_time: UnixTimestamp,
pub prev_publish_time: UnixTimestamp,
pub prev_price: i64,
pub prev_conf: u64,
}
#[derive(Clone, Default, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
@ -236,7 +243,7 @@ pub fn deserialize_rational(mut bytes: impl Read) -> Result<Rational, ErrBox> {
impl PriceAttestation {
pub fn from_pyth_price_bytes(
price_id: Pubkey,
timestamp: UnixTimestamp,
attestation_time: UnixTimestamp,
value: &[u8],
) -> Result<Self, ErrBox> {
let price = pyth_sdk_solana::state::load_price_account(value)?;
@ -252,9 +259,13 @@ impl PriceAttestation {
confidence_interval: price.agg.conf,
status: price.agg.status,
corp_act: price.agg.corp_act,
timestamp: timestamp,
timestamp: attestation_time,
num_publishers: price.num_qt,
max_num_publishers: price.num,
publish_time: price.timestamp,
prev_publish_time: price.prev_timestamp,
prev_price: price.prev_price,
prev_conf: price.prev_conf,
})
}
@ -276,6 +287,10 @@ impl PriceAttestation {
timestamp,
num_publishers,
max_num_publishers,
publish_time,
prev_publish_time,
prev_price,
prev_conf
} = self;
// magic
@ -326,6 +341,18 @@ impl PriceAttestation {
// max_num_publishers
buf.extend_from_slice(&max_num_publishers.to_be_bytes()[..]);
// publish_time
buf.extend_from_slice(&publish_time.to_be_bytes()[..]);
// prev_publish_time
buf.extend_from_slice(&prev_publish_time.to_be_bytes()[..]);
// prev_price
buf.extend_from_slice(&prev_price.to_be_bytes()[..]);
// prev_conf
buf.extend_from_slice(&prev_conf.to_be_bytes()[..]);
buf
}
pub fn deserialize(mut bytes: impl Read) -> Result<Self, ErrBox> {
@ -433,6 +460,22 @@ impl PriceAttestation {
bytes.read_exact(max_num_publishers_vec.as_mut_slice())?;
let max_num_publishers = u32::from_be_bytes(max_num_publishers_vec.as_slice().try_into()?);
let mut publish_time_vec = vec![0u8; mem::size_of::<UnixTimestamp>()];
bytes.read_exact(publish_time_vec.as_mut_slice())?;
let publish_time = UnixTimestamp::from_be_bytes(publish_time_vec.as_slice().try_into()?);
let mut prev_publish_time_vec = vec![0u8; mem::size_of::<UnixTimestamp>()];
bytes.read_exact(prev_publish_time_vec.as_mut_slice())?;
let prev_publish_time = UnixTimestamp::from_be_bytes(prev_publish_time_vec.as_slice().try_into()?);
let mut prev_price_vec = vec![0u8; mem::size_of::<i64>()];
bytes.read_exact(prev_price_vec.as_mut_slice())?;
let prev_price = i64::from_be_bytes(prev_price_vec.as_slice().try_into()?);
let mut prev_conf_vec = vec![0u8; mem::size_of::<u64>()];
bytes.read_exact(prev_conf_vec.as_mut_slice())?;
let prev_conf = u64::from_be_bytes(prev_conf_vec.as_slice().try_into()?);
Ok(Self {
product_id,
price_id,
@ -447,6 +490,10 @@ impl PriceAttestation {
timestamp,
num_publishers,
max_num_publishers,
publish_time,
prev_publish_time,
prev_price,
prev_conf,
})
}
}
@ -487,7 +534,11 @@ mod tests {
corp_act: CorpAction::NoCorpAct,
timestamp: (0xdeadbeeffadedeedu64) as i64,
num_publishers: 123212u32,
max_num_publishers: 321232u32
max_num_publishers: 321232u32,
publish_time: 0xdeadbeefi64,
prev_publish_time: 0xdeadbabei64,
prev_price: 0xdeadfacebeefi64,
prev_conf: 0xbadbadbeefu64, // I could do this all day -SD
}
}