Skip to content

Commit b6bfd16

Browse files
committed
Add cmd_upd_price_no_fail_on_error
1 parent 5a518f3 commit b6bfd16

File tree

3 files changed

+126
-16
lines changed

3 files changed

+126
-16
lines changed

program/src/oracle/oracle.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ static bool is_valid_price_upd( cmd_upd_price_t *cptr, SolAccountInfo *price_acc
509509

510510
// Reject if this price corresponds to the same or earlier time
511511
pc_price_info_t *fptr = &pptr->comp_[comp_idx].latest_;
512-
if ( ( cptr->cmd_ == e_cmd_upd_price || cptr->cmd_ == e_cmd_batch_upd_price ) &&
512+
if ( ( cptr->cmd_ == e_cmd_upd_price || cptr->cmd_ == e_cmd_batch_upd_price || cptr->cmd_ == e_cmd_upd_price_no_fail_on_error ) &&
513513
cptr->pub_slot_ <= fptr->pub_slot_ ) {
514514
return false;
515515
}
@@ -527,7 +527,7 @@ static void do_price_upd( cmd_upd_price_t *cptr, SolAccountInfo *clock_account,
527527

528528
// update component price if required
529529
pc_price_info_t *fptr = &pptr->comp_[comp_idx].latest_;
530-
if ( ( cptr->cmd_ == e_cmd_upd_price || cptr->cmd_ == e_cmd_batch_upd_price ) ) {
530+
if ( ( cptr->cmd_ == e_cmd_upd_price || cptr->cmd_ == e_cmd_batch_upd_price || cptr->cmd_ == e_cmd_upd_price_no_fail_on_error ) ) {
531531
fptr->price_ = cptr->price_;
532532
fptr->conf_ = cptr->conf_;
533533
fptr->status_ = cptr->status_;
@@ -630,6 +630,12 @@ static uint64_t upd_price( SolParameters *prm, SolAccountInfo *ka )
630630
return SUCCESS;
631631
}
632632

633+
static uint64_t upd_price_no_fail_on_error( SolParameters *prm, SolAccountInfo *ka )
634+
{
635+
upd_price( prm, ka );
636+
return SUCCESS;
637+
}
638+
633639
static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka )
634640
{
635641
if (prm->data_len < sizeof(cmd_hdr_t) ) {
@@ -641,20 +647,21 @@ static uint64_t dispatch( SolParameters *prm, SolAccountInfo *ka )
641647
}
642648
switch(hdr->cmd_) {
643649
case e_cmd_upd_price:
644-
case e_cmd_agg_price: return upd_price( prm, ka );
645-
case e_cmd_batch_upd_price: return batch_upd_price( prm, ka );
646-
case e_cmd_init_mapping: return init_mapping( prm, ka );
647-
case e_cmd_add_mapping: return add_mapping( prm, ka );
648-
case e_cmd_add_product: return add_product( prm, ka );
649-
case e_cmd_upd_product: return upd_product( prm, ka );
650-
case e_cmd_add_price: return add_price( prm, ka );
651-
case e_cmd_add_publisher: return add_publisher( prm, ka );
652-
case e_cmd_del_publisher: return del_publisher( prm, ka );
653-
case e_cmd_init_price: return init_price( prm, ka );
654-
case e_cmd_init_test: return init_test( prm, ka );
655-
case e_cmd_upd_test: return upd_test( prm, ka );
656-
case e_cmd_set_min_pub: return set_min_pub( prm, ka );
657-
default: return ERROR_INVALID_ARGUMENT;
650+
case e_cmd_agg_price: return upd_price( prm, ka );
651+
case e_cmd_upd_price_no_fail_on_error: return upd_price_no_fail_on_error( prm, ka );
652+
case e_cmd_batch_upd_price: return batch_upd_price( prm, ka );
653+
case e_cmd_init_mapping: return init_mapping( prm, ka );
654+
case e_cmd_add_mapping: return add_mapping( prm, ka );
655+
case e_cmd_add_product: return add_product( prm, ka );
656+
case e_cmd_upd_product: return upd_product( prm, ka );
657+
case e_cmd_add_price: return add_price( prm, ka );
658+
case e_cmd_add_publisher: return add_publisher( prm, ka );
659+
case e_cmd_del_publisher: return del_publisher( prm, ka );
660+
case e_cmd_init_price: return init_price( prm, ka );
661+
case e_cmd_init_test: return init_test( prm, ka );
662+
case e_cmd_upd_test: return upd_test( prm, ka );
663+
case e_cmd_set_min_pub: return set_min_pub( prm, ka );
664+
default: return ERROR_INVALID_ARGUMENT;
658665
}
659666
}
660667

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
// publish a batch of component prices
225231
// key[0] funding account [signer writable]
226232
// key[1] sysvar_clock account [readable]

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 affect. 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 affect.
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 affect.
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, batch_upd_price ) {
452549

453550
// In this test we submit a batch update containing two price updates for different

0 commit comments

Comments
 (0)