Skip to content
5 changes: 5 additions & 0 deletions src/app/firedancer-dev/commands/backtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ backtest_topo( config_t * config ) {
fd_topob_tile_uses( topo, replay_tile, store_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
FD_TEST( fd_pod_insertf_ulong( topo->props, store_obj->id, "store" ) );

fd_topo_obj_t * acc_pool_obj = setup_topo_acc_pool( topo, config->firedancer.runtime.max_account_cnt );
fd_topob_tile_uses( topo, replay_tile, acc_pool_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], acc_pool_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
FD_TEST( fd_pod_insertf_ulong( topo->props, acc_pool_obj->id, "acc_pool" ) );

/* banks_obj shared by replay and exec tiles */
fd_topob_wksp( topo, "banks" );
fd_topo_obj_t * banks_obj = setup_topo_banks( topo, "banks", config->firedancer.runtime.max_live_slots, config->firedancer.runtime.max_fork_width, 0 );
Expand Down
2 changes: 2 additions & 0 deletions src/app/firedancer-dev/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern fd_topo_obj_callbacks_t fd_obj_cb_fec_sets;
extern fd_topo_obj_callbacks_t fd_obj_cb_txncache;
extern fd_topo_obj_callbacks_t fd_obj_cb_banks;
extern fd_topo_obj_callbacks_t fd_obj_cb_funk;
extern fd_topo_obj_callbacks_t fd_obj_cb_acc_pool;

extern fd_topo_obj_callbacks_t fd_obj_cb_vinyl_meta;
extern fd_topo_obj_callbacks_t fd_obj_cb_vinyl_meta_ele;
Expand All @@ -47,6 +48,7 @@ fd_topo_obj_callbacks_t * CALLBACKS[] = {
&fd_obj_cb_vinyl_meta,
&fd_obj_cb_vinyl_meta_ele,
&fd_obj_cb_vinyl_data,
&fd_obj_cb_acc_pool,
NULL,
};

Expand Down
26 changes: 26 additions & 0 deletions src/app/firedancer/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../../disco/topo/fd_topo.h"
#include "../../disco/store/fd_store.h"
#include "../../flamenco/runtime/fd_bank.h"
#include "../../flamenco/runtime/fd_acc_pool.h"
#include "../../flamenco/runtime/fd_txncache_shmem.h"
#include "../../funk/fd_funk.h"

Expand Down Expand Up @@ -177,4 +178,29 @@ fd_topo_obj_callbacks_t fd_obj_cb_txncache = {
.new = txncache_new,
};

static ulong
acc_pool_footprint( fd_topo_t const * topo,
fd_topo_obj_t const * obj ) {
return fd_acc_pool_footprint( VAL("max_account_cnt") );
}

static ulong
acc_pool_align( fd_topo_t const * topo FD_FN_UNUSED,
fd_topo_obj_t const * obj FD_FN_UNUSED ) {
return fd_acc_pool_align();
}

static void
acc_pool_new( fd_topo_t const * topo,
fd_topo_obj_t const * obj ) {
FD_TEST( fd_acc_pool_new( fd_topo_obj_laddr( topo, obj->id ), VAL("max_account_cnt") ) );
}

fd_topo_obj_callbacks_t fd_obj_cb_acc_pool = {
.name = "acc_pool",
.footprint = acc_pool_footprint,
.align = acc_pool_align,
.new = acc_pool_new,
};

#undef VAL
6 changes: 6 additions & 0 deletions src/app/firedancer/config/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,12 @@ user = ""
# max_fork_width, the client will crash.
max_fork_width = 32

# max_account_cnt is the used to size out the amount of memory used
# by transaction execution for account staging. The minimum amount
# of accounts is 256 if bundles are disabled and is 640 if bundles
# are enabled.
max_account_cnt = 1024

# The program cache pre-loads frequently executed programs for
# faster transaction execution.
[runtime.program_cache]
Expand Down
2 changes: 2 additions & 0 deletions src/app/firedancer/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern fd_topo_obj_callbacks_t fd_obj_cb_fec_sets;
extern fd_topo_obj_callbacks_t fd_obj_cb_txncache;
extern fd_topo_obj_callbacks_t fd_obj_cb_banks;
extern fd_topo_obj_callbacks_t fd_obj_cb_funk;
extern fd_topo_obj_callbacks_t fd_obj_cb_acc_pool;

fd_topo_obj_callbacks_t * CALLBACKS[] = {
&fd_obj_cb_mcache,
Expand All @@ -36,6 +37,7 @@ fd_topo_obj_callbacks_t * CALLBACKS[] = {
&fd_obj_cb_txncache,
&fd_obj_cb_banks,
&fd_obj_cb_funk,
&fd_obj_cb_acc_pool,
NULL,
};

Expand Down
21 changes: 21 additions & 0 deletions src/app/firedancer/topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "../../discof/restore/utils/fd_ssctrl.h"
#include "../../discof/restore/utils/fd_ssmsg.h"
#include "../../flamenco/progcache/fd_progcache_admin.h"
#include "../../flamenco/runtime/fd_acc_pool.h"
#include "../../vinyl/meta/fd_vinyl_meta.h"
#include "../../vinyl/io/fd_vinyl_io.h" /* FD_VINYL_IO_TYPE_* */

Expand Down Expand Up @@ -154,6 +155,17 @@ setup_topo_txncache( fd_topo_t * topo,
return obj;
}

fd_topo_obj_t *
setup_topo_acc_pool( fd_topo_t * topo,
ulong max_account_cnt ) {
fd_topob_wksp( topo, "acc_pool" );
fd_topo_obj_t * acc_pool_obj = fd_topob_obj( topo, "acc_pool", "acc_pool" );
fd_pod_insertf_ulong( topo->props, max_account_cnt, "obj.%lu.max_account_cnt", acc_pool_obj->id );
FD_TEST( acc_pool_obj );
FD_TEST( acc_pool_obj->id != ULONG_MAX );
return acc_pool_obj;
}

void
setup_topo_vinyl_meta( fd_topo_t * topo,
fd_configf_t * config ) {
Expand Down Expand Up @@ -947,6 +959,13 @@ fd_topo_initialize( config_t * config ) {
FOR(resolv_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "resolv", i ) ], banks_obj, FD_SHMEM_JOIN_MODE_READ_ONLY );
FD_TEST( fd_pod_insertf_ulong( topo->props, banks_obj->id, "banks" ) );

if( FD_UNLIKELY( config->tiles.bundle.enabled ) ) FD_TEST( config->firedancer.runtime.max_account_cnt>=FD_ACC_POOL_MIN_ACCOUNT_CNT_PER_BUNDLE );
FD_TEST( config->firedancer.runtime.max_account_cnt>=FD_ACC_POOL_MIN_ACCOUNT_CNT_PER_TX );
fd_topo_obj_t * acc_pool_obj = setup_topo_acc_pool( topo, config->firedancer.runtime.max_account_cnt );
FOR(exec_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "exec", i ) ], acc_pool_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
FOR(bank_tile_cnt) fd_topob_tile_uses( topo, &topo->tiles[ fd_topo_find_tile( topo, "bank", i ) ], acc_pool_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
FD_TEST( fd_pod_insertf_ulong( topo->props, acc_pool_obj->id, "acc_pool" ) );

fd_topo_obj_t * progcache_obj = setup_topo_progcache( topo, "progcache",
fd_progcache_est_rec_max( config->firedancer.runtime.program_cache.heap_size_mib<<20,
config->firedancer.runtime.program_cache.mean_cache_entry_size ),
Expand Down Expand Up @@ -1267,6 +1286,7 @@ fd_topo_configure_tile( fd_topo_tile_t * tile,
tile->exec.funk_obj_id = fd_pod_query_ulong( config->topo.props, "funk", ULONG_MAX ); FD_TEST( tile->exec.funk_obj_id !=ULONG_MAX );
tile->exec.txncache_obj_id = fd_pod_query_ulong( config->topo.props, "txncache", ULONG_MAX ); FD_TEST( tile->exec.txncache_obj_id !=ULONG_MAX );
tile->exec.progcache_obj_id = fd_pod_query_ulong( config->topo.props, "progcache", ULONG_MAX ); FD_TEST( tile->exec.progcache_obj_id!=ULONG_MAX );
tile->exec.acc_pool_obj_id = fd_pod_query_ulong( config->topo.props, "acc_pool", ULONG_MAX ); FD_TEST( tile->exec.acc_pool_obj_id !=ULONG_MAX );

tile->exec.max_live_slots = config->firedancer.runtime.max_live_slots;

Expand Down Expand Up @@ -1343,6 +1363,7 @@ fd_topo_configure_tile( fd_topo_tile_t * tile,
tile->bank.txncache_obj_id = fd_pod_query_ulong( config->topo.props, "txncache", ULONG_MAX );
tile->bank.funk_obj_id = fd_pod_query_ulong( config->topo.props, "funk", ULONG_MAX );
tile->bank.progcache_obj_id = fd_pod_query_ulong( config->topo.props, "progcache", ULONG_MAX );
tile->bank.acc_pool_obj_id = fd_pod_query_ulong( config->topo.props, "acc_pool", ULONG_MAX );

tile->bank.max_live_slots = config->firedancer.runtime.max_live_slots;

Expand Down
4 changes: 4 additions & 0 deletions src/app/firedancer/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ setup_topo_store( fd_topo_t * topo,
ulong fec_max,
uint part_cnt );

fd_topo_obj_t *
setup_topo_acc_pool( fd_topo_t * topo,
ulong account_cnt );

fd_topo_obj_t *
setup_topo_txncache( fd_topo_t * topo,
char const * wksp_name,
Expand Down
1 change: 1 addition & 0 deletions src/app/shared/fd_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct fd_configf {
ulong max_live_slots;
ulong max_vote_accounts;
ulong max_fork_width;
ulong max_account_cnt;

struct {
ulong heap_size_mib;
Expand Down
1 change: 1 addition & 0 deletions src/app/shared/fd_config_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ fd_config_extract_podf( uchar * pod,
CFG_POP ( uint, vinyl.io_uring.queue_depth );

CFG_POP ( ulong, runtime.max_live_slots );
CFG_POP ( ulong, runtime.max_account_cnt );
CFG_POP ( ulong, runtime.max_vote_accounts );
CFG_POP ( ulong, runtime.max_fork_width );

Expand Down
1 change: 1 addition & 0 deletions src/app/shared/fd_tile_unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fd_topo_obj_callbacks_t * CALLBACKS[] = {
&fd_obj_cb_txncache,
&fd_obj_cb_banks,
&fd_obj_cb_funk,
&fd_obj_cb_acc_pool,
NULL,
};

Expand Down
2 changes: 2 additions & 0 deletions src/disco/topo/fd_topo.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ struct fd_topo_tile {
ulong funk_obj_id;
ulong txncache_obj_id;
ulong progcache_obj_id;
ulong acc_pool_obj_id;

ulong max_live_slots;

Expand Down Expand Up @@ -593,6 +594,7 @@ struct fd_topo_tile {
ulong txncache_obj_id;
ulong funk_obj_id;
ulong progcache_obj_id;
ulong acc_pool_obj_id;
} bank;

struct {
Expand Down
53 changes: 31 additions & 22 deletions src/discof/bank/fd_bank_tile.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "../../disco/metrics/generated/fd_metrics_enums.h"
#include "../../flamenco/runtime/fd_runtime.h"
#include "../../flamenco/runtime/fd_bank.h"
#include "../../flamenco/runtime/fd_acc_pool.h"
#include "../../flamenco/accdb/fd_accdb_impl_v1.h"
#include "../../flamenco/progcache/fd_progcache_user.h"
#include "../../flamenco/log_collector/fd_log_collector.h"
Expand Down Expand Up @@ -62,9 +63,8 @@ struct fd_bank_ctx {
a separate transaction context and a set of accounts, but the exec
stack can be reused. We will also use these same memory regions
for non-bundle execution. */
fd_exec_accounts_t exec_accounts[ FD_PACK_MAX_TXN_PER_BUNDLE ];
fd_txn_in_t txn_in[ FD_PACK_MAX_TXN_PER_BUNDLE ];
fd_txn_out_t txn_out[ FD_PACK_MAX_TXN_PER_BUNDLE ];
fd_txn_in_t txn_in[ FD_PACK_MAX_TXN_PER_BUNDLE ];
fd_txn_out_t txn_out[ FD_PACK_MAX_TXN_PER_BUNDLE ];

fd_log_collector_t log_collector[ 1 ];

Expand Down Expand Up @@ -178,8 +178,6 @@ handle_microblock( fd_bank_ctx_t * ctx,
for( ulong i=0UL; i<txn_cnt; i++ ) {
fd_txn_p_t * txn = (fd_txn_p_t *)( dst + (i*sizeof(fd_txn_p_t)) );
fd_txn_in_t * txn_in = &ctx->txn_in[ 0 ];
ctx->txn_in->bundle.is_bundle = 0;

fd_txn_out_t * txn_out = &ctx->txn_out[ 0 ];

uint requested_exec_plus_acct_data_cus = txn->pack_cu.requested_exec_plus_acct_data_cus;
Expand All @@ -192,8 +190,8 @@ handle_microblock( fd_bank_ctx_t * ctx,
txn->flags &= ~FD_TXN_P_FLAGS_SANITIZE_SUCCESS;
txn->flags &= ~FD_TXN_P_FLAGS_EXECUTE_SUCCESS;

txn_in->txn = txn;
txn_in->exec_accounts = &ctx->exec_accounts[ 0 ];
txn_in->bundle.is_bundle = 0;
txn_in->txn = txn;

fd_bank_t * bank = fd_banks_bank_query( ctx->banks, ctx->_bank_idx );
FD_TEST( bank );
Expand All @@ -204,6 +202,7 @@ handle_microblock( fd_bank_ctx_t * ctx,

if( FD_UNLIKELY( !txn_out->err.is_committable ) ) {
FD_TEST( !txn_out->err.is_fees_only );
fd_runtime_cancel_txn( ctx->runtime, txn_out );
if( FD_LIKELY( ctx->enable_rebates ) ) fd_pack_rebate_sum_add_txn( ctx->rebater, txn, NULL, 1UL );
ctx->metrics.txn_landed[ FD_METRICS_ENUM_TRANSACTION_LANDED_V_UNLANDED_IDX ]++;
ctx->metrics.txn_result[ fd_bank_err_from_runtime_err( txn_out->err.txn_err ) ]++;
Expand Down Expand Up @@ -232,27 +231,27 @@ handle_microblock( fd_bank_ctx_t * ctx,
if that happens. We cannot reject the transaction here as there
would be no way to undo the partially applied changes to the bank
in finalize anyway. */
fd_runtime_commit_txn( ctx->runtime, bank, txn_in, txn_out );
fd_runtime_commit_txn( ctx->runtime, bank, txn_out );

if( FD_UNLIKELY( !txn_out->err.is_committable ) ) {
/* If the transaction failed to fit into the block, we need to
updated the transaction flag with the error code. */
txn->flags = (txn->flags & 0x00FFFFFFU) | ((uint)(-txn_out->err.txn_err)<<24);
fd_cost_tracker_t * cost_tracker = fd_bank_cost_tracker_locking_modify( bank );
uchar * signature = (uchar *)txn_in->txn->payload + TXN( txn_in->txn )->signature_off;
int res = fd_cost_tracker_calculate_cost_and_add( cost_tracker, bank, txn_in, txn_out );
int err = fd_cost_tracker_try_add_cost( cost_tracker, txn_out );
FD_LOG_HEXDUMP_WARNING(( "txn", txn->payload, txn->payload_sz ));
FD_LOG_CRIT(( "transaction %s failed to fit into block despite pack guaranteeing it would "
"(res=%d) [block_cost=%lu, vote_cost=%lu, allocated_accounts_data_size=%lu, "
"block_cost_limit=%lu, vote_cost_limit=%lu, account_cost_limit=%lu]",
FD_BASE58_ENC_64_ALLOCA( signature ), res, cost_tracker->block_cost, cost_tracker->vote_cost,
FD_BASE58_ENC_64_ALLOCA( signature ), err, cost_tracker->block_cost, cost_tracker->vote_cost,
cost_tracker->allocated_accounts_data_size,
cost_tracker->block_cost_limit, cost_tracker->vote_cost_limit,
cost_tracker->account_cost_limit ));
}

uint actual_execution_cus = (uint)(txn_out->details.compute_budget.compute_unit_limit - txn_out->details.compute_budget.compute_meter);
uint actual_acct_data_cus = (uint)(txn_out->details.loaded_accounts_data_size_cost);
uint actual_acct_data_cus = (uint)(txn_out->details.txn_cost.transaction.loaded_accounts_data_size_cost);

int is_simple_vote = 0;
if( FD_UNLIKELY( is_simple_vote = fd_txn_is_simple_vote_transaction( TXN(txn), txn->payload ) ) ) {
Expand Down Expand Up @@ -377,12 +376,11 @@ handle_bundle( fd_bank_ctx_t * ctx,
continue;
}

txn_in->txn = txn;
txn_in->exec_accounts = &ctx->exec_accounts[ i ];
txn_in->txn = txn;
txn_in->bundle.is_bundle = 1;

fd_bank_t * bank = fd_banks_bank_query( ctx->banks, ctx->_bank_idx );
FD_TEST( bank );
txn_in->bundle.is_bundle = 1;
fd_runtime_prepare_and_execute_txn( ctx->runtime, bank, txn_in, txn_out );
txn->flags = (txn->flags & 0x00FFFFFFU) | ((uint)(-txn_out->err.txn_err)<<24);
if( FD_UNLIKELY( !txn_out->err.is_committable || txn_out->err.txn_err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) {
Expand All @@ -405,23 +403,23 @@ handle_bundle( fd_bank_ctx_t * ctx,
fd_txn_out_t * txn_out = &ctx->txn_out[ i ];
uchar * signature = (uchar *)txn_in->txn->payload + TXN( txn_in->txn )->signature_off;

fd_runtime_commit_txn( ctx->runtime, bank, txn_in, txn_out );
fd_runtime_commit_txn( ctx->runtime, bank, txn_out );
if( FD_UNLIKELY( !txn_out->err.is_committable ) ) {
txns[ i ].flags = (txns[ i ].flags & 0x00FFFFFFU) | ((uint)(-txn_out->err.txn_err)<<24);
fd_cost_tracker_t * cost_tracker = fd_bank_cost_tracker_locking_modify( bank );
int res = fd_cost_tracker_calculate_cost_and_add( cost_tracker, bank, txn_in, txn_out );
int err = fd_cost_tracker_try_add_cost( cost_tracker, txn_out );
FD_LOG_HEXDUMP_WARNING(( "txn", txns[ i ].payload, txns[ i ].payload_sz ));
FD_LOG_CRIT(( "transaction %s failed to fit into block despite pack guaranteeing it would "
"(res=%d) [block_cost=%lu, vote_cost=%lu, allocated_accounts_data_size=%lu, "
"block_cost_limit=%lu, vote_cost_limit=%lu, account_cost_limit=%lu]",
FD_BASE58_ENC_64_ALLOCA( signature ), res, cost_tracker->block_cost, cost_tracker->vote_cost,
FD_BASE58_ENC_64_ALLOCA( signature ), err, cost_tracker->block_cost, cost_tracker->vote_cost,
cost_tracker->allocated_accounts_data_size,
cost_tracker->block_cost_limit, cost_tracker->vote_cost_limit,
cost_tracker->account_cost_limit ));
}

uint actual_execution_cus = (uint)(txn_out->details.compute_budget.compute_unit_limit - txn_out->details.compute_budget.compute_meter);
uint actual_acct_data_cus = (uint)(txn_out->details.loaded_accounts_data_size_cost);
uint actual_acct_data_cus = (uint)(txn_out->details.txn_cost.transaction.loaded_accounts_data_size_cost);
if( FD_UNLIKELY( fd_txn_is_simple_vote_transaction( TXN( &txns[ i ] ), txns[ i ].payload ) ) ) {
actual_execution_cus = FD_PACK_VOTE_DEFAULT_COMPUTE_UNITS;
actual_acct_data_cus = 0U;
Expand All @@ -436,6 +434,14 @@ handle_bundle( fd_bank_ctx_t * ctx,
}
} else {
for( ulong i=0UL; i<txn_cnt; i++ ) {

/* If the bundle peer flag is not set, that means the transaction
was at least partially sanitized/setup. We have to cancel
these txns as they will not be included in the block. */
if( !(txns[ i ].flags % ((uint)(-FD_RUNTIME_TXN_ERR_BUNDLE_PEER)<<24)) ) {
fd_runtime_cancel_txn( ctx->runtime, &ctx->txn_out[ i ] );
}

uint requested_exec_plus_acct_data_cus = txns[ i ].pack_cu.requested_exec_plus_acct_data_cus;
uint non_execution_cus = txns[ i ].pack_cu.non_execution_cus;
txns[ i ].bank_cu.actual_consumed_cus = 0U;
Expand Down Expand Up @@ -588,18 +594,21 @@ unprivileged_init( fd_topo_t * topo,
fd_txncache_t * txncache = fd_txncache_join( fd_txncache_new( _txncache, txncache_shmem ) );
FD_TEST( txncache );


fd_acc_pool_t * acc_pool = fd_acc_pool_join( fd_topo_obj_laddr( topo, tile->bank.acc_pool_obj_id ) );
FD_TEST( acc_pool );

for( ulong i=0UL; i<FD_PACK_MAX_TXN_PER_BUNDLE; i++ ) {
ctx->txn_in[ i ].bundle.prev_txn_cnt = i;
for( ulong j=0UL; j<i; j++ ) {
ctx->txn_in[ i ].bundle.prev_txn_ins[ j ] = &ctx->txn_in[ j ];
ctx->txn_in[ i ].bundle.prev_txn_outs[ j ] = &ctx->txn_out[ j ];
}
for( ulong j=0UL; j<i; j++ ) ctx->txn_in[ i ].bundle.prev_txn_outs[ j ] = &ctx->txn_out[ j ];
}

ctx->runtime->accdb = accdb;
ctx->runtime->funk = fd_accdb_user_v1_funk( accdb );
ctx->runtime->progcache = progcache;
ctx->runtime->status_cache = txncache;
ctx->runtime->acc_pool = acc_pool;

ctx->runtime->log.log_collector = ctx->log_collector;
ctx->runtime->log.enable_log_collector = 0;
ctx->runtime->log.capture_ctx = NULL;
Expand Down
Loading
Loading