Skip to content

Commit

Permalink
Add rent exemption check (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
tompntn authored Apr 14, 2022
1 parent f6c572f commit 8b0baf5
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 15 deletions.
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

0 comments on commit 8b0baf5

Please sign in to comment.