Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 2 additions & 98 deletions program/c/src/oracle/oracle.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,55 +59,6 @@ static bool valid_writable_account( SolParameters *prm,
is_rent_exempt( *ka->lamports, ka->data_len );
}

static uint64_t add_price( SolParameters *prm, SolAccountInfo *ka )
{
// Validate command parameters
cmd_add_price_t *cptr = (cmd_add_price_t*)prm->data;
if ( prm->data_len != sizeof( cmd_add_price_t ) ||
cptr->expo_ > PC_MAX_NUM_DECIMALS ||
cptr->expo_ < -PC_MAX_NUM_DECIMALS ||
cptr->ptype_ == PC_PTYPE_UNKNOWN ) {
return ERROR_INVALID_ARGUMENT;
}

// Account (1) is the product account that we're going to add to
// Account (2) is the new price account
// Verify that these are signed, writable accounts with correct ownership
// and size
if ( prm->ka_num != 3 ||
!valid_funding_account( &ka[0] ) ||
!valid_signable_account( prm, &ka[1], PC_PROD_ACC_SIZE ) ||
!valid_signable_account( prm, &ka[2], sizeof( pc_price_t ) ) ) {
return ERROR_INVALID_ARGUMENT;
}

// Verify that the product account is valid
// and that the new price account is uninitialized
pc_prod_t *pptr = (pc_prod_t*)ka[1].data;
pc_price_t *sptr = (pc_price_t*)ka[2].data;
if ( pptr->magic_ != PC_MAGIC ||
pptr->ver_ != cptr->ver_ ||
pptr->type_ != PC_ACCTYPE_PRODUCT ||
sptr->magic_ != 0 ) {
return ERROR_INVALID_ARGUMENT;
}

// Initialize symbol account
sol_memset( sptr, 0, sizeof( pc_price_t ) );
sptr->magic_ = PC_MAGIC;
sptr->ver_ = cptr->ver_;
sptr->type_ = PC_ACCTYPE_PRICE;
sptr->size_ = sizeof( pc_price_t ) - sizeof( sptr->comp_ );
sptr->expo_ = cptr->expo_;
sptr->ptype_ = cptr->ptype_;
pc_pub_key_assign( &sptr->prod_, (pc_pub_key_t*)ka[1].key );

// bind price account to product account
pc_pub_key_assign( &sptr->next_, &pptr->px_acc_ );
pc_pub_key_assign( &pptr->px_acc_, (pc_pub_key_t*)ka[2].key );
return SUCCESS;
}

static uint64_t init_price( SolParameters *prm, SolAccountInfo *ka )
{
// Validate command parameters
Expand Down Expand Up @@ -156,53 +107,6 @@ static uint64_t init_price( SolParameters *prm, SolAccountInfo *ka )
return SUCCESS;
}

static uint64_t add_publisher( SolParameters *prm, SolAccountInfo *ka )
{
// Validate command parameters
cmd_add_publisher_t *cptr = (cmd_add_publisher_t*)prm->data;
if ( prm->data_len != sizeof( cmd_add_publisher_t ) ||
pc_pub_key_is_zero( &cptr->pub_ ) ) {
return ERROR_INVALID_ARGUMENT;
}

// Account (1) is the price account
// Verify that this is signed, writable with correct ownership
// and size
if ( prm->ka_num != 2 ||
!valid_funding_account( &ka[0] ) ||
!valid_signable_account( prm, &ka[1], sizeof( pc_price_t ) ) ) {
return ERROR_INVALID_ARGUMENT;
}

// Verify that symbol account is initialized and corresponds to the
// same symbol and price-type in the instruction parameters
pc_price_t *sptr = (pc_price_t*)ka[1].data;
if ( sptr->magic_ != PC_MAGIC ||
sptr->ver_ != cptr->ver_ ||
sptr->type_ != PC_ACCTYPE_PRICE ) {
return ERROR_INVALID_ARGUMENT;
}

// try to add publisher
for(uint32_t i=0; i != sptr->num_; ++i ) {
pc_price_comp_t *iptr = &sptr->comp_[i];
if ( pc_pub_key_equal( &iptr->pub_, &cptr->pub_ ) ) {
return ERROR_INVALID_ARGUMENT;
}
}
if ( sptr->num_ >= PC_COMP_SIZE ) {
return ERROR_INVALID_ARGUMENT;
}
pc_price_comp_t *iptr = &sptr->comp_[sptr->num_++];
sol_memset( iptr, 0, sizeof( pc_price_comp_t ) );
pc_pub_key_assign( &iptr->pub_, &cptr->pub_ );

// update size of account
sptr->size_ = sizeof( pc_price_t ) - sizeof( sptr->comp_ ) +
sptr->num_ * sizeof( pc_price_comp_t );
return SUCCESS;
}

