Skip to content

Commit 9ef18a2

Browse files
authored
Pubkey (#277)
* Pubkey * Use fault for zero pubkey * Restore tests * Add sanity check test for Pubkey::default * Get current onchain bytes can get interpreted as Pubkey properly * Update test
1 parent 1a6ce1b commit 9ef18a2

16 files changed

+114
-268
lines changed

program/rust/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ num-traits = "0.2"
1919
solana-program-test = "=1.10.29"
2020
solana-sdk = "=1.10.29"
2121
tokio = "1.14.1"
22+
hex = "0.3.1"
2223

2324
[features]
2425
debug = []

program/rust/src/c_oracle_header.rs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ pub struct PriceAccount {
8282
pub unused_2_: i16,
8383
pub unused_3_: i32,
8484
/// Corresponding product account
85-
pub product_account: CPubkey,
85+
pub product_account: Pubkey,
8686
/// Next price account in the list
87-
pub next_price_account: CPubkey,
87+
pub next_price_account: Pubkey,
8888
/// Second to last slot where aggregation was succesful (i.e. status : TRADING)
8989
pub prev_slot_: u64,
9090
/// Aggregate price at prev_slot_
@@ -102,7 +102,7 @@ pub struct PriceAccount {
102102
#[repr(C)]
103103
#[derive(Copy, Clone, Pod, Zeroable)]
104104
pub struct PriceComponent {
105-
pub pub_: CPubkey,
105+
pub pub_: Pubkey,
106106
pub agg_: PriceInfo,
107107
pub latest_: PriceInfo,
108108
}
@@ -138,7 +138,7 @@ pub struct AccountHeader {
138138
#[derive(Copy, Clone, Pod, Zeroable)]
139139
pub struct ProductAccount {
140140
pub header: AccountHeader,
141-
pub first_price_account: CPubkey,
141+
pub first_price_account: Pubkey,
142142
}
143143

144144
#[repr(C)]
@@ -147,35 +147,12 @@ pub struct MappingAccount {
147147
pub header: AccountHeader,
148148
pub number_of_products: u32,
149149
pub unused_: u32,
150-
pub next_mapping_account: CPubkey,
151-
pub products_list: [CPubkey; PC_MAP_TABLE_SIZE as usize],
150+
pub next_mapping_account: Pubkey,
151+
pub products_list: [Pubkey; PC_MAP_TABLE_SIZE as usize],
152152
}
153153

154-
// Unsafe impl because CPubkey is a union
155-
unsafe impl Pod for CPubkey {
156-
}
157-
unsafe impl Zeroable for CPubkey {
158-
}
159-
160-
161154
// Unsafe impl because product_list is of size 640 and there's no derived trait for this size
162155
unsafe impl Pod for MappingAccount {
163156
}
164157
unsafe impl Zeroable for MappingAccount {
165158
}
166-
167-
#[repr(C)]
168-
#[derive(Copy, Clone)]
169-
pub union CPubkey {
170-
pub k1_: [u8; 32usize],
171-
pub k8_: [u64; 4usize],
172-
}
173-
174-
impl CPubkey {
175-
pub fn new_unique() -> CPubkey {
176-
let solana_unique = Pubkey::new_unique();
177-
CPubkey {
178-
k1_: solana_unique.to_bytes(),
179-
}
180-
}
181-
}

program/rust/src/instruction.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use crate::c_oracle_header::{
2-
CPubkey,
3-
PC_VERSION,
4-
};
1+
use crate::c_oracle_header::PC_VERSION;
52
use crate::deserialize::load;
63
use crate::error::OracleError;
74
use bytemuck::{
@@ -13,6 +10,7 @@ use num_derive::{
1310
ToPrimitive,
1411
};
1512
use num_traits::FromPrimitive;
13+
use solana_program::pubkey::Pubkey;
1614

1715
/// WARNING : NEW COMMANDS SHOULD BE ADDED AT THE END OF THE LIST
1816
#[repr(i32)]
@@ -122,7 +120,7 @@ pub type InitPriceArgs = AddPriceArgs;
122120
#[derive(Zeroable, Pod, Copy, Clone)]
123121
pub struct AddPublisherArgs {
124122
pub header: CommandHeader,
125-
pub publisher: CPubkey,
123+
pub publisher: Pubkey,
126124
}
127125

128126
pub type DelPublisherArgs = AddPublisherArgs;

program/rust/src/rust_oracle.rs

Lines changed: 23 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::mem::{
44
};
55

66
use crate::c_oracle_header::{
7-
CPubkey,
87
MappingAccount,
98
PriceAccount,
109
PriceComponent,
@@ -40,19 +39,12 @@ use crate::utils::{
4039
check_valid_signable_account,
4140
check_valid_writable_account,
4241
is_component_update,
43-
pubkey_assign,
44-
pubkey_clear,
45-
pubkey_equal,
46-
pubkey_is_zero,
4742
pyth_assert,
4843
read_pc_str_t,
4944
try_convert,
5045
};
5146
use crate::OracleError;
52-
use bytemuck::{
53-
bytes_of,
54-
bytes_of_mut,
55-
};
47+
use bytemuck::bytes_of_mut;
5648
use solana_program::account_info::AccountInfo;
5749
use solana_program::clock::Clock;
5850
use solana_program::entrypoint::ProgramResult;
@@ -197,15 +189,12 @@ pub fn add_mapping(
197189
let mut cur_mapping = load_checked::<MappingAccount>(cur_mapping, hdr.version)?;
198190
pyth_assert(
199191
cur_mapping.number_of_products == PC_MAP_TABLE_SIZE
200-
&& pubkey_is_zero(&cur_mapping.next_mapping_account),
192+
&& cur_mapping.next_mapping_account == Pubkey::default(),
201193
ProgramError::InvalidArgument,
202194
)?;
203195

204196
initialize_pyth_account_checked::<MappingAccount>(next_mapping, hdr.version)?;
205-
pubkey_assign(
206-
&mut cur_mapping.next_mapping_account,
207-
&next_mapping.key.to_bytes(),
208-
);
197+
cur_mapping.next_mapping_account = *next_mapping.key;
209198

210199
Ok(())
211200
}
@@ -240,10 +229,7 @@ pub fn upd_price(
240229

241230
// Verify that publisher is authorized
242231
while publisher_index < price_data.num_ as usize {
243-
if pubkey_equal(
244-
&price_data.comp_[publisher_index].pub_,
245-
&funding_account.key.to_bytes(),
246-
) {
232+
if price_data.comp_[publisher_index].pub_ == *funding_account.key {
247233
break;
248234
}
249235
publisher_index += 1;
@@ -357,18 +343,9 @@ pub fn add_price(
357343
initialize_pyth_account_checked::<PriceAccount>(price_account, cmd_args.header.version)?;
358344
price_data.exponent = cmd_args.exponent;
359345
price_data.price_type = cmd_args.price_type;
360-
pubkey_assign(
361-
&mut price_data.product_account,
362-
&product_account.key.to_bytes(),
363-
);
364-
pubkey_assign(
365-
&mut price_data.next_price_account,
366-
bytes_of(&product_data.first_price_account),
367-
);
368-
pubkey_assign(
369-
&mut product_data.first_price_account,
370-
&price_account.key.to_bytes(),
371-
);
346+
price_data.product_account = *product_account.key;
347+
price_data.next_price_account = product_data.first_price_account;
348+
product_data.first_price_account = *price_account.key;
372349

373350
Ok(())
374351
}
@@ -399,22 +376,16 @@ pub fn del_price(
399376
let mut product_data = load_checked::<ProductAccount>(product_account, cmd_args.version)?;
400377
let price_data = load_checked::<PriceAccount>(price_account, cmd_args.version)?;
401378
pyth_assert(
402-
pubkey_equal(
403-
&product_data.first_price_account,
404-
&price_account.key.to_bytes(),
405-
),
379+
product_data.first_price_account == *price_account.key,
406380
ProgramError::InvalidArgument,
407381
)?;
408382

409383
pyth_assert(
410-
pubkey_equal(&price_data.product_account, &product_account.key.to_bytes()),
384+
price_data.product_account == *product_account.key,
411385
ProgramError::InvalidArgument,
412386
)?;
413387

414-
pubkey_assign(
415-
&mut product_data.first_price_account,
416-
bytes_of(&price_data.next_price_account),
417-
);
388+
product_data.first_price_account = price_data.next_price_account;
418389
}
419390

420391
// Zero out the balance of the price account to delete it.
@@ -502,7 +473,7 @@ pub fn add_publisher(
502473

503474
pyth_assert(
504475
instruction_data.len() == size_of::<AddPublisherArgs>()
505-
&& !pubkey_is_zero(&cmd_args.publisher),
476+
&& cmd_args.publisher != Pubkey::default(),
506477
ProgramError::InvalidArgument,
507478
)?;
508479

@@ -521,7 +492,7 @@ pub fn add_publisher(
521492
}
522493

523494
for i in 0..(price_data.num_ as usize) {
524-
if pubkey_equal(&cmd_args.publisher, bytes_of(&price_data.comp_[i].pub_)) {
495+
if cmd_args.publisher == price_data.comp_[i].pub_ {
525496
return Err(ProgramError::InvalidArgument);
526497
}
527498
}
@@ -532,10 +503,7 @@ pub fn add_publisher(
532503
0,
533504
size_of::<PriceComponent>(),
534505
);
535-
pubkey_assign(
536-
&mut price_data.comp_[current_index].pub_,
537-
bytes_of(&cmd_args.publisher),
538-
);
506+
price_data.comp_[current_index].pub_ = cmd_args.publisher;
539507
price_data.num_ += 1;
540508
price_data.header.size =
541509
try_convert::<_, u32>(size_of::<PriceAccount>() - size_of_val(&price_data.comp_))?
@@ -555,7 +523,7 @@ pub fn del_publisher(
555523

556524
pyth_assert(
557525
instruction_data.len() == size_of::<DelPublisherArgs>()
558-
&& !pubkey_is_zero(&cmd_args.publisher),
526+
&& cmd_args.publisher != Pubkey::default(),
559527
ProgramError::InvalidArgument,
560528
)?;
561529

@@ -570,7 +538,7 @@ pub fn del_publisher(
570538
let mut price_data = load_checked::<PriceAccount>(price_account, cmd_args.header.version)?;
571539

572540
for i in 0..(price_data.num_ as usize) {
573-
if pubkey_equal(&cmd_args.publisher, bytes_of(&price_data.comp_[i].pub_)) {
541+
if cmd_args.publisher == price_data.comp_[i].pub_ {
574542
for j in i + 1..(price_data.num_ as usize) {
575543
price_data.comp_[j - 1] = price_data.comp_[j];
576544
}
@@ -615,15 +583,12 @@ pub fn add_product(
615583
initialize_pyth_account_checked::<ProductAccount>(new_product_account, hdr.version)?;
616584

617585
let current_index: usize = try_convert(mapping_data.number_of_products)?;
618-
pubkey_assign(
619-
&mut mapping_data.products_list[current_index],
620-
bytes_of(&new_product_account.key.to_bytes()),
621-
);
586+
mapping_data.products_list[current_index] = *new_product_account.key;
622587
mapping_data.number_of_products += 1;
623588
mapping_data.header.size = try_convert::<_, u32>(
624589
size_of::<MappingAccount>() - size_of_val(&mapping_data.products_list),
625590
)? + mapping_data.number_of_products
626-
* try_convert::<_, u32>(size_of::<CPubkey>())?;
591+
* try_convert::<_, u32>(size_of::<Pubkey>())?;
627592

628593
Ok(())
629594
}
@@ -746,15 +711,15 @@ pub fn del_product(
746711
ProgramError::InvalidArgument,
747712
)?;
748713
pyth_assert(
749-
pubkey_is_zero(&product_data.first_price_account),
714+
product_data.first_price_account == Pubkey::default(),
750715
ProgramError::InvalidArgument,
751716
)?;
752717

753-
let product_key = product_account.key.to_bytes();
718+
let product_key = product_account.key;
754719
let product_index = mapping_data
755720
.products_list
756721
.iter()
757-
.position(|x| pubkey_equal(x, &product_key))
722+
.position(|x| *x == *product_key)
758723
.ok_or(ProgramError::InvalidArgument)?;
759724

760725
let num_after_removal: usize = try_convert(
@@ -765,16 +730,13 @@ pub fn del_product(
765730
)?;
766731

767732
let last_key_bytes = mapping_data.products_list[num_after_removal];
768-
pubkey_assign(
769-
&mut mapping_data.products_list[product_index],
770-
bytes_of(&last_key_bytes),
771-
);
772-
pubkey_clear(&mut mapping_data.products_list[num_after_removal]);
733+
mapping_data.products_list[product_index] = last_key_bytes;
734+
mapping_data.products_list[num_after_removal] = Pubkey::default();
773735
mapping_data.number_of_products = try_convert::<_, u32>(num_after_removal)?;
774736
mapping_data.header.size = try_convert::<_, u32>(
775737
size_of::<MappingAccount>() - size_of_val(&mapping_data.products_list),
776738
)? + mapping_data.number_of_products
777-
* try_convert::<_, u32>(size_of::<CPubkey>())?;
739+
* try_convert::<_, u32>(size_of::<Pubkey>())?;
778740
}
779741

780742
// Zero out the balance of the price account to delete it.

program/rust/src/tests/test_add_mapping.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,7 @@ use crate::instruction::{
1515
};
1616
use crate::processor::process_instruction;
1717
use crate::tests::test_utils::AccountSetup;
18-
use crate::utils::{
19-
clear_account,
20-
pubkey_assign,
21-
pubkey_equal,
22-
pubkey_is_zero,
23-
};
18+
use crate::utils::clear_account;
2419
use bytemuck::bytes_of;
2520
use solana_program::program_error::ProgramError;
2621
use solana_program::pubkey::Pubkey;
@@ -64,15 +59,9 @@ fn test_add_mapping() {
6459
let mut cur_mapping_data =
6560
load_checked::<MappingAccount>(&cur_mapping, PC_VERSION).unwrap();
6661

67-
assert!(pubkey_equal(
68-
&cur_mapping_data.next_mapping_account,
69-
&next_mapping.key.to_bytes()
70-
));
71-
assert!(pubkey_is_zero(&next_mapping_data.next_mapping_account));
72-
pubkey_assign(
73-
&mut cur_mapping_data.next_mapping_account,
74-
&Pubkey::default().to_bytes(),
75-
);
62+
assert!(cur_mapping_data.next_mapping_account == *next_mapping.key);
63+
assert!(next_mapping_data.next_mapping_account == Pubkey::default());
64+
cur_mapping_data.next_mapping_account = Pubkey::default();
7665
cur_mapping_data.number_of_products = 0;
7766
}
7867

@@ -94,7 +83,7 @@ fn test_add_mapping() {
9483
{
9584
let mut cur_mapping_data =
9685
load_checked::<MappingAccount>(&cur_mapping, PC_VERSION).unwrap();
97-
assert!(pubkey_is_zero(&cur_mapping_data.next_mapping_account));
86+
assert!(cur_mapping_data.next_mapping_account == Pubkey::default());
9887
cur_mapping_data.number_of_products = PC_MAP_TABLE_SIZE;
9988
cur_mapping_data.header.magic_number = 0;
10089
}

0 commit comments

Comments
 (0)