Skip to content

Commit

Permalink
feat: add publisher caps to the validator (#412)
Browse files Browse the repository at this point in the history
* feat(program): match version with pythnet

* feat: validator access point (wip)

* feat: add price account flags

* feat(program): fill out validator aggregation code

* feat: don't aggregate on v2, clear message buffer, report validator aggregation errors

* feat: return price feed messages from validator aggregation

* test: enable v2 aggregation

* test: test aggregation toggle

* fix: don't aggregate in validator if already aggregated in this slot

* chore: reexport solana_program and add derive debug

* chore: add comments

* fix: don't revert if c_upd_aggregate returns false

* fix: make update_price_cumulative infallible; don't generate v2 messages until v1 buffer is cleared

* chore: remove publisher sorting hack

* chore: remove AggregationOutcome

* fix: remove debug_assert

* fix: allow clearing message buffers regardless of message_sent_ flag

* test: add test_upd_price_with_validator

* checkpoint

* fix import

* go

* try this

* go

* try again

* Checkpoint

* go

* rename

* add test

* cargo lock

* go

* go

* format

* rename

* bump again

* add z

* go

* chore: add missing imports and fix warnings

* add m

* Clippy

* Update program/rust/src/accounts/price.rs

Co-authored-by: Pavel Strakhov <ri@idzaaus.org>

* Update program/rust/src/accounts/price.rs

Co-authored-by: Pavel Strakhov <ri@idzaaus.org>

* Remove vector

* fix: remove unwrap

* add comments

* fix: undo this

* another comment

* add comment

* use checked indexing

* fix: use crates version of pythnet-sdk

---------

Co-authored-by: Reisen <reisen@morphism.org>
Co-authored-by: Pavel Strakhov <ri@idzaaus.org>
  • Loading branch information
3 people authored Jul 31, 2024
1 parent 0f6a651 commit 1de3dd4
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 43 deletions.
70 changes: 58 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions program/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ num-traits = "0.2"
byteorder = "1.4.3"
serde = { version = "1.0", features = ["derive"], optional = true }
strum = { version = "0.24.1", features = ["derive"], optional = true }
pythnet-sdk = { git = "https://github.com/pyth-network/pyth-crosschain", rev="60144002053a93f424be70decd8a8ccb8d618d81"}
pythnet-sdk = "2.2.0"
solana-sdk = { version = "=1.14.17", optional = true }
bitflags = { version = "2.6.0", features = ["bytemuck"] }

Expand All @@ -31,7 +31,7 @@ rand = "0.8.5"
quickcheck_macros = "1"
bincode = "1.3.3"
serde = { version = "1.0", features = ["derive"] }
pythnet-sdk = { git = "https://github.com/pyth-network/pyth-crosschain", rev="60144002053a93f424be70decd8a8ccb8d618d81", features = ["quickcheck"]}
pythnet-sdk = { version = "2.2.0" , features = ["quickcheck"]}
serde_json = "1.0"
test-generator = "0.3.1"
csv = "1.1"
Expand Down
34 changes: 29 additions & 5 deletions program/rust/src/accounts/price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ use {
},
pythnet_sdk::messages::{
PriceFeedMessage,
PublisherStakeCapsMessage,
TwapMessage,
},
solana_program::pubkey::Pubkey,
std::mem::size_of,
std::{
mem::size_of,
u16,
},
};

/// Pythnet-specific PriceAccount implementation
Expand Down Expand Up @@ -111,7 +115,7 @@ mod price_pythnet {
};