// remove publisher from price node
static uint64_t del_publisher( SolParameters *prm, SolAccountInfo *ka )
{
Expand Down Expand Up @@ -353,8 +257,8 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka )
case e_cmd_add_mapping: return ERROR_INVALID_ARGUMENT;
case e_cmd_add_product: return ERROR_INVALID_ARGUMENT;
case e_cmd_upd_product: return ERROR_INVALID_ARGUMENT;
case e_cmd_add_price: return add_price( prm, ka );
case e_cmd_add_publisher: return add_publisher( prm, ka );
case e_cmd_add_price: return ERROR_INVALID_ARGUMENT;
case e_cmd_add_publisher: return ERROR_INVALID_ARGUMENT;
case e_cmd_del_publisher: return del_publisher( prm, ka );
case e_cmd_init_price: return init_price( prm, ka );
case e_cmd_init_test: return ERROR_INVALID_ARGUMENT;
Expand Down
82 changes: 0 additions & 82 deletions program/c/src/oracle/test_oracle.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,88 +7,6 @@ uint64_t MAPPING_ACCOUNT_LAMPORTS = 143821440;
uint64_t PRODUCT_ACCOUNT_LAMPORTS = 4454400;
uint64_t PRICE_ACCOUNT_LAMPORTS = 23942400;

Test( oracle, add_publisher ) {
// start with perfect inputs
cmd_add_publisher_t idata = {
.ver_ = PC_VERSION,
.cmd_ = e_cmd_add_publisher,
.pub_ = { .k8_ = { 3UL, 4UL, 5UL, 6UL } }
};
SolPubkey p_id = {.x = { 0xff, }};
SolPubkey pkey = {.x = { 1, }};
SolPubkey skey = {.x = { 3, }};
uint64_t pqty = 100;
pc_price_t sptr[1];
sol_memset( sptr, 0, sizeof( pc_price_t ) );
sptr->magic_ = PC_MAGIC;
sptr->ver_ = PC_VERSION;
sptr->type_ = PC_ACCTYPE_PRICE;
sptr->ptype_ = PC_PTYPE_PRICE;
SolAccountInfo acc[] = {{
.key = &pkey,
.lamports = &pqty,
.data_len = 0,
.data = NULL,
.owner = NULL,
.rent_epoch = 0,
.is_signer = true,
.is_writable = true,
.executable = false
},{
.key = &skey,
.lamports = &pqty,
.data_len = sizeof( pc_price_t ),
.data = (uint8_t*)sptr,
.owner = &p_id,
.rent_epoch = 0,
.is_signer = true,
.is_writable = true,
.executable = false
} };
SolParameters prm = {
.ka = acc,
.ka_num = 2,
.data = (const uint8_t*)&idata,
.data_len = sizeof( idata ),
.program_id = &p_id
};

// Expect the instruction to fail, because the price account isn't rent exempt
cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) );

// Now give the price account enough lamports to be rent exempt
acc[1].lamports = &PRICE_ACCOUNT_LAMPORTS;

cr_assert( SUCCESS == dispatch( &prm, acc ) );
cr_assert( sptr->num_ == 1 );
cr_assert( pc_pub_key_equal( &idata.pub_, &sptr->comp_[0].pub_ ) );
// cant add twice
cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) );

// invalid params
sol_memset( sptr, 0, sizeof( pc_price_t ) );
sptr->magic_ = PC_MAGIC;
sptr->ver_ = PC_VERSION;
sptr->type_ = PC_ACCTYPE_PRICE;
// bad price account
sptr->magic_ = 0;
cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) );
sptr->magic_ = PC_MAGIC;

// fill up price node
for( unsigned i = 0;; ++i ) {
idata.pub_.k8_[0] = 10 + i;
uint64_t rc = dispatch( &prm, acc );
if ( rc != SUCCESS ) {
cr_assert( i == ( unsigned )(PC_COMP_SIZE) );
break;
}
cr_assert( sptr->num_ == i + 1 );
cr_assert( pc_pub_key_equal( &idata.pub_, &sptr->comp_[i].pub_ ) );
cr_assert( rc == SUCCESS );
}
}

Test(oracle, pc_size ) {
cr_assert( sizeof( pc_pub_key_t ) == 32 );
cr_assert( sizeof( pc_map_table_t ) ==
Expand Down
10 changes: 10 additions & 0 deletions program/rust/src/c_oracle_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use bytemuck::{
Pod,
Zeroable,
};
use solana_program::pubkey::Pubkey;
use std::mem::size_of;
//bindings.rs is generated by build.rs to include
//things defined in bindings.h
Expand Down Expand Up @@ -51,6 +52,15 @@ impl PythAccount for pc_price_t {
const INITIAL_SIZE: u32 = PC_PRICE_T_COMP_OFFSET as u32;
}

impl pc_pub_key_t {
pub fn new_unique() -> pc_pub_key_t {
let solana_unique = Pubkey::new_unique();
pc_pub_key_t {
k1_: solana_unique.to_bytes(),
}
}
}


#[cfg(target_endian = "little")]
unsafe impl Zeroable for pc_acc {
Expand Down
2 changes: 2 additions & 0 deletions program/rust/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod test_add_mapping;
mod test_add_price;
mod test_add_product;
mod test_add_publisher;
mod test_init_mapping;
mod test_set_min_pub;
mod test_upd_product;
Expand Down
Loading