Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: wrap Pythnet/Solana accounts generically #107

Merged
merged 3 commits into from
Feb 19, 2024
Merged

Conversation

Reisen
Copy link
Contributor

@Reisen Reisen commented Feb 9, 2024

See pyth-network/pyth-sdk-rs#113 for how and why the API changed.

The short version is the API now provides the ability to read price accounts on both Solana and Pythnet accounting for the differences in those accounts. That API intentionally does not expose a generic wrapper because the differences (especially as new fields are added) cannot be abstracted.

In pyth-agent, the design currently does not distinguish between which network a price account came from in various code paths, but because these account structures now differ this will require a large refactor that introduces the concept of network differences. Rather than do this now, this introduces a thin wrapper around the API that does act as a generic wrapper, which is possible because it currently doesn't care about extended fields. This is not a decent approach which is why it is not in the API, but is a good stopgap for pyth-agent as It's a small diff to unwind.

The wrapper works by copying the data into a fixed 64 sized account and ignoring the rest of the type entirely. It uses some hacks to do this unfortunately, but the alternative refactor for pyth-agent will be very large.

No new test is added to the integration tests because the tests use program admin to sync accounts and it doesn't work on newer oracle versions. We need to revamp the integration tests in the future to be in Rust and use new permissioning approaches.

@Reisen Reisen requested a review from ali-bahjati February 9, 2024 16:42
@Reisen Reisen force-pushed the push-qkqyyytqnrzp branch 3 times, most recently from 75933b4 to 6f0c20e Compare February 9, 2024 16:59
.context(format!("Could not parse price account at {}", price_key))?;

let next_price = price.next;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this extra variable?

Copy link
Contributor Author

@Reisen Reisen Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah unfortunately the price gets moved when it's inserted into the map, rather than clone the whole thing this just copies out the only useful data we need.

Copy link
Contributor

@jayantk jayantk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems reasonable to me

@@ -288,14 +353,17 @@ impl Oracle {
account_key: &Pubkey,
account: &Account,
) -> Result<()> {
let price_account = *load_price_account(&account.data)
// TODO: remove unwrap()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you did this todo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah thank you, removed comment.

/// and construct the right one regardless of which network we read. This will only work
/// as long as we don't care about any extended fields.
///
/// TODO: Refactor the agent's network handling code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I think it's fine to keep things like this, because we're going to deprecate the solana oracle anyway, and then we won't need both account representations.

@Reisen Reisen force-pushed the push-qkqyyytqnrzp branch from 6f0c20e to 7eca044 Compare February 9, 2024 17:09
n if n == std::mem::size_of::<SolanaPriceAccount>() => 32,
n if n == std::mem::size_of::<PythnetPriceAccount>() => 64,
_ => return None,
};
Copy link
Contributor

@guibescos guibescos Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need unsafe? Why don't you conditionally deserialize as SolanaPriceAccount or PythnetPriceAccount.
Then you use the resulting SolanaPriceAccount or PythnetPriceAccount to build a PriceEntry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you expand on how to do that parsing? You might be right and I missed it but as far as I can tell these types are used mostly with zero copy casts and we haven't properly defined a parser/wire format to do this. In order to construct the underlying array I'm inferring from size, and the slice constructor is inherently unsafe which is where unsafe comes from.

Definitely would prefer a solution without unsafe, can you expand a bit more?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@guibescos guibescos Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably fine copying the data, you're copying it anyway

@@ -423,7 +426,7 @@ impl Adapter {
publisher_accounts: price_account
.comp
.iter()
.filter(|comp| **comp != PriceComp::default())
.filter(|comp| *comp != &PriceComp::default())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lack of this check is not harmful but having a default publisher in logs is annoying.

@ali-bahjati ali-bahjati merged commit d19023b into main Feb 19, 2024
2 checks passed
@ali-bahjati ali-bahjati deleted the push-qkqyyytqnrzp branch February 19, 2024 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants