Skip to content

Commit 40a7845

Browse files
show magic, account type and version usage; simplify rust package
1 parent f92cad1 commit 40a7845

File tree

4 files changed

+179
-131
lines changed

4 files changed

+179
-131
lines changed

pcrust/Cargo.toml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
[package]
2-
name = "pcrust"
2+
name = "pyth-client"
33
version = "0.1.0"
4-
authors = ["Richard Brooks <[email protected]>"]
4+
authors = ["Richard Brooks"]
55
edition = "2018"
6+
license = "Apache-2.0"
7+
homepage = "https://pyth.network"
8+
repository = "https://github.com/pyth-network/pyth-client"
9+
description = "pyth price oracle data structures and example usage"
10+
readme = "false"
11+
keywords = [ "pyth", "solana", "oracle" ]
612

713
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
814

915
[dependencies]
10-
solana-client = { path="../../solana/client" }
11-
solana-sdk = { path="../../solana/sdk" }
12-
solana-program = { path="../../solana/sdk/program" }
16+
solana-client = "1.6.7"
17+
solana-sdk = "1.6.7"
18+
solana-program = "1.6.7"
19+

pcrust/src/lib.rs

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,137 @@
1-
pub mod pc;
1+
pub const MAGIC : u32 = 0xa1b2c3d4;
2+
pub const VERSION_1 : u32 = 1;
3+
pub const VERSION : u32 = VERSION_1;
4+
pub const MAP_TABLE_SIZE : usize = 640;
5+
pub const PROD_ACCT_SIZE : usize = 512;
6+
pub const PROD_HDR_SIZE : usize = 48;
7+
pub const PROD_ATTR_SIZE : usize = PROD_ACCT_SIZE - PROD_HDR_SIZE;
8+
9+
// each account has its own type
10+
#[repr(C)]
11+
pub enum AccountType
12+
{
13+
Unknown,
14+
Mapping,
15+
Product,
16+
Price
17+
}
18+
19+
// aggregate and contributing prices are associated with a status
20+
// only Trading status is valid
21+
#[repr(C)]
22+
pub enum PriceStatus
23+
{
24+
Unknown,
25+
Trading,
26+
Halted,
27+
Auction
28+
}
29+
30+
// ongoing coporate action event - still undergoing dev
31+
#[repr(C)]
32+
pub enum CorpAction
33+
{
34+
NoCorpAct
35+
}
36+
37+
// different types of prices associated with a product
38+
#[repr(C)]
39+
pub enum PriceType
40+
{
41+
Unknown,
42+
Price,
43+
TWAP,
44+
Volatility
45+
}
46+
47+
// solana public key
48+
#[repr(C)]
49+
pub struct AccKey
50+
{
51+
pub val: [u8;32]
52+
}
53+
54+
// Mapping account structure
55+
#[repr(C)]
56+
pub struct Mapping
57+
{
58+
pub magic : u32, // pyth magic number
59+
pub ver : u32, // program version
60+
pub atype : u32, // account type
61+
pub size : u32, // account used size
62+
pub num : u32, // number of product accounts
63+
pub unused : u32,
64+
pub next : AccKey, // next mapping account (if any)
65+
pub products : [AccKey;MAP_TABLE_SIZE]
66+
}
67+
68+
// Product account structure
69+
#[repr(C)]
70+
pub struct Product
71+
{
72+
pub magic : u32, // pyth magic number
73+
pub ver : u32, // program version
74+
pub atype : u32, // account type
75+
pub size : u32, // price account size
76+
pub px_acc : AccKey, // first price account in list
77+
pub attr : [u8;PROD_ATTR_SIZE]
78+
}
79+
80+
// contributing or aggregate price component
81+
#[repr(C)]
82+
pub struct PriceInfo
83+
{
84+
pub price : i64,
85+
pub conf : u64,
86+
pub status : PriceStatus,
87+
pub corp_act : CorpAction,
88+
pub pub_slot : u64
89+
}
90+
91+
// latest component price and price used in aggregate snapshot
92+
#[repr(C)]
93+
pub struct PriceComp
94+
{
95+
publisher : AccKey,
96+
agg : PriceInfo,
97+
latest : PriceInfo
98+
}
99+
100+
// Price account structure
101+
#[repr(C)]
102+
pub struct Price
103+
{
104+
pub magic : u32, // pyth magic number
105+
pub ver : u32, // program version
106+
pub atype : u32, // account type
107+
pub size : u32, // price account size
108+
pub ptype : PriceType, // price or calculation type
109+
pub expo : i32, // price exponent
110+
pub num : u32, // number of component prices
111+
pub unused : u32,
112+
pub curr_slot : u64, // currently accumulating price slot
113+
pub valid_slot : u64, // valid slot-time of agg. price
114+
pub prod : AccKey,
115+
pub next : AccKey,
116+
pub agg_pub : AccKey,
117+
pub agg : PriceInfo,
118+
pub comp : [PriceComp;16]
119+
}
120+
121+
struct AccKeyU64
122+
{
123+
pub val: [u64;4]
124+
}
125+
126+
pub fn cast<T>( d: &[u8] ) -> &T {
127+
let (_, pxa, _) = unsafe { d.align_to::<T>() };
128+
&pxa[0]
129+
}
130+
131+
impl AccKey
132+
{
133+
pub fn is_valid( &self ) -> bool {
134+
let k8 = cast::<AccKeyU64>( &self.val );
135+
return k8.val[0]!=0 || k8.val[1]!=0 || k8.val[2]!=0 || k8.val[3]!=0;
136+
}
137+
}