PriceFeedMessage {
id: key.to_bytes(),
feed_id: key.to_bytes(),
price,
conf,
exponent: self.exponent,
Expand Down Expand Up @@ -141,7 +145,7 @@ mod price_pythnet {
};

TwapMessage {
id: key.to_bytes(),
feed_id: key.to_bytes(),
cumulative_price: self.price_cumulative.price,
cumulative_conf: self.price_cumulative.conf,
num_down_slots: self.price_cumulative.num_down_slots,
Expand Down Expand Up @@ -270,7 +274,7 @@ impl PythOracleSerialize for PriceFeedMessage {
bytes[i..i + 1].clone_from_slice(&[DISCRIMINATOR]);
i += 1;

bytes[i..i + 32].clone_from_slice(&self.id[..]);
bytes[i..i + 32].clone_from_slice(&self.feed_id[..]);
i += 32;

bytes[i..i + 8].clone_from_slice(&self.price.to_be_bytes());
Expand Down Expand Up @@ -313,7 +317,7 @@ impl PythOracleSerialize for TwapMessage {
bytes[i..i + 1].clone_from_slice(&[DISCRIMINATOR]);
i += 1;

bytes[i..i + 32].clone_from_slice(&self.id[..]);
bytes[i..i + 32].clone_from_slice(&self.feed_id[..]);
i += 32;

bytes[i..i + 16].clone_from_slice(&self.cumulative_price.to_be_bytes());
Expand All @@ -340,3 +344,23 @@ impl PythOracleSerialize for TwapMessage {
bytes.to_vec()
}
}

impl PythOracleSerialize for PublisherStakeCapsMessage {
fn to_bytes(self) -> Vec<u8> {
const DISCRIMINATOR: u8 = 2;
let mut result = vec![DISCRIMINATOR];
result.extend_from_slice(&self.publish_time.to_be_bytes());
result.extend_from_slice(
&u16::try_from(self.caps.as_ref().len())
.unwrap_or(u16::MAX)
.to_be_bytes(),
);

for cap in self.caps {
result.extend_from_slice(&cap.publisher);
result.extend_from_slice(&cap.cap.to_be_bytes());
}

result
}
}
27 changes: 27 additions & 0 deletions program/rust/src/tests/test_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ use {
messages::{
Message,
PriceFeedMessage,
PublisherStakeCapsMessage,
TwapMessage,
},
wire::from_slice,
},
quickcheck::{
Gen,
QuickCheck,
},
quickcheck_macros::quickcheck,
};

Expand Down Expand Up @@ -38,3 +43,25 @@ fn test_twap_message_roundtrip(input: TwapMessage) -> bool {
_ => false,
}
}


fn prop_publisher_caps_message_roundtrip(input: PublisherStakeCapsMessage) -> bool {
let reconstructed = from_slice::<BigEndian, Message>(&input.clone().to_bytes()).unwrap();

println!("Failed test case:");
println!("{:?}", input);
println!("{:?}", reconstructed);

match reconstructed {
Message::PublisherStakeCapsMessage(reconstructed) => reconstructed == input,
_ => false,
}
}

#[test]
fn test_publisher_caps_message_roundtrip() {
// Configure the size parameter for the generator
QuickCheck::new()
.gen(Gen::new(1024))
.quickcheck(prop_publisher_caps_message_roundtrip as fn(PublisherStakeCapsMessage) -> bool);
}
8 changes: 4 additions & 4 deletions program/rust/src/tests/test_upd_price_with_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ fn test_upd_price_with_validator() {
.unwrap();
let expected_messages1 = [
PriceFeedMessage {
id: price_account.key.to_bytes(),
feed_id: price_account.key.to_bytes(),
price: 42,
conf: 2,
exponent: 0,
Expand All @@ -141,7 +141,7 @@ fn test_upd_price_with_validator() {
}
.to_bytes(),
TwapMessage {
id: price_account.key.to_bytes(),
feed_id: price_account.key.to_bytes(),
cumulative_price: 42,
cumulative_conf: 2,
num_down_slots: 0,
Expand All @@ -161,7 +161,7 @@ fn test_upd_price_with_validator() {

let expected_messages2 = [
PriceFeedMessage {
id: price_account.key.to_bytes(),
feed_id: price_account.key.to_bytes(),
price: 42,
conf: 2,
exponent: 0,
Expand All @@ -172,7 +172,7 @@ fn test_upd_price_with_validator() {
}
.to_bytes(),
TwapMessage {
id: price_account.key.to_bytes(),
feed_id: price_account.key.to_bytes(),
cumulative_price: 84,
cumulative_conf: 4,
num_down_slots: 0,
Expand Down
Loading

0 comments on commit 1de3dd4

Please sign in to comment.