Skip to content

Commit 0c7fb9e

Browse files
committed
Add cmd_upd_price_no_fail_on_error
1 parent 94386d1 commit 0c7fb9e

File tree

3 files changed

+125
-15
lines changed

3 files changed

+125
-15
lines changed

program/src/oracle/oracle.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ static uint64_t upd_price( SolParameters *prm, SolAccountInfo *ka )
520520
// reject if this price corresponds to the same or earlier time
521521
pc_price_info_t *fptr = &pptr->comp_[i].latest_;
522522
sysvar_clock_t *sptr = (sysvar_clock_t*)ka[clock_idx].data;
523-
if ( cptr->cmd_ == e_cmd_upd_price &&
523+
if ( ( cptr->cmd_ == e_cmd_upd_price || cptr->cmd_ == e_cmd_upd_price_no_fail_on_error ) &&
524524
cptr->pub_slot_ <= fptr->pub_slot_ ) {
525525
return ERROR_INVALID_ARGUMENT;
526526
}
@@ -531,7 +531,7 @@ static uint64_t upd_price( SolParameters *prm, SolAccountInfo *ka )
531531
}
532532

533533
// update component price if required
534-
if ( cptr->cmd_ == e_cmd_upd_price ) {
534+
if ( cptr->cmd_ == e_cmd_upd_price || cptr->cmd_ == e_cmd_upd_price_no_fail_on_error ) {
535535
fptr->price_ = cptr->price_;
536536
fptr->conf_ = cptr->conf_;
537537
fptr->status_ = cptr->status_;
@@ -540,6 +540,12 @@ static uint64_t upd_price( SolParameters *prm, SolAccountInfo *ka )
540540
return SUCCESS;
541541
}
542542

543+
static uint64_t upd_price_no_fail_on_error( SolParameters *prm, SolAccountInfo *ka )
544+
{
545+
upd_price( prm, ka );
546+
return SUCCESS;
547+
}
548+
543549
static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka )
544550
{
545551
if (prm->data_len < sizeof(cmd_hdr_t) ) {
@@ -551,19 +557,20 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka )
551557
}
552558
switch(hdr->cmd_) {
553559
case e_cmd_upd_price:
554-
case e_cmd_agg_price: return upd_price( prm, ka );
555-
case e_cmd_init_mapping: return init_mapping( prm, ka );
556-
case e_cmd_add_mapping: return add_mapping( prm, ka );
557-
case e_cmd_add_product: return add_product( prm, ka );
558-
case e_cmd_upd_product: return upd_product( prm, ka );
559-
case e_cmd_add_price: return add_price( prm, ka );
560-
case e_cmd_add_publisher: return add_publisher( prm, ka );
561-
case e_cmd_del_publisher: return del_publisher( prm, ka );
562-
case e_cmd_init_price: return init_price( prm, ka );
563-
case e_cmd_init_test: return init_test( prm, ka );
564-
case e_cmd_upd_test: return upd_test( prm, ka );
565-
case e_cmd_set_min_pub: return set_min_pub( prm, ka );
566-
default: return ERROR_INVALID_ARGUMENT;
560+
case e_cmd_agg_price: return upd_price( prm, ka );
561+
case e_cmd_upd_price_no_fail_on_error: return upd_price_no_fail_on_error( prm, ka );
562+
case e_cmd_init_mapping: return init_mapping( prm, ka );
563+
case e_cmd_add_mapping: return add_mapping( prm, ka );
564+
case e_cmd_add_product: return add_product( prm, ka );
565+
case e_cmd_upd_product: return upd_product( prm, ka );
566+
case e_cmd_add_price: return add_price( prm, ka );
567+
case e_cmd_add_publisher: return add_publisher( prm, ka );
568+
case e_cmd_del_publisher: return del_publisher( prm, ka );
569+
case e_cmd_init_price: return init_price( prm, ka );
570+
case e_cmd_init_test: return init_test( prm, ka );
571+
case e_cmd_upd_test: return upd_test( prm, ka );
572+
case e_cmd_set_min_pub: return set_min_pub( prm, ka );
573+
default: return ERROR_INVALID_ARGUMENT;
567574
}
568575
}
569576

program/src/oracle/oracle.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ typedef enum {
221221
// key[2] sysvar_clock account [readable]
222222
e_cmd_upd_price,
223223

224+
// publish component price, never returning an error even if the update failed
225+
// key[0] funding account [signer writable]
226+
// key[1] price account [writable]
227+
// key[2] sysvar_clock account [readable]
228+
e_cmd_upd_price_no_fail_on_error,
229+
224230
// compute aggregate price
225231
// key[0] funding account [signer writable]
226232
// key[1] price account [writable]

program/src/oracle/test_oracle.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,103 @@ Test( oracle, upd_price ) {
448448
cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) );
449449
}
450450

