diff --git a/src/app/firedancer-dev/commands/backtest.c b/src/app/firedancer-dev/commands/backtest.c index 1feb407b35..09ed889173 100644 --- a/src/app/firedancer-dev/commands/backtest.c +++ b/src/app/firedancer-dev/commands/backtest.c @@ -15,7 +15,7 @@ */ -#include "../../shared/commands/configure/configure.h" +#include "../../firedancer/topology.h" #include "../../shared/commands/run/run.h" /* initialize_workspaces */ #include "../../shared/fd_config.h" /* config_t */ #include "../../../disco/tiles.h" @@ -23,124 +23,12 @@ #include "../../../disco/topo/fd_topob.h" #include "../../../disco/topo/fd_pod_format.h" #include "../../../discof/geyser/fd_replay_notif.h" -#include "../../../flamenco/runtime/fd_runtime.h" #include "../../../flamenco/runtime/fd_txncache.h" -#include "../../../flamenco/snapshot/fd_snapshot_base.h" #include /* pause */ extern fd_topo_obj_callbacks_t * CALLBACKS[]; fd_topo_run_tile_t fdctl_tile_run( fd_topo_tile_t const * tile ); -static fd_topo_obj_t * -setup_topo_runtime_pub( fd_topo_t * topo, - char const * wksp_name, - ulong mem_max ) { - fd_topo_obj_t * obj = fd_topob_obj( topo, "runtime_pub", wksp_name ); - FD_TEST( fd_pod_insertf_ulong( topo->props, mem_max, "obj.%lu.mem_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, 12UL, "obj.%lu.wksp_tag", obj->id ) ); - return obj; -} - -static fd_topo_obj_t * -setup_topo_txncache( fd_topo_t * topo, - char const * wksp_name, - ulong max_rooted_slots, - ulong max_live_slots, - ulong max_txn_per_slot, - ulong max_constipated_slots ) { - fd_topo_obj_t * obj = fd_topob_obj( topo, "txncache", wksp_name ); - - FD_TEST( fd_pod_insertf_ulong( topo->props, max_rooted_slots, "obj.%lu.max_rooted_slots", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, max_live_slots, "obj.%lu.max_live_slots", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, max_txn_per_slot, "obj.%lu.max_txn_per_slot", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, max_constipated_slots, "obj.%lu.max_constipated_slots", obj->id ) ); - - return obj; -} - -#include -#include "../../../flamenco/runtime/fd_blockstore.h" -static fd_topo_obj_t * -setup_topo_blockstore( fd_topo_t * topo, - char const * wksp_name, - ulong shred_max, - ulong block_max, - ulong idx_max, - ulong txn_max, - ulong alloc_max ) { - fd_topo_obj_t * obj = fd_topob_obj( topo, "blockstore", wksp_name ); - - ulong seed; - FD_TEST( sizeof(ulong) == getrandom( &seed, sizeof(ulong), 0 ) ); - - FD_TEST( fd_pod_insertf_ulong( topo->props, 1UL, "obj.%lu.wksp_tag", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, seed, "obj.%lu.seed", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, shred_max, "obj.%lu.shred_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, block_max, "obj.%lu.block_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, idx_max, "obj.%lu.idx_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, txn_max, "obj.%lu.txn_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, alloc_max, "obj.%lu.alloc_max", obj->id ) ); - - /* DO NOT MODIFY LOOSE WITHOUT CHANGING HOW BLOCKSTORE ALLOCATES INTERNAL STRUCTURES */ - - ulong blockstore_footprint = fd_blockstore_footprint( shred_max, block_max, idx_max, txn_max ) + alloc_max; - FD_TEST( fd_pod_insertf_ulong( topo->props, blockstore_footprint, "obj.%lu.loose", obj->id ) ); - - return obj; -} - -static void -setup_snapshots( config_t * config, - fd_topo_tile_t * tile ) { - uchar incremental_is_file, incremental_is_url; - if( strnlen( config->tiles.replay.incremental, PATH_MAX )>0UL ) { - incremental_is_file = 1U; - } else { - incremental_is_file = 0U; - } - if( strnlen( config->tiles.replay.incremental_url, PATH_MAX )>0UL ) { - incremental_is_url = 1U; - } else { - incremental_is_url = 0U; - } - if( FD_UNLIKELY( incremental_is_file && incremental_is_url ) ) { - FD_LOG_ERR(( "At most one of the incremental snapshot source strings in the configuration file under [tiles.replay.incremental] and [tiles.replay.incremental_url] may be set." )); - } - tile->replay.incremental_src_type = INT_MAX; - if( FD_LIKELY( incremental_is_url ) ) { - strncpy( tile->replay.incremental, config->tiles.replay.incremental_url, sizeof(tile->replay.incremental) ); - tile->replay.incremental_src_type = FD_SNAPSHOT_SRC_HTTP; - } - if( FD_UNLIKELY( incremental_is_file ) ) { - strncpy( tile->replay.incremental, config->tiles.replay.incremental, sizeof(tile->replay.incremental) ); - tile->replay.incremental_src_type = FD_SNAPSHOT_SRC_FILE; - } - - uchar snapshot_is_file, snapshot_is_url; - if( strnlen( config->tiles.replay.snapshot, PATH_MAX )>0UL ) { - snapshot_is_file = 1U; - } else { - snapshot_is_file = 0U; - } - if( strnlen( config->tiles.replay.snapshot_url, PATH_MAX )>0UL ) { - snapshot_is_url = 1U; - } else { - snapshot_is_url = 0U; - } - if( FD_UNLIKELY( snapshot_is_file && snapshot_is_url ) ) { - FD_LOG_ERR(( "At most one of the full snapshot source strings in the configuration file under [tiles.replay.snapshot] and [tiles.replay.snapshot_url] may be set." )); - } - tile->replay.snapshot_src_type = INT_MAX; - if( FD_LIKELY( snapshot_is_url ) ) { - strncpy( tile->replay.snapshot, config->tiles.replay.snapshot_url, sizeof(tile->replay.snapshot) ); - tile->replay.snapshot_src_type = FD_SNAPSHOT_SRC_HTTP; - } - if( FD_UNLIKELY( snapshot_is_file ) ) { - strncpy( tile->replay.snapshot, config->tiles.replay.snapshot, sizeof(tile->replay.snapshot) ); - tile->replay.snapshot_src_type = FD_SNAPSHOT_SRC_FILE; - } -} - static void backtest_topo( config_t * config ) { fd_topo_cpus_t cpus[1]; @@ -164,75 +52,19 @@ backtest_topo( config_t * config ) { /**********************************************************************/ fd_topob_wksp( topo, "metric" ); fd_topob_wksp( topo, "metric_in" ); - fd_topo_tile_t * metric_tile = fd_topob_tile( topo, "metric", "metric", "metric_in", metric_cpu_idx, 0, 0 ); - if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( config->tiles.metric.prometheus_listen_address, &metric_tile->metric.prometheus_listen_addr ) ) ) - FD_LOG_ERR(( "failed to parse prometheus listen address `%s`", config->tiles.metric.prometheus_listen_address )); - metric_tile->metric.prometheus_listen_port = config->tiles.metric.prometheus_listen_port; + fd_topob_tile( topo, "metric", "metric", "metric_in", metric_cpu_idx, 0, 0 ); /**********************************************************************/ /* Add the rocksdb tile to topo */ /**********************************************************************/ fd_topob_wksp( topo, "rocksdb" ); - fd_topo_tile_t * rocksdb_tile = fd_topob_tile( topo, "arch_b", "rocksdb", "metric_in", rocksdb_cpu_idx, 0, 0 ); - rocksdb_tile->archiver.end_slot = config->tiles.archiver.end_slot; - strncpy( rocksdb_tile->archiver.archiver_path, config->tiles.archiver.archiver_path, PATH_MAX ); - if( FD_UNLIKELY( 0==strlen( rocksdb_tile->archiver.archiver_path ) ) ) { - FD_LOG_ERR(( "Rocksdb not found, check `archiver.archiver_path` in toml" )); - } else { - FD_LOG_NOTICE(( "Found rocksdb path from config: %s", rocksdb_tile->archiver.archiver_path )); - } + fd_topo_tile_t * rocksdb_tile = fd_topob_tile( topo, "arch_b", "rocksdb", "metric_in", rocksdb_cpu_idx, 0, 0 ); /**********************************************************************/ /* Add the replay tile to topo */ /**********************************************************************/ fd_topob_wksp( topo, "replay" ); fd_topo_tile_t * replay_tile = fd_topob_tile( topo, "replay", "replay", "metric_in", replay_cpu_idx, 0, 0 ); - replay_tile->replay.fec_max = config->tiles.shred.max_pending_shred_sets; - replay_tile->replay.max_vote_accounts = config->firedancer.runtime.limits.max_vote_accounts; - - /* specified by [tiles.replay] */ - - strncpy( replay_tile->replay.blockstore_file, config->firedancer.blockstore.file, sizeof(replay_tile->replay.blockstore_file) ); - strncpy( replay_tile->replay.blockstore_checkpt, config->firedancer.blockstore.checkpt, sizeof(replay_tile->replay.blockstore_checkpt) ); - - replay_tile->replay.tx_metadata_storage = config->rpc.extended_tx_metadata_storage; - strncpy( replay_tile->replay.capture, config->tiles.replay.capture, sizeof(replay_tile->replay.capture) ); - strncpy( replay_tile->replay.funk_checkpt, config->tiles.replay.funk_checkpt, sizeof(replay_tile->replay.funk_checkpt) ); - replay_tile->replay.funk_rec_max = config->tiles.replay.funk_rec_max; - replay_tile->replay.funk_sz_gb = config->tiles.replay.funk_sz_gb; - replay_tile->replay.funk_txn_max = config->tiles.replay.funk_txn_max; - strncpy( replay_tile->replay.funk_file, config->tiles.replay.funk_file, sizeof(replay_tile->replay.funk_file) ); - replay_tile->replay.plugins_enabled = config->tiles.gui.enabled; - - if( FD_UNLIKELY( !strncmp( config->tiles.replay.genesis, "", 1 ) - && !strncmp( config->tiles.replay.snapshot, "", 1 ) ) ) { - fd_cstr_printf_check( config->tiles.replay.genesis, PATH_MAX, NULL, "%s/genesis.bin", config->paths.ledger ); - } - strncpy( replay_tile->replay.genesis, config->tiles.replay.genesis, sizeof(replay_tile->replay.genesis) ); - - setup_snapshots( config, replay_tile ); - - strncpy( replay_tile->replay.slots_replayed, config->tiles.replay.slots_replayed, sizeof(replay_tile->replay.slots_replayed) ); - strncpy( replay_tile->replay.status_cache, config->tiles.replay.status_cache, sizeof(replay_tile->replay.status_cache) ); - strncpy( replay_tile->replay.cluster_version, config->tiles.replay.cluster_version, sizeof(replay_tile->replay.cluster_version) ); - replay_tile->replay.bank_tile_count = config->layout.bank_tile_count; - replay_tile->replay.exec_tile_count = config->firedancer.layout.exec_tile_count; - replay_tile->replay.writer_tile_cuont = config->firedancer.layout.writer_tile_count; - strncpy( replay_tile->replay.tower_checkpt, config->tiles.replay.tower_checkpt, sizeof(replay_tile->replay.tower_checkpt) ); - - replay_tile->replay.enable_features_cnt = config->tiles.replay.enable_features_cnt; - for( ulong i = 0; i < replay_tile->replay.enable_features_cnt; i++ ) { - strncpy( replay_tile->replay.enable_features[i], config->tiles.replay.enable_features[i], sizeof(replay_tile->replay.enable_features[i]) ); - } - - /* not specified by [tiles.replay] */ - - strncpy( replay_tile->replay.identity_key_path, config->paths.identity_key, sizeof(replay_tile->replay.identity_key_path) ); - replay_tile->replay.ip_addr = config->net.ip_addr; - replay_tile->replay.vote = config->firedancer.consensus.vote; - strncpy( replay_tile->replay.vote_account_path, config->paths.vote_account, sizeof(replay_tile->replay.vote_account_path) ); - replay_tile->replay.full_interval = config->tiles.batch.full_interval; - replay_tile->replay.incremental_interval = config->tiles.batch.incremental_interval; /**********************************************************************/ /* Add the executor tiles to topo */ @@ -397,7 +229,7 @@ backtest_topo( config_t * config ) { } /* root_slot_obj shared by replay and rocksdb tiles */ - fd_topob_wksp( topo, "root_slot" ); + fd_topob_wksp( topo, "root_slot" ); fd_topo_obj_t * root_slot_obj = fd_topob_obj( topo, "fseq", "root_slot" ); fd_topob_tile_uses( topo, replay_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_WRITE ); fd_topob_tile_uses( topo, rocksdb_tile, root_slot_obj, FD_SHMEM_JOIN_MODE_READ_ONLY ); @@ -427,6 +259,29 @@ backtest_topo( config_t * config ) { fd_topob_tile_uses( topo, replay_tile, constipated_obj, FD_SHMEM_JOIN_MODE_READ_WRITE ); FD_TEST( fd_pod_insertf_ulong( topo->props, constipated_obj->id, "constipate" ) ); + for( ulong i=0UL; itile_cnt; i++ ) { + fd_topo_tile_t * tile = &topo->tiles[ i ]; + if( !strcmp( tile->name, "rocksdb" ) ) { + tile->archiver.end_slot = config->tiles.archiver.end_slot; + strncpy( tile->archiver.archiver_path, config->tiles.archiver.archiver_path, PATH_MAX ); + if( FD_UNLIKELY( 0==strlen( tile->archiver.archiver_path ) ) ) { + FD_LOG_ERR(( "Rocksdb not found, check `archiver.archiver_path` in toml" )); + } else { + FD_LOG_NOTICE(( "Found rocksdb path from config: %s", tile->archiver.archiver_path )); + } + } else if( !fd_topo_configure_tile( tile, config ) ) { + FD_LOG_ERR(( "unknown tile name %lu `%s`", i, tile->name )); + } + + /* Override */ + if( !strcmp( tile->name, "replay" ) ) { + tile->replay.enable_features_cnt = config->tiles.replay.enable_features_cnt; + for( ulong i = 0; i < tile->replay.enable_features_cnt; i++ ) { + strncpy( tile->replay.enable_features[i], config->tiles.replay.enable_features[i], sizeof(tile->replay.enable_features[i]) ); + } + } + } + /**********************************************************************/ /* Finish and print out the topo information */ /**********************************************************************/ @@ -436,7 +291,7 @@ backtest_topo( config_t * config ) { static void backtest_cmd_fn( args_t * args FD_PARAM_UNUSED, - config_t * config ) { + config_t * config ) { FD_LOG_NOTICE(( "Start to run the backtest cmd" )); backtest_topo( config ); @@ -459,13 +314,13 @@ backtest_cmd_fn( args_t * args FD_PARAM_UNUSED, static void backtest_cmd_perm( args_t * args FD_PARAM_UNUSED, - fd_cap_chk_t * chk FD_PARAM_UNUSED, - config_t const * config FD_PARAM_UNUSED ) {} + fd_cap_chk_t * chk FD_PARAM_UNUSED, + config_t const * config FD_PARAM_UNUSED ) {} static void backtest_cmd_args( int * pargc FD_PARAM_UNUSED, - char *** pargv FD_PARAM_UNUSED, - args_t * args FD_PARAM_UNUSED ) {} + char *** pargv FD_PARAM_UNUSED, + args_t * args FD_PARAM_UNUSED ) {} action_t fd_action_backtest = { .name = "backtest", diff --git a/src/app/firedancer-dev/commands/sim.c b/src/app/firedancer-dev/commands/sim.c index 0417dfc3fe..1b084e3968 100644 --- a/src/app/firedancer-dev/commands/sim.c +++ b/src/app/firedancer-dev/commands/sim.c @@ -17,78 +17,17 @@ a notification for the previous frag from storei_notif. */ +#include "../../firedancer/topology.h" #include "../../shared/commands/run/run.h" /* initialize_workspaces */ -#include "../../shared/fd_config.h" /* config_t */ #include "../../../disco/topo/fd_cpu_topo.h" /* fd_topo_cpus */ #include "../../../disco/topo/fd_topob.h" #include "../../../disco/topo/fd_pod_format.h" -#include "../../../flamenco/runtime/fd_runtime.h" #include "../../../flamenco/runtime/fd_txncache.h" #include /* pause */ extern fd_topo_obj_callbacks_t * CALLBACKS[]; fd_topo_run_tile_t fdctl_tile_run( fd_topo_tile_t const * tile ); -/* setup_topo_txncache, setup_topo_runtime_pub and setup_topo_blockstore - are simply copied from fd_firedancer.c */ -static fd_topo_obj_t * -setup_topo_txncache( fd_topo_t * topo, - char const * wksp_name, - ulong max_rooted_slots, - ulong max_live_slots, - ulong max_txn_per_slot, - ulong max_constipated_slots ) { - fd_topo_obj_t * obj = fd_topob_obj( topo, "txncache", wksp_name ); - - FD_TEST( fd_pod_insertf_ulong( topo->props, max_rooted_slots, "obj.%lu.max_rooted_slots", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, max_live_slots, "obj.%lu.max_live_slots", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, max_txn_per_slot, "obj.%lu.max_txn_per_slot", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, max_constipated_slots, "obj.%lu.max_constipated_slots", obj->id ) ); - - return obj; -} - -static fd_topo_obj_t * -setup_topo_runtime_pub( fd_topo_t * topo, - char const * wksp_name, - ulong mem_max ) { - fd_topo_obj_t * obj = fd_topob_obj( topo, "runtime_pub", wksp_name ); - FD_TEST( fd_pod_insertf_ulong( topo->props, mem_max, "obj.%lu.mem_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, 12UL, "obj.%lu.wksp_tag", obj->id ) ); - return obj; -} - -#include -#include "../../../flamenco/runtime/fd_blockstore.h" -static fd_topo_obj_t * -setup_topo_blockstore( fd_topo_t * topo, - char const * wksp_name, - ulong shred_max, - ulong block_max, - ulong idx_max, - ulong txn_max, - ulong alloc_max ) { - fd_topo_obj_t * obj = fd_topob_obj( topo, "blockstore", wksp_name ); - - ulong seed; - FD_TEST( sizeof(ulong) == getrandom( &seed, sizeof(ulong), 0 ) ); - - FD_TEST( fd_pod_insertf_ulong( topo->props, 1UL, "obj.%lu.wksp_tag", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, seed, "obj.%lu.seed", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, shred_max, "obj.%lu.shred_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, block_max, "obj.%lu.block_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, idx_max, "obj.%lu.idx_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, txn_max, "obj.%lu.txn_max", obj->id ) ); - FD_TEST( fd_pod_insertf_ulong( topo->props, alloc_max, "obj.%lu.alloc_max", obj->id ) ); - - /* DO NOT MODIFY LOOSE WITHOUT CHANGING HOW BLOCKSTORE ALLOCATES INTERNAL STRUCTURES */ - - ulong blockstore_footprint = fd_blockstore_footprint( shred_max, block_max, idx_max, txn_max ) + alloc_max; - FD_TEST( fd_pod_insertf_ulong( topo->props, blockstore_footprint, "obj.%lu.loose", obj->id ) ); - - return obj; -} - static void sim_topo( config_t * config ) { fd_topo_cpus_t cpus[1]; @@ -106,95 +45,24 @@ sim_topo( config_t * config ) { static_end_idx, }; - /**********************************************************************/ - /* Add the metric tile to topo */ - /**********************************************************************/ fd_topob_wksp( topo, "metric" ); fd_topob_wksp( topo, "metric_in" ); - fd_topo_tile_t * metric_tile = fd_topob_tile( topo, "metric", "metric", "metric_in", metric_cpu_idx, 0, 0 ); - if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( config->tiles.metric.prometheus_listen_address, &metric_tile->metric.prometheus_listen_addr ) ) ) - FD_LOG_ERR(( "failed to parse prometheus listen address `%s`", config->tiles.metric.prometheus_listen_address )); - metric_tile->metric.prometheus_listen_port = config->tiles.metric.prometheus_listen_port; + fd_topob_tile( topo, "metric", "metric", "metric_in", metric_cpu_idx, 0, 0 ); - /**********************************************************************/ - /* Add the playback tile to topo */ - /**********************************************************************/ fd_topob_wksp( topo, "playback" ); - fd_topo_tile_t * playback_tile = fd_topob_tile( topo, "arch_p", "playback", "metric_in", playback_cpu_idx, 0, 0 ); - strncpy( playback_tile->archiver.archiver_path, config->tiles.archiver.archiver_path, PATH_MAX ); - if( FD_UNLIKELY( 0==strlen( playback_tile->archiver.archiver_path ) ) ) { - FD_LOG_ERR(( "Archive file not found for playback" )); - } else { - FD_LOG_NOTICE(( "Found archive file from config: %s", playback_tile->archiver.archiver_path )); - } + fd_topob_tile( topo, "arch_p", "playback", "metric_in", playback_cpu_idx, 0, 0 ); - /**********************************************************************/ - /* Add the storei tile to topo */ - /**********************************************************************/ fd_topob_wksp( topo, "storei" ); fd_topo_tile_t * storei_tile = fd_topob_tile( topo, "storei", "storei", "metric_in", storei_cpu_idx, 0, 0 ); - strncpy( storei_tile->store_int.blockstore_file, config->firedancer.blockstore.file, sizeof(storei_tile->store_int.blockstore_file) ); - strncpy( storei_tile->store_int.blockstore_restore, config->firedancer.blockstore.restore, sizeof(storei_tile->store_int.blockstore_restore) ); - strncpy( storei_tile->store_int.identity_key_path, config->paths.identity_key, sizeof(storei_tile->store_int.identity_key_path) ); - strncpy( storei_tile->store_int.slots_pending, config->tiles.store_int.slots_pending, sizeof( storei_tile->store_int.slots_pending ) ); - strncpy( storei_tile->store_int.shred_cap_archive, config->tiles.store_int.shred_cap_archive, sizeof(storei_tile->store_int.shred_cap_archive) ); - strncpy( storei_tile->store_int.shred_cap_replay, config->tiles.store_int.shred_cap_replay, sizeof(storei_tile->store_int.shred_cap_replay) ); - storei_tile->store_int.shred_cap_end_slot = config->tiles.store_int.shred_cap_end_slot; - storei_tile->store_int.expected_shred_version = config->consensus.expected_shred_version; - /**********************************************************************/ - /* Add the replay tile to topo */ - /**********************************************************************/ fd_topob_wksp( topo, "replay" ); fd_topo_tile_t * replay_tile = fd_topob_tile( topo, "replay", "replay", "metric_in", replay_cpu_idx, 0, 0 ); - replay_tile->replay.fec_max = config->tiles.shred.max_pending_shred_sets; - replay_tile->replay.max_vote_accounts = config->firedancer.runtime.limits.max_vote_accounts; - - /* specified by [tiles.replay] */ - strncpy( replay_tile->replay.blockstore_file, config->firedancer.blockstore.file, sizeof(replay_tile->replay.blockstore_file) ); - strncpy( replay_tile->replay.blockstore_checkpt, config->firedancer.blockstore.checkpt, sizeof(replay_tile->replay.blockstore_checkpt) ); - - replay_tile->replay.tx_metadata_storage = config->rpc.extended_tx_metadata_storage; - strncpy( replay_tile->replay.capture, config->tiles.replay.capture, sizeof(replay_tile->replay.capture) ); - strncpy( replay_tile->replay.funk_checkpt, config->tiles.replay.funk_checkpt, sizeof(replay_tile->replay.funk_checkpt) ); - replay_tile->replay.funk_rec_max = config->tiles.replay.funk_rec_max; - replay_tile->replay.funk_sz_gb = config->tiles.replay.funk_sz_gb; - replay_tile->replay.funk_txn_max = config->tiles.replay.funk_txn_max; - strncpy( replay_tile->replay.funk_file, config->tiles.replay.funk_file, sizeof(replay_tile->replay.funk_file) ); - replay_tile->replay.plugins_enabled = 0; - - if( FD_UNLIKELY( !strncmp( config->tiles.replay.genesis, "", 1 ) - && !strncmp( config->tiles.replay.snapshot, "", 1 ) ) ) { - fd_cstr_printf_check( config->tiles.replay.genesis, PATH_MAX, NULL, "%s/genesis.bin", config->paths.ledger ); - } - strncpy( replay_tile->replay.genesis, config->tiles.replay.genesis, sizeof(replay_tile->replay.genesis) ); - - strncpy( replay_tile->replay.incremental, config->tiles.replay.incremental, sizeof(replay_tile->replay.incremental) ); - strncpy( replay_tile->replay.slots_replayed, config->tiles.replay.slots_replayed, sizeof(replay_tile->replay.slots_replayed) ); - strncpy( replay_tile->replay.snapshot, config->tiles.replay.snapshot, sizeof(replay_tile->replay.snapshot) ); - strncpy( replay_tile->replay.status_cache, config->tiles.replay.status_cache, sizeof(replay_tile->replay.status_cache) ); - - strncpy( replay_tile->replay.cluster_version, config->tiles.replay.cluster_version, sizeof(replay_tile->replay.cluster_version) ); - replay_tile->replay.bank_tile_count = config->layout.bank_tile_count; - replay_tile->replay.exec_tile_count = config->firedancer.layout.exec_tile_count; - strncpy( replay_tile->replay.tower_checkpt, config->tiles.replay.tower_checkpt, sizeof(replay_tile->replay.tower_checkpt) ); - - /* not specified by [tiles.replay] */ - strncpy( replay_tile->replay.identity_key_path, config->paths.identity_key, sizeof(replay_tile->replay.identity_key_path) ); - replay_tile->replay.ip_addr = config->net.ip_addr; - replay_tile->replay.vote = config->firedancer.consensus.vote; - strncpy( replay_tile->replay.vote_account_path, config->paths.vote_account, sizeof(replay_tile->replay.vote_account_path) ); - replay_tile->replay.full_interval = config->tiles.batch.full_interval; - replay_tile->replay.incremental_interval = config->tiles.batch.incremental_interval; #define FOR(cnt) for( ulong i=0UL; ifiredancer.layout.exec_tile_count; - FOR(exec_tile_cnt) fd_topob_tile( topo, "exec", "exec", "metric_in", static_end_idx+i, 0, 0 ); + ulong exec_tile_cnt = config->firedancer.layout.exec_tile_count; + FOR(exec_tile_cnt) fd_topob_tile( topo, "exec", "exec", "metric_in", static_end_idx+i, 0, 0 ); /**********************************************************************/ /* Setup playback<->storei and storei<->replay links in topo */ @@ -307,6 +175,28 @@ sim_topo( config_t * config ) { FD_TEST( fd_pod_insertf_ulong( topo->props, exec_fseq_obj->id, "exec_fseq.%lu", i ) ); } + for( ulong i=0UL; itile_cnt; i++ ) { + fd_topo_tile_t * tile = &topo->tiles[ i ]; + if( !strcmp( tile->name, "arch_p" ) ) { + strncpy( tile->archiver.archiver_path, config->tiles.archiver.archiver_path, PATH_MAX ); + if( FD_UNLIKELY( 0==strlen( tile->archiver.archiver_path ) ) ) { + FD_LOG_ERR(( "Archive file not found for playback" )); + } else { + FD_LOG_NOTICE(( "Found archive file from config: %s", tile->archiver.archiver_path )); + } + } else if( !fd_topo_configure_tile( tile, config ) ) { + FD_LOG_ERR(( "unknown tile name %lu `%s`", i, tile->name )); + } + + /* Override */ + if( !strcmp( tile->name, "replay" ) ) { + strncpy( tile->replay.incremental, config->tiles.replay.incremental, sizeof(tile->replay.incremental) ); + strncpy( tile->replay.slots_replayed, config->tiles.replay.slots_replayed, sizeof(tile->replay.slots_replayed) ); + strncpy( tile->replay.snapshot, config->tiles.replay.snapshot, sizeof(tile->replay.snapshot) ); + strncpy( tile->replay.status_cache, config->tiles.replay.status_cache, sizeof(tile->replay.status_cache) ); + } + } + /**********************************************************************/ /* Finish and print out the topo information */ /**********************************************************************/ diff --git a/src/app/firedancer/topology.c b/src/app/firedancer/topology.c index 4e4217d5f0..ff8c116594 100644 --- a/src/app/firedancer/topology.c +++ b/src/app/firedancer/topology.c @@ -1,4 +1,4 @@ -#include "../shared/fd_config.h" +#include "topology.h" #include "../../discof/geyser/fd_replay_notif.h" #include "../../disco/net/fd_net_tile.h" @@ -8,8 +8,6 @@ #include "../../disco/topo/fd_cpu_topo.h" #include "../../disco/topo/fd_pod_format.h" #include "../../flamenco/runtime/fd_blockstore.h" -#include "../../flamenco/runtime/fd_runtime.h" -#include "../../flamenco/runtime/fd_runtime_public.h" #include "../../flamenco/runtime/fd_txncache.h" #include "../../flamenco/snapshot/fd_snapshot_base.h" #include "../../util/tile/fd_tile_private.h" @@ -21,14 +19,14 @@ extern fd_topo_obj_callbacks_t * CALLBACKS[]; -static fd_topo_obj_t * +fd_topo_obj_t * setup_topo_blockstore( fd_topo_t * topo, - char const * wksp_name, - ulong shred_max, - ulong block_max, - ulong idx_max, - ulong txn_max, - ulong alloc_max ) { + char const * wksp_name, + ulong shred_max, + ulong block_max, + ulong idx_max, + ulong txn_max, + ulong alloc_max ) { fd_topo_obj_t * obj = fd_topob_obj( topo, "blockstore", wksp_name ); ulong seed; @@ -50,7 +48,7 @@ setup_topo_blockstore( fd_topo_t * topo, return obj; } -static fd_topo_obj_t * +fd_topo_obj_t * setup_topo_runtime_pub( fd_topo_t * topo, char const * wksp_name, ulong mem_max ) { @@ -60,13 +58,13 @@ setup_topo_runtime_pub( fd_topo_t * topo, return obj; } -static fd_topo_obj_t * +fd_topo_obj_t * setup_topo_txncache( fd_topo_t * topo, - char const * wksp_name, - ulong max_rooted_slots, - ulong max_live_slots, - ulong max_txn_per_slot, - ulong max_constipated_slots ) { + char const * wksp_name, + ulong max_rooted_slots, + ulong max_live_slots, + ulong max_txn_per_slot, + ulong max_constipated_slots ) { fd_topo_obj_t * obj = fd_topob_obj( topo, "txncache", wksp_name ); FD_TEST( fd_pod_insertf_ulong( topo->props, max_rooted_slots, "obj.%lu.max_rooted_slots", obj->id ) ); @@ -77,6 +75,29 @@ setup_topo_txncache( fd_topo_t * topo, return obj; } +fd_topo_obj_t * +setup_topo_funk( fd_topo_t * topo, + char const * wksp_name, + ulong max_account_records, + ulong max_database_transactions ) { + fd_topo_obj_t * obj = fd_topob_obj( topo, "funk", wksp_name ); + FD_TEST( fd_pod_insert_ulong( topo->props, "funk", obj->id ) ); + FD_TEST( fd_pod_insertf_ulong( topo->props, max_account_records, "obj.%lu.rec_max", obj->id ) ); + FD_TEST( fd_pod_insertf_ulong( topo->props, max_database_transactions, "obj.%lu.txn_max", obj->id ) ); + ulong funk_footprint = fd_funk_footprint( max_database_transactions, max_account_records ); + if( FD_UNLIKELY( !funk_footprint ) ) FD_LOG_ERR(( "Invalid [funk] parameters" )); + + /* Increase workspace partition count */ + ulong wksp_idx = fd_topo_find_wksp( topo, wksp_name ); + FD_TEST( wksp_idx!=ULONG_MAX ); + fd_topo_wksp_t * wksp = &topo->workspaces[ wksp_idx ]; + ulong part_max = fd_wksp_part_max_est( funk_footprint, 1U<<18U ); + if( FD_UNLIKELY( !part_max ) ) FD_LOG_ERR(( "fd_wksp_part_max_est(%lu,256KiB) failed", funk_footprint )); + wksp->part_max += part_max; + + return obj; +} + static int resolve_gossip_entrypoint( char const * host_port, fd_ip4_port_t * ip4_port ) { @@ -761,7 +782,40 @@ fd_topo_initialize( config_t * config ) { for( ulong i=0UL; itile_cnt; i++ ) { fd_topo_tile_t * tile = &topo->tiles[ i ]; + if( !fd_topo_configure_tile( tile, config ) ) { + FD_LOG_ERR(( "unknown tile name %lu `%s`", i, tile->name )); + } + } + + if( FD_UNLIKELY( is_auto_affinity ) ) fd_topob_auto_layout( topo, 0 ); + + fd_topob_finish( topo, CALLBACKS ); + FD_TEST( blockstore_obj->id ); + + const char * status_cache = config->tiles.replay.status_cache; + if ( strlen( status_cache ) > 0 ) { + /* Make the status cache workspace match the parameters used to create the + checkpoint. This is a bit nonintuitive because of the way + fd_topo_create_workspace works. */ + fd_wksp_preview_t preview[1]; + int err = fd_wksp_preview( status_cache, preview ); + if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "unable to preview %s: error %d", status_cache, err )); + fd_topo_wksp_t * wksp = &topo->workspaces[ topo->objs[ txncache_obj->id ].wksp_id ]; + wksp->part_max = preview->part_max; + wksp->known_footprint = 0; + wksp->total_footprint = preview->data_max; + ulong page_sz = FD_SHMEM_GIGANTIC_PAGE_SZ; + wksp->page_sz = page_sz; + ulong footprint = fd_wksp_footprint( preview->part_max, preview->data_max ); + wksp->page_cnt = footprint / page_sz; + } + config->topo = *topo; +} + +int +fd_topo_configure_tile( fd_topo_tile_t * tile, + fd_config_t * config ) { if( FD_UNLIKELY( !strcmp( tile->name, "net" ) || !strcmp( tile->name, "sock" ) ) ) { tile->net.shred_listen_port = config->tiles.shred.shred_listen_port; @@ -795,7 +849,7 @@ fd_topo_initialize( config_t * config ) { } else if( FD_UNLIKELY( !strcmp( tile->name, "shred" ) ) ) { strncpy( tile->shred.identity_key_path, config->paths.identity_key, sizeof(tile->shred.identity_key_path) ); - tile->shred.depth = topo->links[ tile->out_link_id[ 0 ] ].depth; + tile->shred.depth = config->topo.links[ tile->out_link_id[ 0 ] ].depth; tile->shred.fec_resolver_depth = config->tiles.shred.max_pending_shred_sets; tile->shred.expected_shred_version = config->consensus.expected_shred_version; tile->shred.shred_listen_port = config->tiles.shred.shred_listen_port; @@ -828,7 +882,6 @@ fd_topo_initialize( config_t * config ) { } else if( FD_UNLIKELY( !strcmp( tile->name, "repair" ) ) ) { tile->repair.max_pending_shred_sets = config->tiles.shred.max_pending_shred_sets; - tile->repair.shred_tile_cnt = config->layout.shred_tile_count; tile->repair.repair_intake_listen_port = config->tiles.repair.repair_intake_listen_port; tile->repair.repair_serve_listen_port = config->tiles.repair.repair_serve_listen_port; strncpy( tile->repair.good_peer_cache_file, config->tiles.repair.good_peer_cache_file, sizeof(tile->repair.good_peer_cache_file) ); @@ -852,11 +905,11 @@ fd_topo_initialize( config_t * config ) { tile->replay.funk_sz_gb = config->tiles.replay.funk_sz_gb; tile->replay.funk_txn_max = config->tiles.replay.funk_txn_max; strncpy( tile->replay.funk_file, config->tiles.replay.funk_file, sizeof(tile->replay.funk_file) ); - tile->replay.plugins_enabled = plugins_enabled; + tile->replay.plugins_enabled = fd_topo_find_tile( &config->topo, "plugin", 0UL ) != ULONG_MAX; if( FD_UNLIKELY( !strncmp( config->tiles.replay.genesis, "", 1 ) && !strncmp( config->tiles.replay.snapshot, "", 1 ) ) ) { - fd_cstr_printf_check( config->tiles.replay.genesis, PATH_MAX, NULL, "%s/genesis.bin", config->paths.ledger ); + fd_cstr_printf_check( config->tiles.replay.genesis, PATH_MAX, NULL, "%s/genesis.bin", config->paths.ledger ); } strncpy( tile->replay.genesis, config->tiles.replay.genesis, sizeof(tile->replay.genesis) ); @@ -865,9 +918,6 @@ fd_topo_initialize( config_t * config ) { strncpy( tile->replay.slots_replayed, config->tiles.replay.slots_replayed, sizeof(tile->replay.slots_replayed) ); strncpy( tile->replay.status_cache, config->tiles.replay.status_cache, sizeof(tile->replay.status_cache) ); strncpy( tile->replay.cluster_version, config->tiles.replay.cluster_version, sizeof(tile->replay.cluster_version) ); - tile->replay.bank_tile_count = config->layout.bank_tile_count; - tile->replay.exec_tile_count = config->firedancer.layout.exec_tile_count; - tile->replay.writer_tile_cuont = config->firedancer.layout.writer_tile_count; strncpy( tile->replay.tower_checkpt, config->tiles.replay.tower_checkpt, sizeof(tile->replay.tower_checkpt) ); /* not specified by [tiles.replay] */ @@ -946,34 +996,9 @@ fd_topo_initialize( config_t * config ) { tile->restart.heap_mem_max = config->firedancer.runtime.heap_size_gib<<30; } else if( FD_UNLIKELY( !strcmp( tile->name, "arch_f" ) || !strcmp( tile->name, "arch_w" ) ) ) { - tile->archiver.enabled = config->tiles.archiver.enabled; strncpy( tile->archiver.archiver_path, config->tiles.archiver.archiver_path, sizeof(tile->archiver.archiver_path) ); } else { - FD_LOG_ERR(( "unknown tile name %lu `%s`", i, tile->name )); + return 0; } - } - - if( FD_UNLIKELY( is_auto_affinity ) ) fd_topob_auto_layout( topo, 0 ); - - fd_topob_finish( topo, CALLBACKS ); - - const char * status_cache = config->tiles.replay.status_cache; - if ( strlen( status_cache ) > 0 ) { - /* Make the status cache workspace match the parameters used to create the - checkpoint. This is a bit nonintuitive because of the way - fd_topo_create_workspace works. */ - fd_wksp_preview_t preview[1]; - int err = fd_wksp_preview( status_cache, preview ); - if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "unable to preview %s: error %d", status_cache, err )); - fd_topo_wksp_t * wksp = &topo->workspaces[ topo->objs[ txncache_obj->id ].wksp_id ]; - wksp->part_max = preview->part_max; - wksp->known_footprint = 0; - wksp->total_footprint = preview->data_max; - ulong page_sz = FD_SHMEM_GIGANTIC_PAGE_SZ; - wksp->page_sz = page_sz; - ulong footprint = fd_wksp_footprint( preview->part_max, preview->data_max ); - wksp->page_cnt = footprint / page_sz; - } - - config->topo = *topo; + return 1; } diff --git a/src/app/firedancer/topology.h b/src/app/firedancer/topology.h index f998c9b847..3f213b1eba 100644 --- a/src/app/firedancer/topology.h +++ b/src/app/firedancer/topology.h @@ -1,12 +1,49 @@ #ifndef HEADER_fd_src_app_firedancer_topology_h #define HEADER_fd_src_app_firedancer_topology_h +/* topology.h contains APIs for constructing a Firedancer topology. */ + #include "../shared/fd_config.h" FD_PROTOTYPES_BEGIN +/* fd_topo_initialize constructs a full validator config according to + the given topology. Populates config->topo. */ + void -fd_topo_initialize( config_t * config ); +fd_topo_initialize( fd_config_t * config ); + +fd_topo_obj_t * +setup_topo_blockstore( fd_topo_t * topo, + char const * wksp_name, + ulong shred_max, + ulong block_max, + ulong idx_max, + ulong txn_max, + ulong alloc_max ); + +fd_topo_obj_t * +setup_topo_runtime_pub( fd_topo_t * topo, + char const * wksp_name, + ulong mem_max ); + +fd_topo_obj_t * +setup_topo_txncache( fd_topo_t * topo, + char const * wksp_name, + ulong max_rooted_slots, + ulong max_live_slots, + ulong max_txn_per_slot, + ulong max_constipated_slots ); + +fd_topo_obj_t * +setup_topo_funk( fd_topo_t * topo, + char const * wksp_name, + ulong max_account_records, + ulong max_database_transactions ); + +int +fd_topo_configure_tile( fd_topo_tile_t * tile, + fd_config_t * config ); FD_PROTOTYPES_END diff --git a/src/disco/topo/fd_topo.h b/src/disco/topo/fd_topo.h index 6c91f3dbb0..2428a87b19 100644 --- a/src/disco/topo/fd_topo.h +++ b/src/disco/topo/fd_topo.h @@ -292,9 +292,6 @@ typedef struct { uint ip_addr; int vote; char vote_account_path[ PATH_MAX ]; - ulong bank_tile_count; - ulong exec_tile_count; - ulong writer_tile_cuont; ulong full_interval; ulong incremental_interval; @@ -373,7 +370,6 @@ typedef struct { int good_peer_cache_file_fd; char identity_key_path[ PATH_MAX ]; ulong max_pending_shred_sets; - uint shred_tile_cnt; } repair; struct { @@ -427,7 +423,6 @@ typedef struct { } pktgen; struct { - int enabled; ulong end_slot; char archiver_path[ PATH_MAX ]; @@ -515,10 +510,13 @@ fd_topo_workspace_align( void ) { return 4096UL; } -FD_FN_PURE static inline void * +static inline void * fd_topo_obj_laddr( fd_topo_t const * topo, ulong obj_id ) { fd_topo_obj_t const * obj = &topo->objs[ obj_id ]; + FD_TEST( obj_idid == obj_id ); + FD_TEST( obj->offset ); return (void *)((ulong)topo->workspaces[ obj->wksp_id ].wksp + obj->offset); } diff --git a/src/disco/topo/fd_topob.c b/src/disco/topo/fd_topob.c index bf994e7bf1..7d3849d7ad 100644 --- a/src/disco/topo/fd_topob.c +++ b/src/disco/topo/fd_topob.c @@ -602,7 +602,9 @@ fd_topob_finish( fd_topo_t * topo, if( FD_UNLIKELY( cb->loose ) ) loose_sz += cb->loose( topo, obj ); } - ulong part_max = 3UL + (loose_sz / (64UL << 10)); /* 3 for initial alignment + actual alloc + residual padding */ + ulong part_max = wksp->part_max; + if( !part_max ) part_max = (loose_sz / (64UL << 10)); /* alloc + residual padding */ + part_max += 3; /* for initial alignment */ ulong offset = fd_ulong_align_up( fd_wksp_private_data_off( part_max ), fd_topo_workspace_align() ); for( ulong j=0UL; jobj_cnt; j++ ) { diff --git a/src/discof/repair/fd_repair_tile.c b/src/discof/repair/fd_repair_tile.c index a9f1afb53c..418efdabc1 100644 --- a/src/discof/repair/fd_repair_tile.c +++ b/src/discof/repair/fd_repair_tile.c @@ -1339,7 +1339,7 @@ unprivileged_init( fd_topo_t * topo, } if( FD_UNLIKELY( sign_link_out_idx==UINT_MAX ) ) FD_LOG_ERR(( "Missing gossip_sign link" )); ctx->shred_tile_cnt = shred_tile_idx; - FD_TEST( ctx->shred_tile_cnt == tile->repair.shred_tile_cnt ); + FD_TEST( ctx->shred_tile_cnt == fd_topo_tile_name_cnt( topo, "shred" ) ); /* Scratch mem setup */ diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index 239d24df58..60fa7cf2a1 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -2986,7 +2986,7 @@ unprivileged_init( fd_topo_t * topo, /**********************************************************************/ /* Join each of the exec spads. */ - ctx->exec_cnt = tile->replay.exec_tile_count; + ctx->exec_cnt = fd_topo_tile_name_cnt( topo, "exec" ); for( ulong i=0UL; iexec_cnt; i++ ) { ulong exec_spad_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "exec_spad.%lu", i ); fd_spad_t * spad = fd_spad_join( fd_topo_obj_laddr( topo, exec_spad_id ) ); @@ -3083,8 +3083,8 @@ unprivileged_init( fd_topo_t * topo, /* bank */ /**********************************************************************/ - ctx->bank_cnt = tile->replay.bank_tile_count; - for( ulong i=0UL; ireplay.bank_tile_count; i++ ) { + ctx->bank_cnt = fd_topo_tile_name_cnt( topo, "bank" ); + for( ulong i=0UL; i<(ctx->bank_cnt); i++ ) { ulong busy_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "bank_busy.%lu", i ); FD_TEST( busy_obj_id!=ULONG_MAX ); ctx->bank_busy[ i ] = fd_fseq_join( fd_topo_obj_laddr( topo, busy_obj_id ) ); @@ -3109,7 +3109,7 @@ unprivileged_init( fd_topo_t * topo, /**********************************************************************/ /* exec */ /**********************************************************************/ - ctx->exec_cnt = tile->replay.exec_tile_count; + ctx->exec_cnt = fd_topo_tile_name_cnt( topo, "exec" ); if( FD_UNLIKELY( ctx->exec_cnt>FD_PACK_MAX_BANK_TILES ) ) { FD_LOG_ERR(( "replay tile has too many exec tiles %lu", ctx->exec_cnt )); } @@ -3153,7 +3153,7 @@ unprivileged_init( fd_topo_t * topo, /**********************************************************************/ /* writer */ /**********************************************************************/ - ctx->writer_cnt = tile->replay.writer_tile_cuont; + ctx->writer_cnt = fd_topo_tile_name_cnt( topo, "writer" ); if( FD_UNLIKELY( ctx->writer_cnt>FD_PACK_MAX_BANK_TILES ) ) { FD_LOG_CRIT(( "replay tile has too many writer tiles %lu", ctx->writer_cnt )); }