Skip to content

Commit e0f888f

Browse files
authored
Rust/del publisher (#237)
* Simplistic trait * Remove irrelevant file * Rename * Delete * Add functions to initialize tests * Restore rust oracle * Add comment * Upd product uses the new syntax * Formatted * Implemented * Add test * Prune oracle * Lint * Delete * Update memset
1 parent 612e9bf commit e0f888f

File tree

7 files changed

+241
-140
lines changed

7 files changed

+241
-140
lines changed

program/c/src/oracle/oracle.c

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -107,54 +107,6 @@ static uint64_t init_price( SolParameters *prm, SolAccountInfo *ka )
107107
return SUCCESS;
108108
}
109109

110-
// remove publisher from price node
111-
static uint64_t del_publisher( SolParameters *prm, SolAccountInfo *ka )
112-
{
113-
// Validate command parameters
114-
cmd_del_publisher_t *cptr = (cmd_del_publisher_t*)prm->data;
115-
if ( prm->data_len != sizeof( cmd_del_publisher_t ) ||
116-
pc_pub_key_is_zero( &cptr->pub_ ) ) {
117-
return ERROR_INVALID_ARGUMENT;
118-
}
119-
120-
// Account (1) is the price account
121-
// Verify that this is signed, writable with correct ownership
122-
// and size
123-
if ( prm->ka_num != 2 ||
124-
!valid_funding_account( &ka[0] ) ||
125-
!valid_signable_account( prm, &ka[1], sizeof( pc_price_t ) ) ) {
126-
return ERROR_INVALID_ARGUMENT;
127-
}
128-
129-
// Verify that symbol account is initialized and corresponds to the
130-
// same symbol and price-type in the instruction parameters
131-
pc_price_t *sptr = (pc_price_t*)ka[1].data;
132-
if ( sptr->magic_ != PC_MAGIC ||
133-
sptr->ver_ != cptr->ver_ ||
134-
sptr->type_ != PC_ACCTYPE_PRICE ) {
135-
return ERROR_INVALID_ARGUMENT;
136-
}
137-
138-
// try to remove publisher
139-
for(uint32_t i=0; i != sptr->num_; ++i ) {
140-
pc_price_comp_t *iptr = &sptr->comp_[i];
141-
if ( pc_pub_key_equal( &iptr->pub_, &cptr->pub_ ) ) {
142-
for( unsigned j=i+1; j != sptr->num_; ++j ) {
143-
pc_price_comp_t *jptr = &sptr->comp_[j];
144-
iptr[0] = jptr[0];
145-
iptr = jptr;
146-
}
147-
--sptr->num_;
148-
sol_memset( iptr, 0, sizeof( pc_price_comp_t ) );
149-
// update size of account
150-
sptr->size_ = sizeof( pc_price_t ) - sizeof( sptr->comp_ ) +
151-
sptr->num_ * sizeof( pc_price_comp_t );
152-
return SUCCESS;
153-
}
154-
}
155-
return ERROR_INVALID_ARGUMENT;
156-
}
157-
158110
static uint64_t upd_price( SolParameters *prm, SolAccountInfo *ka )
159111
{
160112
// Validate command parameters
@@ -259,7 +211,7 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka )
259211
case e_cmd_upd_product: return ERROR_INVALID_ARGUMENT;
260212
case e_cmd_add_price: return ERROR_INVALID_ARGUMENT;
261213
case e_cmd_add_publisher: return ERROR_INVALID_ARGUMENT;
262-
case e_cmd_del_publisher: return del_publisher( prm, ka );
214+
case e_cmd_del_publisher: return ERROR_INVALID_ARGUMENT;
263215
case e_cmd_init_price: return init_price( prm, ka );
264216
case e_cmd_init_test: return ERROR_INVALID_ARGUMENT;
265217
case e_cmd_upd_test: return ERROR_INVALID_ARGUMENT;