451+
Test( oracle, upd_price_no_fail_on_error ) {
452+
cmd_upd_price_t idata = {
453+
.ver_ = PC_VERSION,
454+
.cmd_ = e_cmd_upd_price_no_fail_on_error,
455+
.status_ = PC_STATUS_TRADING,
456+
.price_ = 42L,
457+
.conf_ = 9L,
458+
.pub_slot_ = 1
459+
};
460+
SolPubkey p_id = {.x = { 0xff, }};
461+
SolPubkey pkey = {.x = { 1, }};
462+
SolPubkey skey = {.x = { 3, }};
463+
sysvar_clock_t cvar = {
464+
.slot_ = 1
465+
};
466+
uint64_t pqty = 100, sqty = 200;
467+
pc_price_t sptr[1];
468+
sol_memset( sptr, 0, sizeof( pc_price_t ) );
469+
sptr->magic_ = PC_MAGIC;
470+
sptr->ver_ = PC_VERSION;
471+
sptr->ptype_ = PC_PTYPE_PRICE;
472+
sptr->type_ = PC_ACCTYPE_PRICE;
473+
sptr->num_ = 1;
474+
475+
SolAccountInfo acc[] = {{
476+
.key = &pkey,
477+
.lamports = &pqty,
478+
.data_len = 0,
479+
.data = NULL,
480+
.owner = NULL,
481+
.rent_epoch = 0,
482+
.is_signer = true,
483+
.is_writable = true,
484+
.executable = false
485+
},{
486+
.key = &skey,
487+
.lamports = &sqty,
488+
.data_len = sizeof( pc_price_t ),
489+
.data = (uint8_t*)sptr,
490+
.owner = &p_id,
491+
.rent_epoch = 0,
492+
.is_signer = false,
493+
.is_writable = true,
494+
.executable = false
495+
},{
496+
.key = (SolPubkey*)sysvar_clock,
497+
.lamports = &sqty,
498+
.data_len = sizeof( sysvar_clock_t ),
499+
.data = (uint8_t*)&cvar,
500+
.owner = &p_id,
501+
.rent_epoch = 0,
502+
.is_signer = false,
503+
.is_writable = false,
504+
.executable = false
505+
}};
506+
SolParameters prm = {
507+
.ka = acc,
508+
.ka_num = 3,
509+
.data = (const uint8_t*)&idata,
510+
.data_len = sizeof( idata ),
511+
.program_id = &p_id
512+
};
513+
514+
// We haven't permissioned the publish account for the price account
515+
// yet, so any update should fail silently and have no effect. The
516+
// transaction should "succeed".
517+
cr_assert( SUCCESS == dispatch( &prm, acc ) );
518+
cr_assert( sptr->comp_[0].latest_.price_ == 0L );
519+
cr_assert( sptr->comp_[0].latest_.conf_ == 0L );
520+
cr_assert( sptr->comp_[0].latest_.pub_slot_ == 0 );
521+
cr_assert( sptr->agg_.pub_slot_ == 0 );
522+
cr_assert( sptr->valid_slot_ == 0 );
523+
524+
// Now permission the publish account for the price account.
525+
pc_pub_key_assign( &sptr->comp_[0].pub_, (pc_pub_key_t*)&pkey );
526+
527+
// The update should now succeed, and have an effect.
528+
cr_assert( SUCCESS == dispatch( &prm, acc ) );
529+
cr_assert( sptr->comp_[0].latest_.price_ == 42L );
530+
cr_assert( sptr->comp_[0].latest_.conf_ == 9L );
531+
cr_assert( sptr->comp_[0].latest_.pub_slot_ == 1 );
532+
cr_assert( sptr->agg_.pub_slot_ == 1 );
533+
cr_assert( sptr->valid_slot_ == 0 );
534+
535+
// Invalid updates, such as publishing an update for the current slot,
536+
// should still fail silently and have no effect.
537+
idata.price_ = 55L;
538+
idata.conf_ = 22L;
539+
idata.pub_slot_ = 1;
540+
cr_assert( SUCCESS == dispatch( &prm, acc ) );
541+
cr_assert( sptr->comp_[0].latest_.price_ == 42L );
542+
cr_assert( sptr->comp_[0].latest_.conf_ == 9L );
543+
cr_assert( sptr->comp_[0].latest_.pub_slot_ == 1 );
544+
cr_assert( sptr->agg_.pub_slot_ == 1 );
545+
cr_assert( sptr->valid_slot_ == 0 );
546+
}
547+
451548
Test( oracle, upd_aggregate ) {
452549
pc_price_t px[1];
453550
sol_memset( px, 0, sizeof( pc_price_t ) );

0 commit comments

Comments
 (0)