Skip to content

Commit

Permalink
Add fd_sysvar_rent query helper
Browse files Browse the repository at this point in the history
  • Loading branch information
riptl authored and ripatel-fd committed Jan 9, 2024
1 parent 3e6d351 commit 6d3ed92
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/flamenco/runtime/sysvar/Local.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
ifdef FD_HAS_INT128
$(call add-hdrs,fd_sysvar_rent.h)

$(call add-objs,fd_sysvar_rent,fd_flamenco)

$(call make-unit-test,test_sysvar_rent,test_sysvar_rent,fd_flamenco fd_funk fd_ballet fd_util)
$(call run-unit-test,test_sysvar_rent)
endif
40 changes: 40 additions & 0 deletions src/flamenco/runtime/sysvar/fd_sysvar_rent.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,51 @@
#include "fd_sysvar_rent.h"
#include "../fd_acc_mgr.h"
#include "../fd_system_ids.h"
#include <assert.h>

/* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/rent.rs#L36 */
#define ACCOUNT_STORAGE_OVERHEAD (128)

fd_rent_t *
fd_sysvar_rent_read( fd_rent_t * result,
fd_exec_slot_ctx_t * slot_ctx ) {

FD_BORROWED_ACCOUNT_DECL(rent_rec);

int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_rent_id, rent_rec );
if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) {
FD_LOG_WARNING(( "failed to read rent sysvar: %d", err ));
return NULL;
}

fd_bincode_decode_ctx_t decode = {
.data = rent_rec->const_data,
.dataend = rent_rec->const_data + rent_rec->const_meta->dlen,
.valloc = slot_ctx->valloc
};
err = fd_rent_decode( result, &decode );
if( FD_UNLIKELY( err ) ) {
FD_LOG_WARNING(( "fd_rent_decode failed" ));
return NULL;
}

return result;
}

ulong
fd_rent_exempt_minimum_balance2( fd_rent_t const * rent,
ulong data_len ) {
/* https://github.com/solana-labs/solana/blob/792fafe0c25ac06868e3ac80a2b13f1a5b4a1ef8/sdk/program/src/rent.rs#L72 */
return (ulong)( (double)((data_len + ACCOUNT_STORAGE_OVERHEAD) * rent->lamports_per_uint8_year) * (double)rent->exemption_threshold );
}

ulong
fd_rent_exempt_minimum_balance( fd_exec_slot_ctx_t * slot_ctx,
ulong data_len ) {
/* TODO wire up with sysvar cache */
fd_rent_t rent;
fd_rent_new( &rent );
fd_rent_t * result = fd_sysvar_rent_read( &rent, slot_ctx );
assert( result );
return fd_rent_exempt_minimum_balance2( &rent, data_len );
}
17 changes: 17 additions & 0 deletions src/flamenco/runtime/sysvar/fd_sysvar_rent.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@

FD_PROTOTYPES_BEGIN

/* fd_sysvar_rent_read queries the rent sysvar from the given slot
context. Rent sysvar is written into *result (may be uninitialized).
Returns result on success, NULL otherwise. */

fd_rent_t *
fd_sysvar_rent_read( fd_rent_t * result,
fd_exec_slot_ctx_t * slot_ctx );

/* fd_rent_exempt_minimum_balance returns the minimum balance needed
for an account with the given data_len to be rent exempt. slot_ctx
is a slot execution context that has a rent sysvar. (Aborts program
if rent sysvar is invalid) */

ulong
fd_rent_exempt_minimum_balance( fd_exec_slot_ctx_t * slot_ctx,
ulong data_len );

/* fd_rent_exempt_minimum_balance2 returns the minimum balance needed
for an account with the given data_len to be rent exempt. rent
points to the current rent parameters. */
Expand Down
67 changes: 67 additions & 0 deletions src/flamenco/runtime/sysvar/test_sysvar_rent.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "../../fd_flamenco.h"
#include "fd_sysvar_rent.h"

struct fd_rent_exempt_fixture {
/* Inputs */
ulong data_len;
ulong lamports_per_byte_year;
union {
double exemption_threshold;
ulong exemption_threshold_bits;
};
/* Output */
ulong min_balance;
};

typedef struct fd_rent_exempt_fixture fd_rent_exempt_fixture_t;


static fd_rent_exempt_fixture_t const
test_rent_exempt_vector[] = {
{ .data_len= 0, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 890880UL },
{ .data_len= 10, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 960480UL },
{ .data_len=131097, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 913326000UL },
{ .data_len= 16392, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 114979200UL },
{ .data_len= 17, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 1009200UL },
{ .data_len= 200, .lamports_per_byte_year= 3480, .exemption_threshold_bits=0x4000000000000000UL, .min_balance= 2282880UL },
{ .data_len= 200, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 2282880UL },
{ .data_len= 20488, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 143487360UL },
{ .data_len= 24, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 1057920UL },
{ .data_len= 33, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 1120560UL },
{ .data_len= 3731, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 26858640UL },
{ .data_len= 3762, .lamports_per_byte_year= 3480, .exemption_threshold_bits=0x4000000000000000UL, .min_balance= 27074400UL },
{ .data_len= 3762, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 27074400UL },
{ .data_len=395693, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance=2754914160UL },
{ .data_len= 40, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 1169280UL },
{ .data_len= 6008, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 42706560UL },
{ .data_len= 82, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 1461600UL },
{ .data_len= 8, .lamports_per_byte_year= 3480, .exemption_threshold_bits=0x4000000000000000UL, .min_balance= 946560UL },
{ .data_len= 8, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 946560UL },
{ .data_len= 9, .lamports_per_byte_year=46980000, .exemption_threshold_bits=0x3f236b06e70b7421UL, .min_balance= 953520UL }
};
#define test_rent_exempt_vector_end (fd_rent_exempt_fixture_t const *)( (uchar const *)test_rent_exempt_vector + sizeof(test_rent_exempt_vector) )


int
main( int argc,
char ** argv ) {
fd_boot( &argc, &argv );
fd_flamenco_boot( &argc, &argv );

fd_rent_exempt_fixture_t const * iter;
for( iter = test_rent_exempt_vector;
iter < test_rent_exempt_vector_end;
iter++ ) {
fd_rent_t rent = {
.lamports_per_uint8_year = iter->lamports_per_byte_year,
.exemption_threshold = iter->exemption_threshold,
};
ulong min_balance = fd_rent_exempt_minimum_balance2( &rent, iter->data_len );
FD_TEST( min_balance == iter->min_balance );
}

FD_LOG_NOTICE(( "pass" ));
fd_flamenco_halt();
fd_halt();
return 0;
}

0 comments on commit 6d3ed92

Please sign in to comment.