program/c/src/oracle/test_oracle.c

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -371,84 +371,3 @@ Test( oracle, upd_aggregate ) {
371371
cr_assert( px->prev_conf_ == prev_conf_ );
372372
cr_assert( px->prev_timestamp_ == prev_timestamp_ );
373373
}
374-
375-
Test( oracle, del_publisher ) {
376-
pc_price_info_t p1 = { .price_=100, .conf_=10,
377-
.status_ = PC_STATUS_TRADING, .pub_slot_ = 42 };
378-
pc_price_info_t p2 = { .price_=200, .conf_=20,
379-
.status_ = PC_STATUS_TRADING, .pub_slot_ = 42 };
380-
381-
// start with perfect inputs
382-
pc_pub_key_t p_id = { .k8_ = { 1, 2, 3, 4 } };
383-
pc_pub_key_t p_id2= { .k8_ = { 2, 3, 4, 5 } };
384-
pc_pub_key_t p_id3= { .k8_ = { 3, 4, 5, 6 } };
385-
cmd_add_publisher_t idata = {
386-
.ver_ = PC_VERSION,
387-
.cmd_ = e_cmd_del_publisher,
388-
.pub_ = p_id2
389-
};
390-
SolPubkey pkey = {.x = { 1, }};
391-
SolPubkey skey = {.x = { 3, }};
392-
uint64_t pqty = 100;
393-
pc_price_t sptr[1];
394-
sol_memset( sptr, 0, sizeof( pc_price_t ) );
395-
sptr->magic_ = PC_MAGIC;
396-
sptr->ver_ = PC_VERSION;
397-
sptr->ptype_ = PC_PTYPE_PRICE;
398-
sptr->type_ = PC_ACCTYPE_PRICE;
399-
sptr->num_ = 1;
400-
sptr->comp_[0].latest_ = p1;
401-
pc_pub_key_assign( &sptr->comp_[0].pub_, (pc_pub_key_t*)&p_id2 );
402-
403-
SolAccountInfo acc[] = {{
404-
.key = &pkey,
405-
.lamports = &pqty,
406-
.data_len = 0,
407-
.data = NULL,
408-
.owner = NULL,
409-
.rent_epoch = 0,
410-
.is_signer = true,
411-
.is_writable = true,
412-
.executable = false
413-
},{
414-
.key = &skey,
415-
.lamports = &PRICE_ACCOUNT_LAMPORTS,
416-
.data_len = sizeof( pc_price_t ),
417-
.data = (uint8_t*)sptr,
418-
.owner = (SolPubkey*)&p_id,
419-
.rent_epoch = 0,
420-
.is_signer = true,
421-
.is_writable = true,
422-
.executable = false
423-
} };
424-
SolParameters prm = {
425-
.ka = acc,
426-
.ka_num = 2,
427-
.data = (const uint8_t*)&idata,
428-
.data_len = sizeof( idata ),
429-
.program_id = (SolPubkey*)&p_id
430-
};
431-
cr_assert( SUCCESS == dispatch( &prm, acc ) );
432-
cr_assert( sptr->num_ == 0 );
433-
cr_assert( sptr->comp_[0].latest_.status_ == 0 );
434-
435-
sptr->num_ = 2;
436-
sptr->comp_[0].latest_ = p1;
437-
sptr->comp_[1].latest_ = p2;
438-
pc_pub_key_assign( &sptr->comp_[0].pub_, (pc_pub_key_t*)&p_id2 );
439-
pc_pub_key_assign( &sptr->comp_[1].pub_, (pc_pub_key_t*)&p_id3 );
440-
cr_assert( SUCCESS == dispatch( &prm, acc ) );
441-
cr_assert( sptr->num_ == 1 );
442-
cr_assert( sptr->comp_[0].latest_.price_ == p2.price_ );
443-
cr_assert( sptr->comp_[1].latest_.status_ == 0 );
444-
445-
sptr->num_ = 2;
446-
sptr->comp_[0].latest_ = p1;
447-
sptr->comp_[1].latest_ = p2;
448-
pc_pub_key_assign( &sptr->comp_[0].pub_, (pc_pub_key_t*)&p_id3 );
449-
pc_pub_key_assign( &sptr->comp_[1].pub_, (pc_pub_key_t*)&p_id2 );
450-
cr_assert( SUCCESS == dispatch( &prm, acc ) );
451-
cr_assert( sptr->num_ == 1 );
452-
cr_assert( sptr->comp_[0].latest_.price_ == p1.price_ );
453-
cr_assert( sptr->comp_[1].latest_.status_ == 0 );
454-
}

program/rust/src/c_oracle_header.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,6 @@ impl PythAccount for pc_price_t {
5252
const INITIAL_SIZE: u32 = PC_PRICE_T_COMP_OFFSET as u32;
5353
}
5454

55-
impl pc_pub_key_t {
56-
pub fn new_unique() -> pc_pub_key_t {
57-
let solana_unique = Pubkey::new_unique();
58-
pc_pub_key_t {
59-
k1_: solana_unique.to_bytes(),
60-
}
61-
}
62-
}
63-
64-
6555
#[cfg(target_endian = "little")]
6656
unsafe impl Zeroable for pc_acc {
6757
}
@@ -143,6 +133,13 @@ unsafe impl Pod for cmd_add_publisher_t {
143133
}
144134

145135
#[cfg(target_endian = "little")]
136+
unsafe impl Zeroable for cmd_del_publisher_t {
137+
}
138+
139+
#[cfg(target_endian = "little")]
140+
unsafe impl Pod for cmd_del_publisher_t {
141+
}
142+
146143
unsafe impl Zeroable for cmd_set_min_pub_t {
147144
}
148145

