feat(oracles/pyth): add pinocchio example - #707
Conversation
Greptile SummaryAdds a Pinocchio-based Pyth oracle example that manually validates and parses
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Reviews (2): Last reviewed commit: "feat(oracles/pyth): add pinocchio exampl..." | Re-trigger Greptile |
| let message_offset = if verification_level == VERIFICATION_LEVEL_FULL { | ||
| VERIFICATION_LEVEL_OFFSET + 1 | ||
| } else { | ||
| VERIFICATION_LEVEL_OFFSET + 2 | ||
| }; |
There was a problem hiding this comment.
Unknown verification variants accepted
Every verification-level byte other than Full is interpreted as Partial, so a receiver-owned account with a malformed or unsupported Borsh enum discriminant can return success and log unrelated bytes as price fields instead of being rejected.
| let message_offset = if verification_level == VERIFICATION_LEVEL_FULL { | |
| VERIFICATION_LEVEL_OFFSET + 1 | |
| } else { | |
| VERIFICATION_LEVEL_OFFSET + 2 | |
| }; | |
| let message_offset = match verification_level { | |
| VERIFICATION_LEVEL_FULL => VERIFICATION_LEVEL_OFFSET + 1, | |
| 0 => VERIFICATION_LEVEL_OFFSET + 2, | |
| _ => return Err(ProgramError::InvalidAccountData), | |
| }; |
Knowledge Base Used:
There was a problem hiding this comment.
Good catch — fixed in 0e328ad. The verification level is now matched explicitly (Full → 1 byte, Partial → 2 bytes, anything else → InvalidAccountData), so a receiver-owned account with a malformed enum discriminant is rejected rather than misparsed. Added a test that a PriceUpdateV2 with an unknown verification level (2) is rejected — 3 tests passing.
b89fd70 to
d5c713d
Compare
Adds a Pinocchio implementation of the Pyth oracle example, the first pinocchio example under oracles/. The single read_price instruction reads a Pyth pull oracle PriceUpdateV2 account and logs its price fields. There is no Pyth SDK for Pinocchio, so the account is parsed by hand: the program checks the account's owner (the Pyth receiver program) and the anchor account discriminator before trusting the data, then reads the price, confidence, exponent, and publish time by byte offset. The account's VerificationLevel is a variable-size Borsh enum, so the price message offset is computed from it. The litesvm test injects a mock PriceUpdateV2 account with known values via setAccount and asserts the program logs the parsed fields, plus a second case that a non-Pyth-owned account is rejected.
d5c713d to
0e328ad
Compare
What
Adds a Pinocchio implementation of the Pyth oracle example (the first pinocchio example under
oracles/), alongside the existinganchorversion. A singleread_priceinstruction reads a Pyth pull-oraclePriceUpdateV2account and logs its price fields.How it works
There is no Pyth SDK for Pinocchio, so the account is parsed by hand:
rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ) and its 8-byte anchor discriminator — so the program never trusts the price data of an arbitrary account (what anchor'sAccount<PriceUpdateV2>does for free).PriceFeedMessage: it follows the discriminator (8), write authority (32), and theVerificationLevel. That enum is variable-size (Full= 1 byte,Partial { num_signatures }= 2), so the message offset is computed from it.price(i64),conf(u64),exponent(i32), andpublish_time(i64) by little-endian byte offset and log them.Test
litesvm+@solana/kit. Since litesvm doesn't bundle Pyth, the test constructs a mockPriceUpdateV2account with known values and injects it viasetAccount, then:price/conf/exponent/publish_time, andVerified locally:
cargo build-sbf, the litesvm tests,tsc --noEmit, Prettier,cargo fmt --check, Clippy, andpnpm install --frozen-lockfileall clean. (Thedeployscript uses the*.soglob per #702.)AI use: I chose the approach (hand-parsing the
PriceUpdateV2layout, validating owner + discriminator, the mock-account test) and verified the layout and discriminator against thepyth-solana-receiver-sdk/pythnet-sdksources; implementation and tests were written with Claude Code and reviewed by me.