Skip to content

Commit 8b0baf5

Browse files
authored
Add rent exemption check (#155)
1 parent f6c572f commit 8b0baf5

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

program/src/oracle/oracle.c

+28-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@
55
#include "oracle.h"
66
#include "upd_aggregate.h"
77

8+
// Returns the minimum number of lamports required to make an account
9+
// with dlen bytes of data rent exempt. These values were calculated
10+
// using the getMinimumBalanceForRentExemption RPC call, and are
11+
// guaranteed never to increase.
12+
static uint64_t rent_exempt_amount( uint64_t dlen )
13+
{
14+
switch ( dlen )
15+
{
16+
case sizeof( pc_map_table_t ):
17+
return 143821440;
18+
case PC_PROD_ACC_SIZE:
19+
return 4454400;
20+
case sizeof( pc_price_t ):
21+
return 23942400;
22+
default:
23+
return UINT64_MAX;
24+
}
25+
}
26+
27+
static bool is_rent_exempt( uint64_t lamports, uint64_t dlen )
28+
{
29+
return lamports >= rent_exempt_amount( dlen );
30+
}
31+
832
static bool valid_funding_account( SolAccountInfo *ka )
933
{
1034
return ka->is_signer &&
@@ -18,7 +42,8 @@ static bool valid_signable_account( SolParameters *prm,
1842
return ka->is_signer &&
1943
ka->is_writable &&
2044
SolPubkey_same( ka->owner, prm->program_id ) &&
21-
ka->data_len >= dlen;
45+
ka->data_len >= dlen &&
46+
is_rent_exempt( *ka->lamports, dlen );
2247
}
2348

2449
static bool valid_writable_account( SolParameters *prm,
@@ -27,7 +52,8 @@ static bool valid_writable_account( SolParameters *prm,
2752
{
2853
return ka->is_writable &&
2954
SolPubkey_same( ka->owner, prm->program_id ) &&
30-
ka->data_len >= dlen;
55+
ka->data_len >= dlen &&
56+
is_rent_exempt( *ka->lamports, dlen );
3157
}
3258

3359
static uint64_t init_mapping( SolParameters *prm, SolAccountInfo *ka )

program/src/oracle/test_oracle.c

+24-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ char heap_start[8192];
44
#include "sort.c"
55
#include <criterion/criterion.h>
66

7+
uint64_t MAPPING_ACCOUNT_LAMPORTS = 143821440;
8+
uint64_t PRODUCT_ACCOUNT_LAMPORTS = 4454400;
9+
uint64_t PRICE_ACCOUNT_LAMPORTS = 23942400;
10+
711
Test(oracle, init_mapping) {
812

913
// start with perfect inputs
@@ -30,7 +34,7 @@ Test(oracle, init_mapping) {
3034
.executable = false
3135
},{
3236
.key = &mkey,
33-
.lamports = &pqty,
37+
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
3438
.data_len = sizeof( pc_map_table_t ),
3539
.data = (uint8_t*)mptr,
3640
.owner = &p_id,
@@ -96,7 +100,7 @@ Test(oracle, add_mapping ) {
96100
SolPubkey pkey = {.x = { 1, }};
97101
SolPubkey tkey = {.x = { 2, }};
98102
SolPubkey mkey = {.x = { 3, }};
99-
uint64_t pqty = 100, tqty = 100;
103+
uint64_t pqty = 100;
100104
pc_map_table_t mptr[1];
101105
sol_memset( mptr, 0, sizeof( pc_map_table_t ) );
102106
SolAccountInfo acc[] = {{
@@ -111,7 +115,7 @@ Test(oracle, add_mapping ) {
111115
.executable = false
112116
},{
113117
.key = &tkey,
114-
.lamports = &pqty,
118+
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
115119
.data_len = sizeof( pc_map_table_t ),
116120
.data = (uint8_t*)tptr,
117121
.owner = &p_id,
@@ -121,7 +125,7 @@ Test(oracle, add_mapping ) {
121125
.executable = false
122126
},{
123127
.key = &mkey,
124-
.lamports = &tqty,
128+
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
125129
.data_len = sizeof( pc_map_table_t ),
126130
.data = (uint8_t*)mptr,
127131
.owner = &p_id,
@@ -186,7 +190,7 @@ Test(oracle, add_product) {
186190
.executable = false
187191
},{
188192
.key = &mkey,
189-
.lamports = &pqty,
193+
.lamports = &MAPPING_ACCOUNT_LAMPORTS,
190194
.data_len = sizeof( pc_map_table_t ),
191195
.data = (uint8_t*)mptr,
192196
.owner = &p_id,
@@ -196,7 +200,7 @@ Test(oracle, add_product) {
196200
.executable = false
197201
},{
198202
.key = &skey,
199-
.lamports = &pqty,
203+
.lamports = &PRODUCT_ACCOUNT_LAMPORTS,
200204
.data_len = PC_PROD_ACC_SIZE,
201205
.data = (uint8_t*)sptr,
202206
.owner = &p_id,
@@ -259,7 +263,7 @@ Test( oracle, add_publisher ) {
259263
SolPubkey p_id = {.x = { 0xff, }};
260264
SolPubkey pkey = {.x = { 1, }};
261265
SolPubkey skey = {.x = { 3, }};
262-
uint64_t pqty = 100, sqty = 200;
266+
uint64_t pqty = 100;
263267
pc_price_t sptr[1];
264268
sol_memset( sptr, 0, sizeof( pc_price_t ) );
265269
sptr->magic_ = PC_MAGIC;
@@ -278,7 +282,7 @@ Test( oracle, add_publisher ) {
278282
.executable = false
279283
},{
280284
.key = &skey,
281-
.lamports = &sqty,
285+
.lamports = &pqty,
282286
.data_len = sizeof( pc_price_t ),
283287
.data = (uint8_t*)sptr,
284288
.owner = &p_id,
@@ -294,6 +298,13 @@ Test( oracle, add_publisher ) {
294298
.data_len = sizeof( idata ),
295299
.program_id = &p_id
296300
};
301+
302+
// Expect the instruction to fail, because the price account isn't rent exempt
303+
cr_assert( ERROR_INVALID_ARGUMENT == dispatch( &prm, acc ) );
304+
305+
// Now give the price account enough lamports to be rent exempt
306+
acc[1].lamports = &PRICE_ACCOUNT_LAMPORTS;
307+
297308
cr_assert( SUCCESS == dispatch( &prm, acc ) );
298309
cr_assert( sptr->num_ == 1 );
299310
cr_assert( pc_pub_key_equal( &idata.pub_, &sptr->comp_[0].pub_ ) );
@@ -358,7 +369,7 @@ Test( oracle, upd_test ) {
358369
.executable = false
359370
},{
360371
.key = &mkey,
361-
.lamports = &pqty,
372+
.lamports = &PRICE_ACCOUNT_LAMPORTS,
362373
.data_len = sizeof( pc_price_t ),
363374
.data = (uint8_t*)mptr,
364375
.owner = &p_id,
@@ -436,7 +447,7 @@ Test( oracle, upd_price ) {
436447
.executable = false
437448
},{
438449
.key = &skey,
439-
.lamports = &sqty,
450+
.lamports = &PRICE_ACCOUNT_LAMPORTS,
440451
.data_len = sizeof( pc_price_t ),
441452
.data = (uint8_t*)sptr,
442453
.owner = &p_id,
@@ -547,7 +558,7 @@ Test( oracle, upd_price_no_fail_on_error ) {
547558
.executable = false
548559
},{
549560
.key = &skey,
550-
.lamports = &sqty,
561+
.lamports = &PRICE_ACCOUNT_LAMPORTS,
551562
.data_len = sizeof( pc_price_t ),
552563
.data = (uint8_t*)sptr,
553564
.owner = &p_id,
@@ -745,7 +756,7 @@ Test( oracle, del_publisher ) {
745756
};
746757
SolPubkey pkey = {.x = { 1, }};
747758
SolPubkey skey = {.x = { 3, }};
748-
uint64_t pqty = 100, sqty = 200;
759+
uint64_t pqty = 100;
749760
pc_price_t sptr[1];
750761
sol_memset( sptr, 0, sizeof( pc_price_t ) );
751762
sptr->magic_ = PC_MAGIC;
@@ -768,7 +779,7 @@ Test( oracle, del_publisher ) {
768779
.executable = false
769780
},{
770781
.key = &skey,
771-
.lamports = &sqty,
782+
.lamports = &PRICE_ACCOUNT_LAMPORTS,
772783
.data_len = sizeof( pc_price_t ),
773784
.data = (uint8_t*)sptr,
774785
.owner = (SolPubkey*)&p_id,

0 commit comments

Comments
 (0)