@@ -166,3 +163,12 @@ unsafe impl Zeroable for pc_price_comp_t {
166163
#[cfg(target_endian = "little")]
167164
unsafe impl Pod for pc_price_comp_t {
168165
}
166+
167+
impl pc_pub_key_t {
168+
pub fn new_unique() -> pc_pub_key_t {
169+
let solana_unique = Pubkey::new_unique();
170+
pc_pub_key_t {
171+
k1_: solana_unique.to_bytes(),
172+
}
173+
}
174+
}

program/rust/src/processor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::c_oracle_header::{
1010
command_t_e_cmd_add_product,
1111
command_t_e_cmd_add_publisher,
1212
command_t_e_cmd_agg_price,
13+
command_t_e_cmd_del_publisher,
1314
command_t_e_cmd_init_mapping,
1415
command_t_e_cmd_set_min_pub,
1516
command_t_e_cmd_upd_account_version,
@@ -28,6 +29,7 @@ use crate::rust_oracle::{
2829
add_price,
2930
add_product,
3031
add_publisher,
32+
del_publisher,
3133
init_mapping,
3234
set_min_pub,
3335
upd_product,
@@ -66,6 +68,7 @@ pub fn process_instruction(
6668
command_t_e_cmd_init_mapping => init_mapping(program_id, accounts, instruction_data),
6769
command_t_e_cmd_add_mapping => add_mapping(program_id, accounts, instruction_data),
6870
command_t_e_cmd_add_publisher => add_publisher(program_id, accounts, instruction_data),
71+
command_t_e_cmd_del_publisher => del_publisher(program_id, accounts, instruction_data),
6972
command_t_e_cmd_add_product => add_product(program_id, accounts, instruction_data),
7073
command_t_e_cmd_upd_product => upd_product(program_id, accounts, instruction_data),
7174
command_t_e_cmd_set_min_pub => set_min_pub(program_id, accounts, instruction_data),

program/rust/src/rust_oracle.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use solana_program::rent::Rent;
2222
use crate::c_oracle_header::{
2323
cmd_add_price_t,
2424
cmd_add_publisher_t,
25+
cmd_del_publisher_t,
2526
cmd_hdr_t,
2627
cmd_set_min_pub_t,
2728
cmd_upd_product_t,
@@ -221,6 +222,54 @@ pub fn add_publisher(
221222
+ price_data.num_ * try_convert::<_, u32>(size_of::<pc_price_comp>())?;
222223
Ok(SUCCESS)
223224
}
225+
226+
/// add a publisher to a price account
227+
/// accounts[0] funding account [signer writable]
228+
/// accounts[1] price account to delete the publisher from [signer writable]
229+
pub fn del_publisher(
230+
program_id: &Pubkey,
231+
accounts: &[AccountInfo],
232+
instruction_data: &[u8],
233+
) -> OracleResult {
234+
let cmd_args = load::<cmd_del_publisher_t>(instruction_data)?;
235+
236+
pyth_assert(
237+
instruction_data.len() == size_of::<cmd_del_publisher_t>()
238+
&& !pubkey_is_zero(&cmd_args.pub_),
239+
ProgramError::InvalidArgument,
240+
)?;
241+
242+
let [funding_account, price_account] = match accounts {
243+
[x, y] => Ok([x, y]),
244+
_ => Err(ProgramError::InvalidArgument),
245+
}?;
246+
247+
check_valid_funding_account(funding_account)?;
248+
check_valid_signable_account(program_id, price_account, size_of::<pc_price_t>())?;
249+
250+
let mut price_data = load_checked::<pc_price_t>(price_account, cmd_args.ver_)?;
251+
252+
for i in 0..(price_data.num_ as usize) {
253+
if pubkey_equal(&cmd_args.pub_, bytes_of(&price_data.comp_[i].pub_)) {
254+
for j in i + 1..(price_data.num_ as usize) {
255+
price_data.comp_[j - 1] = price_data.comp_[j];
256+
}
257+
price_data.num_ -= 1;
258+
let current_index: usize = try_convert(price_data.num_)?;
259+
sol_memset(
260+
bytes_of_mut(&mut price_data.comp_[current_index]),
261+
0,
262+
size_of::<pc_price_comp>(),
263+
);
264+
price_data.size_ =
265+
try_convert::<_, u32>(size_of::<pc_price_t>() - size_of_val(&price_data.comp_))?
266+
+ price_data.num_ * try_convert::<_, u32>(size_of::<pc_price_comp>())?;
267+
return Ok(SUCCESS);
268+
}
269+
}
270+
Err(ProgramError::InvalidArgument)
271+
}
272+
224273
pub fn add_product(
225274
program_id: &Pubkey,
226275
accounts: &[AccountInfo],

program/rust/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod test_add_mapping;
22
mod test_add_price;
33
mod test_add_product;
44
mod test_add_publisher;
5+
mod test_del_publisher;
56
mod test_init_mapping;
67
mod test_set_min_pub;
78
mod test_upd_product;

0 commit comments

Comments
 (0)