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
30 changes: 28 additions & 2 deletions program/src/oracle/oracle.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@
#include "oracle.h"
#include "upd_aggregate.h"

// Returns the minimum number of lamports required to make an account
// with dlen bytes of data rent exempt. These values were calculated
// using the getMinimumBalanceForRentExemption RPC call, and are
// guaranteed never to increase.
static uint64_t rent_exempt_amount( uint64_t dlen )
{
switch ( dlen )
{
case sizeof( pc_map_table_t ):
return 143821440;
case PC_PROD_ACC_SIZE:
return 4454400;
case sizeof( pc_price_t ):
return 23942400;
default:
return UINT64_MAX;
}
}

static bool is_rent_exempt( uint64_t lamports, uint64_t dlen )
{
return lamports >= rent_exempt_amount( dlen );
}

static bool valid_funding_account( SolAccountInfo *ka )
{
return ka->is_signer &&
Expand All @@ -18,7 +42,8 @@ static bool valid_signable_account( SolParameters *prm,
return ka->is_signer &&
ka->is_writable &&
SolPubkey_same( ka->owner, prm->program_id ) &&
ka->data_len >= dlen;
ka->data_len >= dlen &&
is_rent_exempt( *ka->lamports, dlen );
}

static bool valid_writable_account( SolParameters *prm,
Expand All @@ -27,7 +52,8 @@ static bool valid_writable_account( SolParameters *prm,
{
return ka->is_writable &&
SolPubkey_same( ka->owner, prm->program_id ) &&
ka->data_len >= dlen;
ka->data_len >= dlen &&
is_rent_exempt( *ka->lamports, dlen );
}

static uint64_t init_mapping( SolParameters *prm, SolAccountInfo *ka )
Expand Down
37 changes: 24 additions & 13 deletions program/src/oracle/test_oracle.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ char heap_start[8192];
#include "sort.c"
#include <criterion/criterion.h>

uint64_t MAPPING_ACCOUNT_LAMPORTS = 143821440;
uint64_t PRODUCT_ACCOUNT_LAMPORTS = 4454400;
uint64_t PRICE_ACCOUNT_LAMPORTS = 23942400;

Test(oracle, init_mapping) {

// start with perfect inputs
Expand All @@ -30,7 +34,7 @@ Test(oracle, init_mapping) {
.executable = false
},{
.key = &mkey,
.lamports = &pqty,
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_map_table_t ),
.data = (uint8_t*)mptr,
.owner = &p_id,
Expand Down Expand Up @@ -96,7 +100,7 @@ Test(oracle, add_mapping ) {
SolPubkey pkey = {.x = { 1, }};
SolPubkey tkey = {.x = { 2, }};
SolPubkey mkey = {.x = { 3, }};
uint64_t pqty = 100, tqty = 100;
uint64_t pqty = 100;
pc_map_table_t mptr[1];
sol_memset( mptr, 0, sizeof( pc_map_table_t ) );
SolAccountInfo acc[] = {{
Expand All @@ -111,7 +115,7 @@ Test(oracle, add_mapping ) {
.executable = false
},{
.key = &tkey,
.lamports = &pqty,
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_map_table_t ),
.data = (uint8_t*)tptr,
.owner = &p_id,
Expand All @@ -121,7 +125,7 @@ Test(oracle, add_mapping ) {
.executable = false
},{
.key = &mkey,
.lamports = &tqty,
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_map_table_t ),
.data = (uint8_t*)mptr,
.owner = &p_id,
Expand Down Expand Up @@ -186,7 +190,7 @@ Test(oracle, add_product) {
.executable = false
},{
.key = &mkey,
.lamports = &pqty,
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_map_table_t ),
.data = (uint8_t*)mptr,
.owner = &p_id,
Expand All @@ -196,7 +200,7 @@ Test(oracle, add_product) {
.executable = false
},{
.key = &skey,
.lamports = &pqty,
.lamports = &PRODUCT_ACCOUNT_LAMPORTS,
.data_len = PC_PROD_ACC_SIZE,
.data = (uint8_t*)sptr,
.owner = &p_id,
Expand Down Expand Up @@ -259,7 +263,7 @@ Test( oracle, add_publisher ) {
SolPubkey p_id = {.x = { 0xff, }};
SolPubkey pkey = {.x = { 1, }};
SolPubkey skey = {.x = { 3, }};
uint64_t pqty = 100, sqty = 200;
uint64_t pqty = 100;
pc_price_t sptr[1];
sol_memset( sptr, 0, sizeof( pc_price_t ) );
sptr->magic_ = PC_MAGIC;
Expand All @@ -278,7 +282,7 @@ Test( oracle, add_publisher ) {
.executable = false
},{
.key = &skey,
.lamports = &sqty,
.lamports = &pqty,
.data_len = sizeof( pc_price_t ),
.data = (uint8_t*)sptr,
.owner = &p_id,
Expand All @@ -294,6 +298,13 @@ Test( oracle, add_publisher ) {
.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_ ) );
Expand Down Expand Up @@ -358,7 +369,7 @@ Test( oracle, upd_test ) {
.executable = false
},{
.key = &mkey,
.lamports = &pqty,
.lamports = &PRICE_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_price_t ),
.data = (uint8_t*)mptr,
.owner = &p_id,
Expand Down Expand Up @@ -436,7 +447,7 @@ Test( oracle, upd_price ) {
.executable = false
},{
.key = &skey,
.lamports = &sqty,
.lamports = &PRICE_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_price_t ),
.data = (uint8_t*)sptr,
.owner = &p_id,
Expand Down Expand Up @@ -547,7 +558,7 @@ Test( oracle, upd_price_no_fail_on_error ) {
.executable = false
},{
.key = &skey,
.lamports = &sqty,
.lamports = &PRICE_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_price_t ),
.data = (uint8_t*)sptr,
.owner = &p_id,
Expand Down Expand Up @@ -745,7 +756,7 @@ Test( oracle, del_publisher ) {
};
SolPubkey pkey = {.x = { 1, }};
SolPubkey skey = {.x = { 3, }};
uint64_t pqty = 100, sqty = 200;
uint64_t pqty = 100;
pc_price_t sptr[1];
sol_memset( sptr, 0, sizeof( pc_price_t ) );
sptr->magic_ = PC_MAGIC;
Expand All @@ -768,7 +779,7 @@ Test( oracle, del_publisher ) {
.executable = false
},{
.key = &skey,
.lamports = &sqty,
.lamports = &PRICE_ACCOUNT_LAMPORTS,
.data_len = sizeof( pc_price_t ),
.data = (uint8_t*)sptr,
.owner = (SolPubkey*)&p_id,
Expand Down