pcrust/src/main.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
use pcrust::{
2-
pc::Mapping,
3-
pc::Product,
4-
pc::Price,
5-
pc::PriceType,
6-
pc::PriceStatus,
7-
pc::CorpAction,
8-
pc::cast,
9-
pc::PROD_HDR_SIZE
1+
// example usage of pyth-client account structure
2+
// bootstrap all product and pricing accounts from root mapping account
3+
4+
use pyth_client::{
5+
AccountType,
6+
Mapping,
7+
Product,
8+
Price,
9+
PriceType,
10+
PriceStatus,
11+
CorpAction,
12+
cast,
13+
MAGIC,
14+
VERSION_1,
15+
PROD_HDR_SIZE
1016
};
1117
use solana_client::{
1218
rpc_client::RpcClient
@@ -68,13 +74,23 @@ fn main() {
6874
// get Mapping account from key
6975
let map_data = clnt.get_account_data( &akey ).unwrap();
7076
let map_acct = cast::<Mapping>( &map_data );
77+
assert_eq!( map_acct.magic, MAGIC, "not a valid pyth account" );
78+
assert_eq!( map_acct.atype, AccountType::Mapping as u32,
79+
"not a valid pyth mapping account" );
80+
assert_eq!( map_acct.ver, VERSION_1,
81+
"unexpected pyth mapping account version" );
7182

7283
// iget and print each Product in Mapping directory
7384
let mut i = 0;
7485
for prod_akey in &map_acct.products {
7586
let prod_pkey = Pubkey::new( &prod_akey.val );
7687
let prod_data = clnt.get_account_data( &prod_pkey ).unwrap();
7788
let prod_acct = cast::<Product>( &prod_data );
89+
assert_eq!( prod_acct.magic, MAGIC, "not a valid pyth account" );
90+
assert_eq!( prod_acct.atype, AccountType::Product as u32,
91+
"not a valid pyth product account" );
92+
assert_eq!( prod_acct.ver, VERSION_1,
93+
"unexpected pyth product account version" );
7894

7995
// print key and reference data for this Product
8096
println!( "product_account .. {:?}", prod_pkey );
@@ -93,6 +109,11 @@ fn main() {
93109
loop {
94110
let pd = clnt.get_account_data( &px_pkey ).unwrap();
95111
let pa = cast::<Price>( &pd );
112+
assert_eq!( pa.magic, MAGIC, "not a valid pyth account" );
113+
assert_eq!( pa.atype, AccountType::Price as u32,
114+
"not a valid pyth price account" );
115+
assert_eq!( pa.ver, VERSION_1,
116+
"unexpected pyth price account version" );
96117
println!( " price_account .. {:?}", px_pkey );
97118
println!( " price_type ... {}", get_price_type(&pa.ptype));
98119
println!( " exponent ..... {}", pa.expo );

pcrust/src/pc.rs

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)