Skip to content

Commit 18209e6

Browse files
committed
runtime: constrain ticks_per_slot in block harness
- Fixes bug where slots_per_year parameter differs between bank and genesis config (U.B. in the SVM) - Fixes bug where slots_per_year is taken from epoch context even though it can be fully derived from genesis config - Constrains ticks_per_slot (a hardcoded genesis parameter) to reasonable values, which would otherwise cause invalid floating points (denormals, infinite values) in epoch bounaries
1 parent 0eb9962 commit 18209e6

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/flamenco/rewards/fd_rewards.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "fd_rewards.h"
2+
#include <cfloat>
23
#include <math.h>
34

45
#include "../runtime/fd_acc_mgr.h"
@@ -17,9 +18,7 @@
1718
/* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/sdk/src/inflation.rs#L85 */
1819
static double
1920
total( fd_inflation_t const * inflation, double year ) {
20-
if ( FD_UNLIKELY( year == 0.0 ) ) {
21-
FD_LOG_ERR(( "inflation year 0" ));
22-
}
21+
if( FD_UNLIKELY( year < DBL_EPSILON ) ) FD_LOG_ERR(( "invalid inflation year parameter (corrupt genesis config?)" ));
2322
double tapered = inflation->initial * pow( (1.0 - inflation->taper), year );
2423
return (tapered > inflation->terminal) ? tapered : inflation->terminal;
2524
}
@@ -88,6 +87,11 @@ static double
8887
slot_in_year_for_inflation( fd_bank_t const * bank ) {
8988
fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank );
9089
ulong num_slots = get_inflation_num_slots( bank, epoch_schedule, fd_bank_slot_get( bank ) );
90+
FD_LOG_DEBUG(( "slot_in_year_for_inflation:"
91+
" num_slots=%lu"
92+
" slots_per_year=%g",
93+
num_slots,
94+
fd_bank_slots_per_year_get( bank ) ));
9195
return (double)num_slots / (double)fd_bank_slots_per_year_get( bank );
9296
}
9397

@@ -441,7 +445,17 @@ calculate_previous_epoch_inflation_rewards( fd_bank_t const *
441445
rewards->foundation_rate = foundation( fd_bank_inflation_query( bank ), slot_in_year );
442446
rewards->prev_epoch_duration_in_years = epoch_duration_in_years( bank, prev_epoch );
443447
rewards->validator_rewards = (ulong)(rewards->validator_rate * (double)prev_epoch_capitalization * rewards->prev_epoch_duration_in_years);
444-
FD_LOG_DEBUG(( "Rewards %lu, Rate %.16f, Duration %.18f Capitalization %lu Slot in year %.16f", rewards->validator_rewards, rewards->validator_rate, rewards->prev_epoch_duration_in_years, prev_epoch_capitalization, slot_in_year ));
448+
FD_LOG_DEBUG(( "calculate_previous_epoch_inflation_rewards:"
449+
" slot_in_year=%g"
450+
" valdiator_rewards=%lu"
451+
" validator_rate=%g"
452+
" prev_epoch_duration_in_years=%g"
453+
" prev_epoch_capitalization=%lu",
454+
slot_in_year,
455+
rewards->validator_rewards,
456+
rewards->validator_rate,
457+
rewards->prev_epoch_duration_in_years,
458+
prev_epoch_capitalization ));
445459
}
446460

447461
/* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/lib.rs#L29 */
@@ -998,6 +1012,11 @@ fd_distribute_partitioned_epoch_rewards( fd_bank_t * bank,
9981012
ulong distribution_starting_block_height = epoch_rewards->starting_block_height;
9991013
ulong distribution_end_exclusive = fd_epoch_rewards_get_exclusive_ending_block_height( epoch_rewards );
10001014

1015+
if( block_height < distribution_starting_block_height ) {
1016+
fd_bank_epoch_rewards_end_locking_query( bank );
1017+
return;
1018+
}
1019+
10011020
fd_epoch_schedule_t const * epoch_schedule = fd_bank_epoch_schedule_query( bank );
10021021
ulong epoch = fd_bank_epoch_get( bank );
10031022

src/flamenco/runtime/tests/fd_block_harness.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,13 @@ fd_solfuzz_pb_block_ctx_destroy( fd_solfuzz_runner_t * runner ) {
238238
fd_progcache_clear( runner->progcache_admin );
239239
}
240240

241+
static double
242+
years_as_slots( double years,
243+
ulong tick_duration_ns,
244+
ulong ticks_per_slot ) {
245+
return years * SECONDS_PER_YEAR * (1e9 / (double)tick_duration_ns) / (double)ticks_per_slot;
246+
}
247+
241248
/* Sets up block execution context from an input test case to execute
242249
against the runtime. Returns block_info on success and NULL on
243250
failure. */
@@ -296,7 +303,15 @@ fd_solfuzz_pb_block_ctx_create( fd_solfuzz_runner_t * runner,
296303

297304
fd_bank_genesis_creation_time_set( bank, test_ctx->epoch_ctx.genesis_creation_time );
298305

299-
fd_bank_slots_per_year_set( bank, test_ctx->epoch_ctx.slots_per_year );
306+
double slots_per_year = years_as_slots( 1.0, 6250000, test_ctx->epoch_ctx.ticks_per_slot );
307+
if( FD_UNLIKELY( test_ctx->epoch_ctx.ticks_per_slot < 1 ||
308+
test_ctx->epoch_ctx.ticks_per_slot > 1000 ||
309+
slots_per_year<1000. ||
310+
slots_per_year>10e9 ) ) {
311+
FD_LOG_ERR(( "invalid ticks_per_slot value: %lu", test_ctx->epoch_ctx.ticks_per_slot ));
312+
}
313+
314+
fd_bank_slots_per_year_set( bank, slots_per_year );
300315

301316
fd_bank_parent_signature_cnt_set( bank, test_ctx->slot_ctx.parent_signature_count );
302317

0 commit comments

Comments
 (0)