From 73f1f55db6d0163b942bcd628d51cf7cc5bf22eb Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 15:07:29 +0000 Subject: [PATCH 1/9] bank manager wip --- src/app/ledger/main.c | 72 ++- .../shared_dev/commands/configure/genesis.c | 8 +- src/choreo/epoch/fd_epoch.c | 15 +- src/choreo/epoch/fd_epoch.h | 5 +- src/choreo/forks/fd_forks.c | 23 +- src/discof/batch/fd_batch_tile.c | 16 +- src/discof/consensus/test_consensus.c | 6 +- src/discof/exec/fd_exec_tile.c | 47 +- src/discof/replay/fd_replay.c | 4 +- src/discof/replay/fd_replay_tile.c | 298 ++++++---- src/discof/restart/fd_restart_tile.c | 19 +- src/discof/rpcserver/fd_rpc_service.c | 10 +- src/flamenco/fd_flamenco_base.h | 4 + src/flamenco/features/Local.mk | 2 + src/flamenco/features/fd_features.c | 8 +- src/flamenco/features/fd_features.h | 8 +- src/flamenco/rewards/fd_rewards.c | 75 +-- src/flamenco/runtime/Local.mk | 3 + .../runtime/context/fd_exec_epoch_ctx.c | 12 +- .../runtime/context/fd_exec_epoch_ctx.h | 1 - .../runtime/context/fd_exec_slot_ctx.c | 328 ++++++++--- .../runtime/context/fd_exec_slot_ctx.h | 8 +- .../runtime/context/fd_exec_txn_ctx.c | 1 + .../runtime/context/fd_exec_txn_ctx.h | 73 +-- src/flamenco/runtime/fd_bank_mgr.c | 90 +++ src/flamenco/runtime/fd_bank_mgr.h | 145 +++++ src/flamenco/runtime/fd_blockstore.c | 15 +- src/flamenco/runtime/fd_blockstore.h | 6 +- src/flamenco/runtime/fd_blockstore_tool.c | 11 +- src/flamenco/runtime/fd_cost_tracker.c | 2 +- src/flamenco/runtime/fd_executor.c | 38 +- src/flamenco/runtime/fd_executor.h | 6 +- src/flamenco/runtime/fd_hashes.c | 184 +++--- src/flamenco/runtime/fd_hashes.h | 4 +- src/flamenco/runtime/fd_runtime.c | 528 +++++++++++------ src/flamenco/runtime/fd_runtime.h | 1 + src/flamenco/runtime/fd_runtime_init.c | 26 +- src/flamenco/runtime/fd_runtime_public.h | 12 +- src/flamenco/runtime/fd_txn_account_private.h | 2 + .../runtime/program/fd_bpf_program_util.c | 10 +- .../runtime/program/fd_builtin_programs.c | 32 +- .../runtime/program/fd_stake_program.c | 53 +- .../runtime/program/fd_system_program_nonce.c | 15 +- .../runtime/program/fd_vote_program.c | 55 +- src/flamenco/runtime/sysvar/fd_sysvar.c | 13 +- src/flamenco/runtime/sysvar/fd_sysvar_clock.c | 87 ++- .../runtime/sysvar/fd_sysvar_epoch_rewards.c | 6 +- .../runtime/sysvar/fd_sysvar_epoch_schedule.c | 2 +- src/flamenco/runtime/sysvar/fd_sysvar_fees.c | 59 +- src/flamenco/runtime/sysvar/fd_sysvar_fees.h | 1 - .../sysvar/fd_sysvar_last_restart_slot.c | 22 +- .../runtime/sysvar/fd_sysvar_recent_hashes.c | 81 ++- src/flamenco/runtime/sysvar/fd_sysvar_rent.c | 2 +- .../runtime/sysvar/fd_sysvar_slot_hashes.c | 6 +- .../runtime/sysvar/fd_sysvar_slot_history.c | 10 +- .../runtime/sysvar/fd_sysvar_stake_history.c | 2 +- src/flamenco/runtime/tests/fd_dump_pb.c | 91 +-- .../runtime/tests/harness/fd_block_harness.c | 171 ++++-- .../runtime/tests/harness/fd_harness_common.h | 1 + .../runtime/tests/harness/fd_instr_harness.c | 42 +- .../runtime/tests/harness/fd_txn_harness.c | 99 +++- src/flamenco/snapshot/fd_snapshot.c | 60 +- src/flamenco/snapshot/fd_snapshot_create.c | 84 +-- src/flamenco/stakes/fd_stakes.c | 60 +- src/flamenco/types/fd_fuzz_types.h | 51 +- src/flamenco/types/fd_types.c | 540 ++++++++---------- src/flamenco/types/fd_types.h | 196 +++++-- src/flamenco/types/fd_types.json | 51 +- .../types/fd_types_reflect_generated.c | 3 +- src/flamenco/types/gen_stubs.py | 46 +- .../vm/syscall/fd_vm_syscall_runtime.c | 4 +- src/flamenco/vm/test_vm_util.c | 5 +- src/funk/fd_funk_rec.c | 1 + src/funk/fd_funk_rec.h | 2 +- 74 files changed, 2605 insertions(+), 1474 deletions(-) create mode 100644 src/flamenco/runtime/fd_bank_mgr.c create mode 100644 src/flamenco/runtime/fd_bank_mgr.h diff --git a/src/app/ledger/main.c b/src/app/ledger/main.c index 11ca19ca44..7b1fcbe1bc 100644 --- a/src/app/ledger/main.c +++ b/src/app/ledger/main.c @@ -7,6 +7,7 @@ #include "../../flamenco/runtime/fd_runtime_public.h" #include "../../flamenco/runtime/fd_rocksdb.h" #include "../../flamenco/runtime/fd_txncache.h" +#include "../../flamenco/runtime/fd_bank_mgr.h" #include "../../flamenco/rewards/fd_rewards.h" #include "../../ballet/base58/fd_base58.h" #include "../../flamenco/runtime/context/fd_capture_ctx.h" @@ -291,7 +292,7 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { fd_features_restore( ledger_args->slot_ctx, ledger_args->runtime_spad ); - fd_runtime_update_leaders( ledger_args->slot_ctx, ledger_args->slot_ctx->slot_bank.slot, ledger_args->runtime_spad ); + fd_runtime_update_leaders( ledger_args->slot_ctx, ledger_args->slot_ctx->slot, ledger_args->runtime_spad ); fd_calculate_epoch_accounts_hash_values( ledger_args->slot_ctx ); @@ -300,8 +301,8 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { ulong slot_cnt = 0; fd_blockstore_t * blockstore = ledger_args->slot_ctx->blockstore; - ulong prev_slot = ledger_args->slot_ctx->slot_bank.slot; - ulong start_slot = ledger_args->slot_ctx->slot_bank.slot + 1; + ulong prev_slot = ledger_args->slot_ctx->slot; + ulong start_slot = ledger_args->slot_ctx->slot + 1; ledger_args->slot_ctx->root_slot = prev_slot; @@ -350,7 +351,6 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { for( ulong slot = start_slot; slot<=ledger_args->end_slot && !aborted; ++slot ) { ledger_args->slot_ctx->slot_bank.prev_slot = prev_slot; - ledger_args->slot_ctx->slot_bank.slot = slot; FD_LOG_DEBUG(( "reading slot %lu", slot )); @@ -405,10 +405,18 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { continue; } - ledger_args->slot_ctx->slot_bank.tick_height = ledger_args->slot_ctx->slot_bank.max_tick_height; - if( FD_UNLIKELY( FD_RUNTIME_EXECUTE_SUCCESS != fd_runtime_compute_max_tick_height( ledger_args->epoch_ctx->epoch_bank.ticks_per_slot, slot, &ledger_args->slot_ctx->slot_bank.max_tick_height ) ) ) { - FD_LOG_ERR(( "couldn't compute max tick height slot %lu ticks_per_slot %lu", slot, ledger_args->epoch_ctx->epoch_bank.ticks_per_slot )); + ulong * max_tick_height = fd_bank_mgr_max_tick_height_query( ledger_args->slot_ctx->bank_mgr ); + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( ledger_args->slot_ctx->bank_mgr ); + ulong * tick_height = fd_bank_mgr_tick_height_modify( ledger_args->slot_ctx->bank_mgr ); + *tick_height = *max_tick_height; + fd_bank_mgr_tick_height_save( ledger_args->slot_ctx->bank_mgr ); + + max_tick_height = fd_bank_mgr_max_tick_height_modify( ledger_args->slot_ctx->bank_mgr ); + + if( FD_UNLIKELY( FD_RUNTIME_EXECUTE_SUCCESS != fd_runtime_compute_max_tick_height( *ticks_per_slot, slot, max_tick_height ) ) ) { + FD_LOG_ERR(( "couldn't compute max tick height slot %lu ticks_per_slot %lu", slot, *ticks_per_slot )); } + fd_bank_mgr_max_tick_height_save( ledger_args->slot_ctx->bank_mgr ); if( ledger_args->slot_ctx->root_slot%ledger_args->snapshot_freq==0UL && !ledger_args->is_snapshotting ) { @@ -455,8 +463,9 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { } ulong blk_txn_cnt = 0UL; - FD_LOG_NOTICE(( "Used memory in spad before slot=%lu %lu", ledger_args->slot_ctx->slot_bank.slot, ledger_args->runtime_spad->mem_used )); + FD_LOG_NOTICE(( "Used memory in spad before slot=%lu %lu", slot, ledger_args->runtime_spad->mem_used )); FD_TEST( fd_runtime_block_eval_tpool( ledger_args->slot_ctx, + slot, blk, ledger_args->capture_ctx, ledger_args->tpool, @@ -471,11 +480,11 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { fd_hash_t expected; int err = fd_blockstore_block_hash_query( blockstore, slot, &expected ); if( FD_UNLIKELY( err ) ) FD_LOG_ERR( ( "slot %lu is missing its hash", slot ) ); - else if( FD_UNLIKELY( 0 != memcmp( ledger_args->slot_ctx->slot_bank.poh.hash, expected.hash, 32UL ) ) ) { + else if( FD_UNLIKELY( 0 != memcmp( fd_bank_mgr_poh_query( ledger_args->slot_ctx->bank_mgr )->hash, expected.hash, sizeof(fd_hash_t) ) ) ) { char expected_hash[ FD_BASE58_ENCODED_32_SZ ]; fd_acct_addr_cstr( expected_hash, expected.hash ); char poh_hash[ FD_BASE58_ENCODED_32_SZ ]; - fd_acct_addr_cstr( poh_hash, ledger_args->slot_ctx->slot_bank.poh.hash ); + fd_acct_addr_cstr( poh_hash, fd_bank_mgr_poh_query( ledger_args->slot_ctx->bank_mgr )->hash ); FD_LOG_WARNING(( "PoH hash mismatch! slot=%lu expected=%s, got=%s", slot, expected_hash, @@ -718,7 +727,7 @@ fd_ledger_main_setup( fd_ledger_args_t * args ) { /* Finish other runtime setup steps */ fd_features_restore( args->slot_ctx, args->runtime_spad ); - fd_runtime_update_leaders( args->slot_ctx, args->slot_ctx->slot_bank.slot, args->runtime_spad ); + fd_runtime_update_leaders( args->slot_ctx, args->slot_ctx->slot, args->runtime_spad ); fd_calculate_epoch_accounts_hash_values( args->slot_ctx ); fd_exec_para_cb_ctx_t exec_para_ctx = { @@ -1156,11 +1165,11 @@ ingest( fd_ledger_args_t * args ) { /* At this point the account state has been ingested into funk. Intake rocksdb */ if( args->start_slot == 0 ) { - args->start_slot = slot_ctx->slot_bank.slot + 1; + args->start_slot = slot_ctx->slot + 1; } fd_blockstore_t * blockstore = args->blockstore; if( blockstore ) { - blockstore->shmem->lps = blockstore->shmem->hcs = blockstore->shmem->wmk = slot_ctx->slot_bank.slot; + blockstore->shmem->lps = blockstore->shmem->hcs = blockstore->shmem->wmk = slot_ctx->slot; } if( args->funk_only ) { @@ -1169,8 +1178,8 @@ ingest( fd_ledger_args_t * args ) { FD_LOG_NOTICE(( "using shredcap" )); fd_shredcap_populate_blockstore( args->shredcap, blockstore, args->start_slot, args->end_slot ); } else if( args->rocksdb_list[ 0UL ] ) { - if( args->end_slot >= slot_ctx->slot_bank.slot + args->slot_history_max ) { - args->end_slot = slot_ctx->slot_bank.slot + args->slot_history_max - 1; + if( args->end_slot >= slot_ctx->slot + args->slot_history_max ) { + args->end_slot = slot_ctx->slot + args->slot_history_max - 1; } ingest_rocksdb( args->rocksdb_list[ 0UL ], args->start_slot, args->end_slot, blockstore, args->copy_txn_status, args->trash_hash, args->valloc ); @@ -1269,24 +1278,31 @@ replay( fd_ledger_args_t * args ) { fd_exec_epoch_ctx_bank_mem_clear( args->epoch_ctx ); /* TODO: This is very hacky, needs to be cleaned up */ - args->epoch_ctx->epoch_bank.cluster_version[0] = args->cluster_version[0]; - args->epoch_ctx->epoch_bank.cluster_version[1] = args->cluster_version[1]; - args->epoch_ctx->epoch_bank.cluster_version[2] = args->cluster_version[2]; + + void * slot_ctx_mem = fd_spad_alloc_check( spad, FD_EXEC_SLOT_CTX_ALIGN, FD_EXEC_SLOT_CTX_FOOTPRINT ); + args->slot_ctx = fd_exec_slot_ctx_join( fd_exec_slot_ctx_new( slot_ctx_mem, spad ) ); + args->slot_ctx->epoch_ctx = args->epoch_ctx; + args->slot_ctx->funk = funk; + args->slot_ctx->blockstore = args->blockstore; + + FD_TEST( args->slot_ctx->bank_mgr_mem ); + args->slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( args->slot_ctx->bank_mgr_mem ), funk, NULL ); + + fd_cluster_version_t * cluster_version = fd_bank_mgr_cluster_version_modify( args->slot_ctx->bank_mgr ); + + cluster_version->major = args->cluster_version[0]; + cluster_version->minor = args->cluster_version[1]; + cluster_version->patch = args->cluster_version[2]; + fd_bank_mgr_cluster_version_save( args->slot_ctx->bank_mgr ); args->epoch_ctx->runtime_public = runtime_public; - fd_features_enable_cleaned_up( &args->epoch_ctx->features, args->epoch_ctx->epoch_bank.cluster_version ); + fd_features_enable_cleaned_up( &args->epoch_ctx->features, cluster_version ); fd_features_enable_one_offs( &args->epoch_ctx->features, args->one_off_features, args->one_off_features_cnt, 0UL ); // activate them fd_memcpy( &args->epoch_ctx->runtime_public->features, &args->epoch_ctx->features, sizeof(fd_features_t) ); - void * slot_ctx_mem = fd_spad_alloc_check( spad, FD_EXEC_SLOT_CTX_ALIGN, FD_EXEC_SLOT_CTX_FOOTPRINT ); - args->slot_ctx = fd_exec_slot_ctx_join( fd_exec_slot_ctx_new( slot_ctx_mem, spad ) ); - args->slot_ctx->epoch_ctx = args->epoch_ctx; - args->slot_ctx->funk = funk; - args->slot_ctx->blockstore = args->blockstore; - void * status_cache_mem = fd_spad_alloc_check( spad, FD_TXNCACHE_ALIGN, fd_txncache_footprint( FD_TXNCACHE_DEFAULT_MAX_ROOTED_SLOTS, @@ -1347,7 +1363,11 @@ replay( fd_ledger_args_t * args ) { fd_ledger_main_setup( args ); - fd_blockstore_init( args->blockstore, -1, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &args->slot_ctx->slot_bank ); + fd_blockstore_init( args->blockstore, + -1, + FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, + &args->slot_ctx->slot_bank, + args->slot_ctx->slot ); fd_buf_shred_pool_reset( args->blockstore->shred_pool, 0 ); FD_LOG_WARNING(( "setup done" )); diff --git a/src/app/shared_dev/commands/configure/genesis.c b/src/app/shared_dev/commands/configure/genesis.c index 9a8b24ccb3..14841e2b9c 100644 --- a/src/app/shared_dev/commands/configure/genesis.c +++ b/src/app/shared_dev/commands/configure/genesis.c @@ -194,8 +194,12 @@ create_genesis( config_t const * config, fd_features_t features[1]; fd_features_disable_all( features ); - uint version[] = {FD_DEFAULT_AGAVE_CLUSTER_VERSION_MAJOR, FD_DEFAULT_AGAVE_CLUSTER_VERSION_MINOR, FD_DEFAULT_AGAVE_CLUSTER_VERSION_PATCH}; - fd_features_enable_cleaned_up(features, version); + fd_cluster_version_t cluster_version = { + .major = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MAJOR, + .minor = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MINOR, + .patch = FD_DEFAULT_AGAVE_CLUSTER_VERSION_PATCH + }; + fd_features_enable_cleaned_up( features, &cluster_version ); default_enable_features( features ); options->features = features; diff --git a/src/choreo/epoch/fd_epoch.c b/src/choreo/epoch/fd_epoch.c index 6964c5fcef..399abd3055 100644 --- a/src/choreo/epoch/fd_epoch.c +++ b/src/choreo/epoch/fd_epoch.c @@ -1,5 +1,5 @@ #include "fd_epoch.h" - +#include "../../flamenco/runtime/fd_bank_mgr.h" void * fd_epoch_new( void * shmem, ulong voter_max ) { if( FD_UNLIKELY( !shmem ) ) { @@ -103,12 +103,15 @@ fd_epoch_delete( void * epoch ) { } void -fd_epoch_init( fd_epoch_t * epoch, fd_epoch_bank_t const * epoch_bank ) { - epoch->first_slot = epoch_bank->eah_start_slot; - epoch->last_slot = epoch_bank->eah_stop_slot; +fd_epoch_init( fd_epoch_t * epoch, + ulong eah_start_slot, + ulong eah_stop_slot, + fd_vote_accounts_t const * vote_accounts ) { + + epoch->first_slot = eah_start_slot; + epoch->last_slot = eah_stop_slot; - fd_voter_t * epoch_voters = fd_epoch_voters( epoch ); - fd_vote_accounts_t const * vote_accounts = &epoch_bank->stakes.vote_accounts; + fd_voter_t * epoch_voters = fd_epoch_voters( epoch ); for( fd_vote_accounts_pair_t_mapnode_t * curr = fd_vote_accounts_pair_t_map_minimum( vote_accounts->vote_accounts_pool, diff --git a/src/choreo/epoch/fd_epoch.h b/src/choreo/epoch/fd_epoch.h index 4659c9eb79..34c49270f6 100644 --- a/src/choreo/epoch/fd_epoch.h +++ b/src/choreo/epoch/fd_epoch.h @@ -97,7 +97,10 @@ fd_epoch_delete( void * epoch ); epoch. */ void -fd_epoch_init( fd_epoch_t * epoch, fd_epoch_bank_t const * epoch_bank ); +fd_epoch_init( fd_epoch_t * epoch, + ulong eah_start_slot, + ulong eah_stop_slot, + fd_vote_accounts_t const * vote_accounts ); /* fd_epoch_fini finishes an epoch. Assumes epoch is a valid local join and epoch has already been initialized. This should only be called diff --git a/src/choreo/forks/fd_forks.c b/src/choreo/forks/fd_forks.c index 7756ea16e8..d49fbb6e8e 100644 --- a/src/choreo/forks/fd_forks.c +++ b/src/choreo/forks/fd_forks.c @@ -6,7 +6,7 @@ #include "../../flamenco/runtime/fd_runtime.h" #include "../../flamenco/runtime/program/fd_program_util.h" #include "../../flamenco/runtime/program/fd_vote_program.h" - +#include "../../flamenco/runtime/fd_bank_mgr.h" void * fd_forks_new( void * shmem, ulong max, ulong seed ) { @@ -115,7 +115,7 @@ fd_forks_init( fd_forks_t * forks, fd_exec_slot_ctx_t * slot_ctx ) { } fd_fork_t * fork = fd_fork_pool_ele_acquire( forks->pool ); - fork->slot = slot_ctx->slot_bank.slot; + fork->slot = slot_ctx->slot; fork->prev = fd_fork_pool_idx_null( forks->pool ); fork->lock = 0; fork->end_idx = UINT_MAX; @@ -167,8 +167,8 @@ fd_forks_query_const( fd_forks_t const * forks, ulong slot ) { // // fork is advancing // FD_LOG_DEBUG(( "new block execution - slot: %lu, parent_slot: %lu", curr_slot, parent_slot )); -// fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot_bank.slot; -// fork->slot_ctx->slot_bank.slot = curr_slot; +// fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot; +// fork->slot_ctx->slot = curr_slot; // fork->slot_ctx.status_cache = status_cache; // fd_funk_txn_xid_t xid; @@ -245,6 +245,7 @@ slot_ctx_restore( ulong slot, continue; } + slot_ctx_out->slot = slot; slot_ctx_out->slot_bank = *slot_bank; FD_TEST( !fd_runtime_sysvar_cache_load( slot_ctx_out, runtime_spad ) ); @@ -259,20 +260,16 @@ slot_ctx_restore( ulong slot, // signature_cnt, account_delta_hash, prev_banks_hash are used for the banks // hash calculation and not needed when restoring parent - FD_LOG_NOTICE( ( "recovered slot_bank for slot=%lu banks_hash=%s poh_hash %s", - slot_ctx_out->slot_bank.slot, - FD_BASE58_ENC_32_ALLOCA( slot_ctx_out->slot_bank.banks_hash.hash ), - FD_BASE58_ENC_32_ALLOCA( slot_ctx_out->slot_bank.poh.hash ) ) ); + FD_LOG_NOTICE(( "recovered slot_bank for slot=%lu banks_hash=%s", + slot_ctx_out->slot, + FD_BASE58_ENC_32_ALLOCA( slot_ctx_out->slot_bank.banks_hash.hash ) )); /* Prepare bank for next slot */ - slot_ctx_out->slot_bank.slot = slot; - slot_ctx_out->slot_bank.collected_execution_fees = 0; - slot_ctx_out->slot_bank.collected_priority_fees = 0; - slot_ctx_out->slot_bank.collected_rent = 0; + slot_ctx_out->slot = slot; /* FIXME epoch boundary stuff when replaying */ // fd_features_restore( slot_ctx ); - // fd_runtime_update_leaders( slot_ctx, slot_ctx->slot_bank.slot ); + // fd_runtime_update_leaders( slot_ctx, slot_ctx->slot ); // fd_calculate_epoch_accounts_hash_values( slot_ctx ); } diff --git a/src/discof/batch/fd_batch_tile.c b/src/discof/batch/fd_batch_tile.c index ab6ea9beb8..fe8090e120 100644 --- a/src/discof/batch/fd_batch_tile.c +++ b/src/discof/batch/fd_batch_tile.c @@ -381,18 +381,20 @@ produce_eah( fd_snapshot_tile_ctx_t * ctx, fd_stem_context_t * stem, ulong batch FD_LOG_ERR(( "Slot bank record has wrong magic" )); } - int err; - fd_slot_bank_t * slot_bank = fd_bincode_decode_spad( slot_bank, ctx->spad, (uchar *)slot_val+sizeof(uint), fd_funk_val_sz( slot_rec )-sizeof(uint), &err ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { - FD_LOG_ERR(( "Failed to read slot bank record: invalid decode" )); - continue; - } + /* FIXME: The slot bank is getting replaced with the bank manager. */ + // int err; + // fd_slot_bank_t * slot_bank = fd_bincode_decode_spad( slot_bank, ctx->spad, (uchar *)slot_val+sizeof(uint), fd_funk_val_sz( slot_rec )-sizeof(uint), &err ); + // if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { + // FD_LOG_ERR(( "Failed to read slot bank record: invalid decode" )); + // continue; + // } /* At this point, calculate the epoch account hash. */ fd_hash_t epoch_account_hash = {0}; - fd_accounts_hash( funk, slot_bank, &epoch_account_hash, ctx->spad, &ctx->runtime_public->features, NULL, NULL ); + /* FIXME: this has an invalid slot number. */ + fd_accounts_hash( funk, 0UL, &epoch_account_hash, ctx->spad, &ctx->runtime_public->features, NULL, NULL ); FD_LOG_NOTICE(( "Done computing epoch account hash (%s)", FD_BASE58_ENC_32_ALLOCA( &epoch_account_hash ) )); diff --git a/src/discof/consensus/test_consensus.c b/src/discof/consensus/test_consensus.c index 1494f1693e..0881943e35 100644 --- a/src/discof/consensus/test_consensus.c +++ b/src/discof/consensus/test_consensus.c @@ -552,14 +552,14 @@ main( void ) { // if( incremental_snapshot ) { // ulong i, j; // FD_TEST( sscanf( incremental_snapshot, "incremental-snapshot-%lu-%lu", &i, &j ) == 2 ); -// FD_TEST( i == snapshot_slot_ctx->slot_bank.slot ); +// FD_TEST( i == snapshot_slot_ctx->slot ); // FD_TEST( epoch_bank ); // FD_TEST( fd_slot_to_epoch( &epoch_bank->epoch_schedule, i, NULL ) == // fd_slot_to_epoch( &epoch_bank->epoch_schedule, j, NULL ) ); // fd_snapshot_load_all( incremental_snapshot, NULL, snapshot_slot_ctx, 1, 1, FD_SNAPSHOT_TYPE_INCREMENTAL ); // } -// ulong snapshot_slot = snapshot_slot_ctx->slot_bank.slot; +// ulong snapshot_slot = snapshot_slot_ctx->slot; // FD_LOG_NOTICE( ( "snapshot_slot: %lu", snapshot_slot ) ); // snapshot_fork->slot = snapshot_slot; @@ -568,7 +568,7 @@ main( void ) { // FD_TEST( !fd_runtime_sysvar_cache_load( snapshot_slot_ctx ) ); // fd_features_restore( snapshot_slot_ctx ); -// fd_runtime_update_leaders( snapshot_slot_ctx, snapshot_slot_ctx->slot_bank.slot ); +// fd_runtime_update_leaders( snapshot_slot_ctx, snapshot_slot_ctx->slot ); // fd_calculate_epoch_accounts_hash_values( snapshot_slot_ctx ); // fd_funk_start_write( funk ); diff --git a/src/discof/exec/fd_exec_tile.c b/src/discof/exec/fd_exec_tile.c index 3de851a001..e1c594d4af 100644 --- a/src/discof/exec/fd_exec_tile.c +++ b/src/discof/exec/fd_exec_tile.c @@ -9,6 +9,7 @@ #include "../../flamenco/runtime/fd_runtime_public.h" #include "../../flamenco/runtime/fd_executor.h" #include "../../flamenco/runtime/fd_hashes.h" +#include "../../flamenco/runtime/fd_bank_mgr.h" #include "../../flamenco/runtime/program/fd_bpf_program_util.h" #include "../../funk/fd_funk.h" @@ -145,6 +146,10 @@ struct fd_exec_tile_ctx { /* Pairs len is the number of accounts to hash. */ ulong pairs_len; + + /* Local handle to the bank manager. The join must be updated at + every slot boundary. */ + fd_bank_mgr_t * bank_mgr; }; typedef struct fd_exec_tile_ctx fd_exec_tile_ctx_t; @@ -185,11 +190,9 @@ prepare_new_epoch_execution( fd_exec_tile_ctx_t * ctx, fd_spad_push( ctx->exec_spad ); ctx->pending_epoch_pop = 1; - ctx->txn_ctx->features = epoch_msg->features; - ctx->txn_ctx->total_epoch_stake = epoch_msg->total_epoch_stake; - ctx->txn_ctx->schedule = epoch_msg->epoch_schedule; - ctx->txn_ctx->rent = epoch_msg->rent; - ctx->txn_ctx->slots_per_year = epoch_msg->slots_per_year; + ctx->txn_ctx->features = epoch_msg->features; + ctx->txn_ctx->schedule = epoch_msg->epoch_schedule; + ctx->txn_ctx->rent = epoch_msg->rent; uchar * stakes_enc = fd_wksp_laddr_fast( ctx->runtime_public_wksp, epoch_msg->stakes_encoded_gaddr ); if( FD_UNLIKELY( !stakes_enc ) ) { @@ -244,9 +247,6 @@ prepare_new_slot_execution( fd_exec_tile_ctx_t * ctx, fd_funk_txn_end_read( ctx->funk ); ctx->txn_ctx->funk_txn = funk_txn; - ctx->txn_ctx->slot = slot_msg->slot; - ctx->txn_ctx->prev_lamports_per_signature = slot_msg->prev_lamports_per_signature; - ctx->txn_ctx->fee_rate_governor = slot_msg->fee_rate_governor; ctx->txn_ctx->enable_exec_recording = slot_msg->enable_exec_recording; ctx->txn_ctx->sysvar_cache = fd_wksp_laddr_fast( ctx->runtime_public_wksp, slot_msg->sysvar_cache_gaddr ); @@ -254,22 +254,18 @@ prepare_new_slot_execution( fd_exec_tile_ctx_t * ctx, FD_LOG_ERR(( "Could not find valid sysvar cache" )); } - uchar * block_hash_queue_enc = fd_wksp_laddr_fast( ctx->runtime_public_wksp, slot_msg->block_hash_queue_encoded_gaddr ); - if( FD_UNLIKELY( !block_hash_queue_enc ) ) { - FD_LOG_ERR(( "Could not get laddr for encoded block hash queue" )); + /* Update the local join to the bank manager.*/ + ctx->txn_ctx->bank_mgr = fd_bank_mgr_join( ctx->txn_ctx->bank_mgr_mem, ctx->txn_ctx->funk, ctx->txn_ctx->funk_txn ); + if( FD_UNLIKELY( !ctx->txn_ctx->bank_mgr ) ) { + FD_LOG_ERR(( "Could not join bank mgr" )); } - // FIXME account for this in exec spad footprint - int err; - fd_block_hash_queue_t * block_hash_queue = fd_bincode_decode_spad( - block_hash_queue, ctx->exec_spad, - block_hash_queue_enc, slot_msg->block_hash_queue_encoded_sz, - &err ); - if( FD_UNLIKELY( err ) ) { - FD_LOG_ERR(( "Could not decode block hash queue footprint" )); + ctx->txn_ctx->slot = *(fd_bank_mgr_slot_query( ctx->txn_ctx->bank_mgr )); + ctx->txn_ctx->block_hash_queue = fd_bank_mgr_block_hash_queue_query( ctx->txn_ctx->bank_mgr ); + if( FD_UNLIKELY( !ctx->txn_ctx->block_hash_queue ) ) { + FD_LOG_ERR(( "Could not find valid block hash queue" )); } - - ctx->txn_ctx->block_hash_queue = *block_hash_queue; + ctx->txn_ctx->fee_rate_governor = *(fd_bank_mgr_fee_rate_governor_query( ctx->txn_ctx->bank_mgr )); } static void @@ -325,7 +321,7 @@ execute_txn( fd_exec_tile_ctx_t * ctx ) { } } -//TODO hashing can be moved into the writer tile +// TODO: hashing can be moved into the writer tile static void hash_accounts( fd_exec_tile_ctx_t * ctx, fd_runtime_public_hash_bank_msg_t * msg ) { @@ -545,8 +541,8 @@ unprivileged_init( fd_topo_t * topo, void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id ); FD_SCRATCH_ALLOC_INIT( l, scratch ); - fd_exec_tile_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_tile_ctx_t), sizeof(fd_exec_tile_ctx_t) ); - ulong scratch_alloc_mem = FD_SCRATCH_ALLOC_FINI( l, scratch_align() ); + fd_exec_tile_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_tile_ctx_t), sizeof(fd_exec_tile_ctx_t) ); + ulong scratch_alloc_mem = FD_SCRATCH_ALLOC_FINI( l, scratch_align() ); if( FD_UNLIKELY( scratch_alloc_mem - (ulong)scratch - scratch_footprint( tile ) ) ) { FD_LOG_ERR( ( "Scratch_alloc_mem did not match scratch_footprint diff: %lu alloc: %lu footprint: %lu", scratch_alloc_mem - (ulong)scratch - scratch_footprint( tile ), @@ -656,11 +652,12 @@ unprivileged_init( fd_topo_t * topo, FD_LOG_NOTICE(( "Just joined funk at file=%s", tile->exec.funk_file )); - //FIXME /********************************************************************/ /* setup txncache */ /********************************************************************/ + /* TODO: Implement this. */ + /********************************************************************/ /* setup txn ctx */ /********************************************************************/ diff --git a/src/discof/replay/fd_replay.c b/src/discof/replay/fd_replay.c index b9d7f6c8e5..477a461aea 100644 --- a/src/discof/replay/fd_replay.c +++ b/src/discof/replay/fd_replay.c @@ -42,7 +42,7 @@ leader_pipeline( void ) { // /* FIXME. We need a more efficient way to compute the ancestor chain. */ // uchar msg[4098*8] __attribute__( ( aligned( 8U ) ) ); // fd_memset( msg, 0, sizeof(msg) ); - // ulong s = reset_fork->slot_ctx->slot_bank.slot; + // ulong s = reset_fork->slot_ctx->slot; // *(ulong*)(msg + 16U) = s; // ulong i = 0; // do { @@ -67,7 +67,7 @@ leader_pipeline( void ) { // memcpy( microblock_trailer->hash, reset_fork->slot_ctx->slot_bank.block_hash_queue.last_hash->uc, sizeof(fd_hash_t) ); // if( ctx->poh_init_done == 1 ) { // ulong parent_slot = reset_fork->slot_ctx->slot_bank.prev_slot; - // ulong curr_slot = reset_fork->slot_ctx->slot_bank.slot; + // ulong curr_slot = reset_fork->slot_ctx->slot; // FD_LOG_DEBUG(( "publishing mblk to poh - slot: %lu, parent_slot: %lu, flags: %lx", curr_slot, parent_slot, flags )); // ulong tspub = fd_frag_meta_ts_comp( fd_tickcount() ); // ulong sig = fd_disco_replay_old_sig( curr_slot, flags ); diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index e38d515763..d42bf45c4f 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -21,6 +21,7 @@ #include "../../flamenco/stakes/fd_stakes.h" #include "../../flamenco/runtime/fd_runtime.h" #include "../../flamenco/runtime/fd_runtime_public.h" +#include "../../flamenco/runtime/fd_bank_mgr.h" #include "../../flamenco/rewards/fd_rewards.h" #include "../../disco/metrics/fd_metrics.h" #include "../../choreo/fd_choreo.h" @@ -316,6 +317,8 @@ struct fd_replay_tile_ctx { ulong exec_spad_cnt; fd_spad_t * runtime_spad; + /* These parameters should be removed as snapshot-creation is not + being actively supported at this moment. */ /* TODO: refactor this all into fd_replay_tile_snapshot_ctx_t. */ ulong snapshot_interval; /* User defined parameter */ ulong incremental_interval; /* User defined parameter */ @@ -334,6 +337,9 @@ struct fd_replay_tile_ctx { fd_replay_tile_metrics_t metrics; ulong * exec_slice_deque; /* Deque to buffer exec slices */ + + /* Local join to the bank_mgr that must be refreshed at every slot. */ + fd_bank_mgr_t * bank_mgr; }; typedef struct fd_replay_tile_ctx fd_replay_tile_ctx_t; @@ -360,6 +366,7 @@ scratch_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED ) { l = FD_LAYOUT_APPEND( l, fd_forks_align(), fd_forks_footprint( FD_BLOCK_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_ghost_align(), fd_ghost_footprint( FD_BLOCK_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_tower_align(), fd_tower_footprint() ); + l = FD_LAYOUT_APPEND( l, fd_bank_mgr_align(), fd_bank_mgr_footprint() ); for( ulong i = 0UL; iruntime_spad ); - stake_weights_msg[0] = fd_slot_to_leader_schedule_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot ) - 1; /* epoch */ + stake_weights_msg[0] = fd_slot_to_leader_schedule_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot ) - 1; /* epoch */ stake_weights_msg[1] = stake_weight_idx; /* staked_cnt */ stake_weights_msg[2] = fd_epoch_slot0( &epoch_bank->epoch_schedule, stake_weights_msg[0] ); /* start_slot */ stake_weights_msg[3] = epoch_bank->epoch_schedule.slots_per_epoch; /* slot_cnt */ @@ -422,7 +429,7 @@ publish_stake_weights( fd_replay_tile_ctx_t * ctx, ulong stake_weight_idx = fd_stake_weights_by_node( &epoch_bank->next_epoch_stakes, stake_weights, ctx->runtime_spad ); stake_weights_msg[0] = fd_slot_to_leader_schedule_epoch( &epoch_bank->epoch_schedule, - slot_ctx->slot_bank.slot ); /* epoch */ + slot_ctx->slot ); /* epoch */ stake_weights_msg[1] = stake_weight_idx; /* staked_cnt */ stake_weights_msg[2] = fd_epoch_slot0( &epoch_bank->epoch_schedule, stake_weights_msg[0] ); /* start_slot */ stake_weights_msg[3] = epoch_bank->epoch_schedule.slots_per_epoch; /* slot_cnt */ @@ -730,9 +737,11 @@ during_frag( fd_replay_tile_ctx_t * ctx, ctx->skip_frag = 0; if( in_idx==BATCH_IN_IDX ) { + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_modify( ctx->bank_mgr ); uchar * src = (uchar *)fd_chunk_to_laddr( ctx->batch_in_mem, chunk ); - fd_memcpy( ctx->slot_ctx->slot_bank.epoch_account_hash.uc, src, sizeof(fd_hash_t) ); - FD_LOG_NOTICE(( "Epoch account hash calculated to be %s", FD_BASE58_ENC_32_ALLOCA( ctx->slot_ctx->slot_bank.epoch_account_hash.uc ) )); + fd_memcpy( epoch_account_hash, src, sizeof(fd_hash_t) ); + fd_bank_mgr_epoch_account_hash_save( ctx->bank_mgr ); + FD_LOG_NOTICE(( "Epoch account hash calculated to be %s", FD_BASE58_ENC_32_ALLOCA( epoch_account_hash ) )); } } @@ -882,15 +891,17 @@ funk_publish( fd_replay_tile_ctx_t * ctx, fd_funk_txn_start_write( ctx->funk ); - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( ctx->slot_ctx->epoch_ctx ); fd_funk_txn_pool_t * txn_pool = fd_funk_txn_pool( ctx->funk ); + FD_BANK_MGR_DECL( bank_mgr, ctx->funk, to_root_txn ); + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_query( bank_mgr ); + /* Try to publish into Funk */ if( is_constipated ) { FD_LOG_NOTICE(( "Publishing slot=%lu while constipated", wmk )); /* Sanity-check that we are not constipated and the EHA has not been calculated */ - if( FD_UNLIKELY( wmk>=epoch_bank->eah_start_slot ) ) { + if( FD_UNLIKELY( wmk>=*eah_start_slot ) ) { FD_LOG_ERR(( "trying to publish into a constipated funk whilst in front of the EHA start slot - we should never get here" )); } @@ -914,7 +925,7 @@ funk_publish( fd_replay_tile_ctx_t * ctx, FD_LOG_NOTICE(( "Publishing slot=%lu xid=%lu", wmk, to_root_txn->xid.ul[0] )); - if( FD_UNLIKELY( wmk>=epoch_bank->eah_start_slot ) ) { + if( FD_UNLIKELY( wmk>=*eah_start_slot ) ) { FD_LOG_NOTICE(( "EAH is ready to be calculated" )); @@ -933,8 +944,8 @@ funk_publish( fd_replay_tile_ctx_t * ctx, either have been published already or must be less than the eah start slot. */ - int is_curr_gteq_eah_start = txn->xid.ul[0] >= epoch_bank->eah_start_slot; - int is_prev_lt_eah_start = parent_txn->xid.ul[0] < epoch_bank->eah_start_slot; + int is_curr_gteq_eah_start = txn->xid.ul[0] >= *eah_start_slot; + int is_prev_lt_eah_start = parent_txn->xid.ul[0] < *eah_start_slot; if( is_curr_gteq_eah_start && is_prev_lt_eah_start ) { break; } @@ -946,7 +957,7 @@ funk_publish( fd_replay_tile_ctx_t * ctx, calculate the eah for since it's the minimum slot that is >= eah_start_slot. */ - FD_LOG_NOTICE(( "The eah has an expected start slot of %lu and is being created for slot %lu", epoch_bank->eah_start_slot, txn->xid.ul[0] )); + FD_LOG_NOTICE(( "The eah has an expected start slot of %lu and is being created for slot %lu", *eah_start_slot, txn->xid.ul[0] )); if( FD_UNLIKELY( !fd_funk_txn_publish( ctx->funk, txn, 1 ) ) ) { FD_LOG_ERR(( "failed to funk publish" )); @@ -961,7 +972,9 @@ funk_publish( fd_replay_tile_ctx_t * ctx, ulong updated_fseq = fd_batch_fseq_pack( 0UL, 0UL, txn->xid.ul[0] ); fd_fseq_update( ctx->is_constipated, updated_fseq ); - epoch_bank->eah_start_slot = FD_SLOT_NULL; + eah_start_slot = fd_bank_mgr_eah_start_slot_modify( bank_mgr ); + *eah_start_slot = FD_SLOT_NULL; + fd_bank_mgr_eah_start_slot_save( bank_mgr ); } else { /* This is the standard case. Publish all transactions up to and @@ -1128,7 +1141,6 @@ publish_slot_notifications( fd_replay_tile_ctx_t * ctx, msg->slot_exec.parent = ctx->parent_slot; msg->slot_exec.root = fd_fseq_query( ctx->published_wmark ); msg->slot_exec.height = block_entry_block_height; - msg->slot_exec.transaction_count = fork->slot_ctx->slot_bank.transaction_count; msg->slot_exec.shred_cnt = fork->slot_ctx->shred_cnt; memcpy( &msg->slot_exec.bank_hash, &fork->slot_ctx->slot_bank.banks_hash, sizeof( fd_hash_t ) ); memcpy( &msg->slot_exec.block_hash, &ctx->blockhash, sizeof( fd_hash_t ) ); @@ -1157,6 +1169,11 @@ publish_slot_notifications( fd_replay_tile_ctx_t * ctx, .parent_slot = ctx->parent_slot, }; */ + FD_BANK_MGR_DECL( bank_mgr, ctx->funk, ctx->slot_ctx->funk_txn ); + + ulong * execution_fees = fd_bank_mgr_execution_fees_query( bank_mgr ); + ulong * priority_fees = fd_bank_mgr_priority_fees_query( bank_mgr ); + ulong msg[11]; msg[ 0 ] = ctx->curr_slot; msg[ 1 ] = fork->slot_ctx->txn_count; @@ -1164,8 +1181,8 @@ publish_slot_notifications( fd_replay_tile_ctx_t * ctx, msg[ 3 ] = fork->slot_ctx->failed_txn_count; msg[ 4 ] = fork->slot_ctx->nonvote_failed_txn_count; msg[ 5 ] = fork->slot_ctx->total_compute_units_used; - msg[ 6 ] = fork->slot_ctx->slot_bank.collected_execution_fees; - msg[ 7 ] = fork->slot_ctx->slot_bank.collected_priority_fees; + msg[ 6 ] = *execution_fees; + msg[ 7 ] = *priority_fees; msg[ 8 ] = 0UL; /* todo ... track tips */ msg[ 9 ] = ctx->parent_slot; msg[ 10 ] = 0UL; /* todo ... max compute units */ @@ -1234,10 +1251,8 @@ send_exec_epoch_msg( fd_replay_tile_ctx_t * ctx, fd_runtime_public_epoch_msg_t * epoch_msg = (fd_runtime_public_epoch_msg_t *)fd_chunk_to_laddr( exec_out->mem, exec_out->chunk ); epoch_msg->features = slot_ctx->epoch_ctx->features; - epoch_msg->total_epoch_stake = slot_ctx->epoch_ctx->total_epoch_stake; epoch_msg->epoch_schedule = slot_ctx->epoch_ctx->epoch_bank.epoch_schedule; epoch_msg->rent = slot_ctx->epoch_ctx->epoch_bank.rent; - epoch_msg->slots_per_year = slot_ctx->epoch_ctx->epoch_bank.slots_per_year; epoch_msg->bank_hash_cmp_gaddr = fd_wksp_gaddr_fast( ctx->runtime_public_wksp, fd_bank_hash_cmp_leave( ctx->bank_hash_cmp ) ); if( FD_UNLIKELY( !epoch_msg->bank_hash_cmp_gaddr ) ) { @@ -1291,30 +1306,12 @@ send_exec_slot_msg( fd_replay_tile_ctx_t * ctx, fd_runtime_public_slot_msg_t * slot_msg = (fd_runtime_public_slot_msg_t *)fd_chunk_to_laddr( exec_out->mem, exec_out->chunk ); - slot_msg->slot = slot_ctx->slot_bank.slot; - slot_msg->prev_lamports_per_signature = slot_ctx->prev_lamports_per_signature; - slot_msg->fee_rate_governor = slot_ctx->slot_bank.fee_rate_governor; + slot_msg->slot = slot_ctx->slot; slot_msg->enable_exec_recording = slot_ctx->enable_exec_recording; /* Save the gaddr of the sysvar cache */ slot_msg->sysvar_cache_gaddr = fd_wksp_gaddr_fast( ctx->runtime_public_wksp, slot_ctx->sysvar_cache ); - /* Now encode the bhq */ - ulong bhq_encode_sz = fd_block_hash_queue_size( &slot_ctx->slot_bank.block_hash_queue ) + 128UL; - uchar * bhq_encode_mem = fd_spad_alloc( ctx->runtime_spad, - fd_block_hash_queue_align(), - bhq_encode_sz ); - fd_bincode_encode_ctx_t encode = { - .data = bhq_encode_mem, - .dataend = bhq_encode_mem + bhq_encode_sz - }; - int err = fd_block_hash_queue_encode( &slot_ctx->slot_bank.block_hash_queue, &encode ); - if( FD_UNLIKELY( err ) ) { - FD_LOG_ERR(( "Failed to encode block hash queue" )); - } - slot_msg->block_hash_queue_encoded_gaddr = fd_wksp_gaddr_fast( ctx->runtime_public_wksp, bhq_encode_mem ); - slot_msg->block_hash_queue_encoded_sz = bhq_encode_sz; - ulong tspub = fd_frag_meta_ts_comp( fd_tickcount() ); fd_stem_publish( stem, exec_out->idx, @@ -1387,8 +1384,8 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( fork->slot_ctx->epoch_ctx ); /* if it is an epoch boundary, push out stake weights */ - if( fork->slot_ctx->slot_bank.slot != 0 ) { - is_new_epoch_in_new_block = (int)fd_runtime_is_epoch_boundary( epoch_bank, fork->slot_ctx->slot_bank.slot, fork->slot_ctx->slot_bank.prev_slot ); + if( fork->slot_ctx->slot != 0 ) { + is_new_epoch_in_new_block = (int)fd_runtime_is_epoch_boundary( epoch_bank, fork->slot_ctx->slot, fork->slot_ctx->slot_bank.prev_slot ); } fd_block_map_query_t query[1] = { 0 }; @@ -1396,25 +1393,40 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, fd_block_info_t * curr_block_info = fd_block_map_query_ele( query ); if( FD_UNLIKELY( err == FD_MAP_ERR_FULL ) ) FD_LOG_ERR(("Block map prepare failed, likely corrupt.")); if( FD_UNLIKELY( curr_slot != curr_block_info->slot ) ) FD_LOG_ERR(("Block map prepare failed, likely corrupt.")); - curr_block_info->in_poh_hash = fork->slot_ctx->slot_bank.poh; + // curr_block_info->in_poh_hash = fork->slot_ctx->slot_bank.poh; fd_block_map_publish( query ); - fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot_bank.slot; - fork->slot_ctx->slot_bank.slot = curr_slot; - fork->slot_ctx->slot_bank.tick_height = fork->slot_ctx->slot_bank.max_tick_height; - if( FD_UNLIKELY( FD_RUNTIME_EXECUTE_SUCCESS != fd_runtime_compute_max_tick_height( epoch_bank->ticks_per_slot, curr_slot, &fork->slot_ctx->slot_bank.max_tick_height ) ) ) { - FD_LOG_ERR(( "couldn't compute tick height/max tick height slot %lu ticks_per_slot %lu", curr_slot, epoch_bank->ticks_per_slot )); + fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot; + fork->slot_ctx->slot = curr_slot; + + FD_BANK_MGR_DECL( bank_mgr_prev, fork->slot_ctx->funk, fork->slot_ctx->funk_txn ); + + ulong * max_tick_height = fd_bank_mgr_max_tick_height_query( bank_mgr_prev ); + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( bank_mgr_prev ); + ulong * tick_height = fd_bank_mgr_tick_height_modify( bank_mgr_prev ); + *tick_height = *max_tick_height; + fd_bank_mgr_tick_height_save( bank_mgr_prev ); + + + + max_tick_height = fd_bank_mgr_max_tick_height_modify( bank_mgr_prev ); + if( FD_UNLIKELY( FD_RUNTIME_EXECUTE_SUCCESS != fd_runtime_compute_max_tick_height( *ticks_per_slot, + curr_slot, + max_tick_height ) ) ) { + FD_LOG_ERR(( "couldn't compute tick height/max tick height slot %lu ticks_per_slot %lu", curr_slot, *ticks_per_slot )); } + fd_bank_mgr_max_tick_height_save( bank_mgr_prev ); + fork->slot_ctx->enable_exec_recording = ctx->tx_metadata_storage; fork->slot_ctx->runtime_wksp = fd_wksp_containing( ctx->runtime_spad ); /* NOTE: By commenting this out, we don't support forking at the epoch boundary but this code is buggy and leads to crashes. */ - // if( fd_runtime_is_epoch_boundary( epoch_bank, fork->slot_ctx->slot_bank.slot, fork->slot_ctx->slot_bank.prev_slot ) ) { + // if( fd_runtime_is_epoch_boundary( epoch_bank, fork->slot_ctx->slot, fork->slot_ctx->slot_bank.prev_slot ) ) { // FD_LOG_WARNING(("Epoch boundary")); // fd_epoch_fork_elem_t * epoch_fork = NULL; - // ulong new_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, fork->slot_ctx->slot_bank.slot, NULL ); + // ulong new_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, fork->slot_ctx->slot, NULL ); // uint found = fd_epoch_forks_prepare( ctx->epoch_forks, fork->slot_ctx->slot_bank.prev_slot, new_epoch, &epoch_fork ); // if( FD_UNLIKELY( found ) ) { @@ -1433,12 +1445,19 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, if( flags & REPLAY_FLAG_PACKED_MICROBLOCK ) { memset( xid.uc, 0, sizeof(fd_funk_txn_xid_t) ); } else { - xid.ul[1] = fork->slot_ctx->slot_bank.slot; + xid.ul[1] = fork->slot_ctx->slot; } - xid.ul[0] = fork->slot_ctx->slot_bank.slot; + xid.ul[0] = fork->slot_ctx->slot; /* push a new transaction on the stack */ fd_funk_txn_start_write( ctx->funk ); fork->slot_ctx->funk_txn = fd_funk_txn_prepare(ctx->funk, fork->slot_ctx->funk_txn, &xid, 1); + + fork->slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( fork->slot_ctx->bank_mgr_mem ), fork->slot_ctx->funk, fork->slot_ctx->funk_txn ); + + ulong * slot_ptr = fd_bank_mgr_slot_modify( fork->slot_ctx->bank_mgr ); + *slot_ptr = fork->slot_ctx->slot; + fd_bank_mgr_slot_save( fork->slot_ctx->bank_mgr ); + fd_funk_txn_end_write( ctx->funk ); /* We must invalidate all of the sysvar cache entries in the case that @@ -1459,6 +1478,8 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, send_exec_epoch_msg( ctx, stem, fork->slot_ctx ); } + ctx->bank_mgr = fd_bank_mgr_join( ctx->bank_mgr, ctx->funk, fork->slot_ctx->funk_txn ); + /* At this point we need to notify all of the exec tiles and tell them that a new slot is ready to be published. At this point, we should also mark the tile as not being ready. */ @@ -1497,18 +1518,21 @@ init_poh( fd_replay_tile_ctx_t * ctx ) { FD_LOG_INFO(( "sending init msg" )); fd_replay_out_ctx_t * bank_out = &ctx->bank_out[ 0UL ]; fd_poh_init_msg_t * msg = fd_chunk_to_laddr( bank_out->mem, bank_out->chunk ); - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( ctx->epoch_ctx ); - msg->hashcnt_per_tick = ctx->epoch_ctx->epoch_bank.hashes_per_tick; - msg->ticks_per_slot = ctx->epoch_ctx->epoch_bank.ticks_per_slot; - msg->tick_duration_ns = (ulong)(epoch_bank->ns_per_slot / epoch_bank->ticks_per_slot); - if( ctx->slot_ctx->slot_bank.block_hash_queue.last_hash ) { - memcpy(msg->last_entry_hash, ctx->slot_ctx->slot_bank.block_hash_queue.last_hash->uc, sizeof(fd_hash_t)); + FD_TEST( ctx->bank_mgr && ctx->bank_mgr->funk && ctx->bank_mgr->funk_txn ); + msg->hashcnt_per_tick = *(fd_bank_mgr_hashes_per_tick_query( ctx->bank_mgr )); + msg->ticks_per_slot = *(fd_bank_mgr_ticks_per_slot_query( ctx->bank_mgr )); + msg->tick_duration_ns = (ulong)(*fd_bank_mgr_ns_per_slot_query( ctx->bank_mgr ) / *(fd_bank_mgr_ticks_per_slot_query( ctx->bank_mgr ))); + + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( ctx->bank_mgr ); + fd_hash_t * last_hash = fd_block_hash_queue_last_hash_join( bhq ); + if( last_hash ) { + memcpy(msg->last_entry_hash, last_hash, sizeof(fd_hash_t)); } else { memset(msg->last_entry_hash, 0UL, sizeof(fd_hash_t)); } - msg->tick_height = ctx->slot_ctx->slot_bank.slot * msg->ticks_per_slot; + msg->tick_height = ctx->slot_ctx->slot * msg->ticks_per_slot; - ulong sig = fd_disco_replay_old_sig( ctx->slot_ctx->slot_bank.slot, REPLAY_FLAG_INIT ); + ulong sig = fd_disco_replay_old_sig( ctx->slot_ctx->slot, REPLAY_FLAG_INIT ); fd_mcache_publish( bank_out->mcache, bank_out->depth, bank_out->seq, sig, bank_out->chunk, sizeof(fd_poh_init_msg_t), 0UL, 0UL, 0UL ); bank_out->chunk = fd_dcache_compact_next( bank_out->chunk, sizeof(fd_poh_init_msg_t), bank_out->chunk0, bank_out->wmark ); bank_out->seq = fd_seq_inc( bank_out->seq, 1UL ); @@ -1555,7 +1579,7 @@ prepare_first_batch_execution( fd_replay_tile_ctx_t * ctx, fd_stem_context_t * s /**********************************************************************/ if( ctx->capture_ctx ) { - fd_solcap_writer_set_slot( ctx->capture_ctx->capture, fork->slot_ctx->slot_bank.slot ); + fd_solcap_writer_set_slot( ctx->capture_ctx->capture, fork->slot_ctx->slot ); } } @@ -1629,6 +1653,8 @@ exec_slice( fd_replay_tile_ctx_t * ctx, fd_runtime_public_txn_msg_t * exec_msg = (fd_runtime_public_txn_msg_t *)fd_chunk_to_laddr( exec_out->mem, exec_out->chunk ); memcpy( &exec_msg->txn, &txn_p, sizeof(fd_txn_p_t) ); + /* Iterate and check/update all program ids? */ + fd_fork_t * fork = fd_fork_frontier_ele_query( ctx->forks->frontier, &slot, NULL, @@ -1680,38 +1706,41 @@ exec_slice( fd_replay_tile_ctx_t * ctx, FD_LOG_DEBUG(( "[%s] BLOCK EXECUTION COMPLETE", __func__ )); - /* At this point, the entire block has been executed. */ - fd_fork_t * fork = fd_fork_frontier_ele_query( ctx->forks->frontier, - &slot, - NULL, - ctx->forks->pool ); - if( FD_UNLIKELY( !fork ) ) { - FD_LOG_ERR(( "Unable to select a fork" )); - } + /* At this point, the entire block has been executed. */ + fd_fork_t * fork = fd_fork_frontier_ele_query( ctx->forks->frontier, + &slot, + NULL, + ctx->forks->pool ); + if( FD_UNLIKELY( !fork ) ) { + FD_LOG_ERR(( "Unable to select a fork" )); + } - fd_microblock_hdr_t * hdr = (fd_microblock_hdr_t*)fd_type_pun( ctx->mbatch + ctx->slice_exec_ctx.last_mblk_off ); + fd_microblock_hdr_t * hdr = (fd_microblock_hdr_t*)fd_type_pun( ctx->mbatch + ctx->slice_exec_ctx.last_mblk_off ); - // Copy block hash to slot_bank poh for updating the sysvars - fd_block_map_query_t query[1] = { 0 }; - fd_block_map_prepare( ctx->blockstore->block_map, &ctx->curr_slot, NULL, query, FD_MAP_FLAG_BLOCKING ); - fd_block_info_t * block_info = fd_block_map_query_ele( query ); + // Copy block hash to slot_bank poh for updating the sysvars + fd_block_map_query_t query[1] = { 0 }; + fd_block_map_prepare( ctx->blockstore->block_map, &ctx->curr_slot, NULL, query, FD_MAP_FLAG_BLOCKING ); + fd_block_info_t * block_info = fd_block_map_query_ele( query ); - memcpy( fork->slot_ctx->slot_bank.poh.uc, hdr->hash, sizeof(fd_hash_t) ); - block_info->flags = fd_uchar_set_bit( block_info->flags, FD_BLOCK_FLAG_PROCESSED ); - FD_COMPILER_MFENCE(); - block_info->flags = fd_uchar_clear_bit( block_info->flags, FD_BLOCK_FLAG_REPLAYING ); - memcpy( &block_info->block_hash, hdr->hash, sizeof(fd_hash_t) ); - memcpy( &block_info->bank_hash, &fork->slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); + FD_BANK_MGR_DECL( bank_mgr, ctx->slot_ctx->funk, ctx->slot_ctx->funk_txn ); + fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + memcpy( poh->hash, hdr->hash, sizeof(fd_hash_t) ); + fd_bank_mgr_poh_save( bank_mgr ); + block_info->flags = fd_uchar_set_bit( block_info->flags, FD_BLOCK_FLAG_PROCESSED ); + FD_COMPILER_MFENCE(); + block_info->flags = fd_uchar_clear_bit( block_info->flags, FD_BLOCK_FLAG_REPLAYING ); + memcpy( &block_info->block_hash, hdr->hash, sizeof(fd_hash_t) ); + memcpy( &block_info->bank_hash, &fork->slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); - fd_block_map_publish( query ); - ctx->flags = EXEC_FLAG_FINISHED_SLOT; + fd_block_map_publish( query ); + ctx->flags = EXEC_FLAG_FINISHED_SLOT; - ctx->slice_exec_ctx.last_batch = 0; - ctx->slice_exec_ctx.txns_rem = 0; - ctx->slice_exec_ctx.mblks_rem = 0; - ctx->slice_exec_ctx.sz = 0; - ctx->slice_exec_ctx.wmark = 0; - ctx->slice_exec_ctx.last_mblk_off = 0; + ctx->slice_exec_ctx.last_batch = 0; + ctx->slice_exec_ctx.txns_rem = 0; + ctx->slice_exec_ctx.mblks_rem = 0; + ctx->slice_exec_ctx.sz = 0; + ctx->slice_exec_ctx.wmark = 0; + ctx->slice_exec_ctx.last_mblk_off = 0; } } @@ -1809,10 +1838,15 @@ handle_slice( fd_replay_tile_ctx_t * ctx, static void kickoff_repair_orphans( fd_replay_tile_ctx_t * ctx, fd_stem_context_t * stem ) { + ctx->slot_ctx->slot = ctx->curr_slot; + FD_LOG_WARNING(("BLOCKSTORE INIT 2 %lu", ctx->curr_slot)); + fd_blockstore_init( ctx->slot_ctx->blockstore, + ctx->blockstore_fd, + FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, + &ctx->slot_ctx->slot_bank, + ctx->slot_ctx->slot ); - fd_blockstore_init( ctx->slot_ctx->blockstore, ctx->blockstore_fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &ctx->slot_ctx->slot_bank ); - - fd_fseq_update( ctx->published_wmark, ctx->slot_ctx->slot_bank.slot ); + fd_fseq_update( ctx->published_wmark, ctx->slot_ctx->slot ); publish_stake_weights( ctx, stem, ctx->slot_ctx ); } @@ -1840,7 +1874,7 @@ read_snapshot( void * _ctx, if( strcmp( snapshot, "funk" )==0 || strncmp( snapshot, "wksp:", 5 )==0 ) { /* Funk already has a snapshot loaded */ fd_runtime_recover_banks( ctx->slot_ctx, 1, 1, ctx->runtime_spad ); - base_slot = ctx->slot_ctx->slot_bank.slot; + base_slot = ctx->slot_ctx->slot; kickoff_repair_orphans( ctx, stem ); } else { @@ -1873,6 +1907,8 @@ read_snapshot( void * _ctx, /* Load the prefetch manifest, and initialize the status cache and slot context, so that we can use these to kick off repair. */ fd_snapshot_load_prefetch_manifest( tmp_snap_ctx ); + ctx->curr_slot = ctx->slot_ctx->slot; + FD_LOG_WARNING(( "KICKOFF REPAIR ORPHANS 1 %lu", ctx->slot_ctx->slot)); kickoff_repair_orphans( ctx, stem ); } @@ -1898,7 +1934,7 @@ read_snapshot( void * _ctx, if( strlen( incremental )<=0UL ) { fd_snapshot_load_manifest_and_status_cache( snap_ctx, NULL, FD_SNAPSHOT_RESTORE_MANIFEST | FD_SNAPSHOT_RESTORE_STATUS_CACHE ); - + ctx->curr_slot = ctx->slot_ctx->slot; kickoff_repair_orphans( ctx, stem ); /* If we don't have an incremental snapshot, we can still kick off sending the stake weights and snapshot slot to repair. */ @@ -1908,7 +1944,7 @@ read_snapshot( void * _ctx, fd_snapshot_load_manifest_and_status_cache( snap_ctx, NULL, FD_SNAPSHOT_RESTORE_NONE ); } base_slot = fd_snapshot_get_slot( snap_ctx ); - + FD_LOG_WARNING(("BASE SLOT: %lu", base_slot)); fd_snapshot_load_accounts( snap_ctx ); fd_snapshot_load_fini( snap_ctx ); } @@ -1932,7 +1968,7 @@ read_snapshot( void * _ctx, } fd_runtime_update_leaders( ctx->slot_ctx, - ctx->slot_ctx->slot_bank.slot, + ctx->slot_ctx->slot, ctx->runtime_spad ); FD_LOG_NOTICE(( "starting fd_bpf_scan_and_create_bpf_program_cache_entry..." )); @@ -1966,23 +2002,28 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, ctx->exec_spad_cnt, ctx->runtime_spad ); - ulong snapshot_slot = ctx->slot_ctx->slot_bank.slot; + ulong snapshot_slot = ctx->slot_ctx->slot; if( FD_UNLIKELY( !snapshot_slot ) ) { /* Genesis-specific setup. */ /* FIXME: This branch does not set up a new block exec ctx properly. Needs to do whatever prepare_new_block_execution does, but just hacking that in breaks stuff. */ fd_runtime_update_leaders( ctx->slot_ctx, - ctx->slot_ctx->slot_bank.slot, + ctx->slot_ctx->slot, ctx->runtime_spad ); ctx->slot_ctx->slot_bank.prev_slot = 0UL; - ctx->slot_ctx->slot_bank.slot = 1UL; + ctx->slot_ctx->slot = 1UL; + + FD_BANK_MGR_DECL( bank_mgr, ctx->slot_ctx->funk, ctx->slot_ctx->funk_txn ); - ulong hashcnt_per_slot = ctx->slot_ctx->epoch_ctx->epoch_bank.hashes_per_tick * ctx->slot_ctx->epoch_ctx->epoch_bank.ticks_per_slot; + ulong hashcnt_per_slot = *(fd_bank_mgr_hashes_per_tick_query( bank_mgr )) * *(fd_bank_mgr_ticks_per_slot_query( bank_mgr )); + fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + fd_hash_t poh_hash = *poh; while(hashcnt_per_slot--) { - fd_sha256_hash( ctx->slot_ctx->slot_bank.poh.uc, 32UL, ctx->slot_ctx->slot_bank.poh.uc ); + fd_sha256_hash( poh->hash, 32UL, &poh_hash ); } + fd_bank_mgr_poh_save( bank_mgr ); FD_TEST( fd_runtime_block_execute_prepare( ctx->slot_ctx, ctx->runtime_spad ) == 0 ); fd_runtime_block_info_t info = { .signature_cnt = 0 }; @@ -2001,7 +2042,7 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, &exec_para_ctx_block_finalize ); ctx->slot_ctx->slot_bank.prev_slot = 0UL; - ctx->slot_ctx->slot_bank.slot = 1UL; + ctx->slot_ctx->slot = 1UL; snapshot_slot = 1UL; fd_exec_para_cb_ctx_t exec_para_ctx_bpf = { @@ -2031,7 +2072,15 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, fd_fork_t * snapshot_fork = fd_forks_init( ctx->forks, ctx->slot_ctx ); FD_TEST( snapshot_fork ); - fd_epoch_init( ctx->epoch, &snapshot_fork->slot_ctx->epoch_ctx->epoch_bank ); + + FD_BANK_MGR_DECL( bank_mgr, ctx->funk, snapshot_fork->slot_ctx->funk_txn ); + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_query( bank_mgr ); + ulong * eah_stop_slot = fd_bank_mgr_eah_stop_slot_query( bank_mgr ); + + fd_epoch_init( ctx->epoch, + *eah_start_slot, + *eah_stop_slot, + &snapshot_fork->slot_ctx->epoch_ctx->epoch_bank.stakes.vote_accounts ); fd_ghost_init( ctx->ghost, snapshot_slot ); fd_funk_rec_key_t key = { 0 }; @@ -2098,6 +2147,9 @@ init_snapshot( fd_replay_tile_ctx_t * ctx, uchar * slot_ctx_mem = fd_spad_alloc_check( ctx->runtime_spad, FD_EXEC_SLOT_CTX_ALIGN, FD_EXEC_SLOT_CTX_FOOTPRINT ); ctx->slot_ctx = fd_exec_slot_ctx_join( fd_exec_slot_ctx_new( slot_ctx_mem, ctx->runtime_spad ) ); + + ctx->slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( ctx->slot_ctx->bank_mgr_mem ), ctx->funk, NULL ); + ctx->slot_ctx->funk = ctx->funk; ctx->slot_ctx->blockstore = ctx->blockstore; ctx->slot_ctx->epoch_ctx = ctx->epoch_ctx; @@ -2123,11 +2175,13 @@ init_snapshot( fd_replay_tile_ctx_t * ctx, ctx->runtime_spad ); /* We call this after fd_runtime_read_genesis, which sets up the slot_bank needed in blockstore_init. */ - /* FIXME We should really only call this once. */ + /* FIXME: We should really only call this once. */ + FD_LOG_WARNING(("BLOCKSTORE INIT 1 %lu", ctx->curr_slot)); fd_blockstore_init( ctx->slot_ctx->blockstore, ctx->blockstore_fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, - &ctx->slot_ctx->slot_bank ); + &ctx->slot_ctx->slot_bank, + ctx->curr_slot ); ctx->epoch_ctx->bank_hash_cmp = ctx->bank_hash_cmp; ctx->epoch_ctx->runtime_public = ctx->runtime_public; init_after_snapshot( ctx, stem ); @@ -2137,6 +2191,7 @@ init_snapshot( fd_replay_tile_ctx_t * ctx, } /* Redirect ctx->slot_ctx to point to the memory inside forks. */ + FD_LOG_WARNING(("CURR SLOT %lu", ctx->curr_slot)); fd_fork_t * fork = fd_forks_query( ctx->forks, ctx->curr_slot ); ctx->slot_ctx = fork->slot_ctx; @@ -2150,7 +2205,7 @@ init_snapshot( fd_replay_tile_ctx_t * ctx, ulong curr_slot = ctx->curr_slot; ulong block_entry_height = 0; - if( is_snapshot ){ + if( is_snapshot ) { for(;;){ fd_block_map_query_t query[1] = { 0 }; int err = fd_block_map_query_try( ctx->blockstore->block_map, &curr_slot, NULL, query, 0 ); @@ -2240,7 +2295,12 @@ publish_votes_to_plugin( fd_replay_tile_ctx_t * ctx, fd_clock_timestamp_vote_t_mapnode_t query; memcpy( query.elem.pubkey.uc, n->elem.key.uc, 32UL ); - fd_clock_timestamp_vote_t_mapnode_t * res = fd_clock_timestamp_vote_t_map_find( fork->slot_ctx->slot_bank.timestamp_votes.votes_pool, fork->slot_ctx->slot_bank.timestamp_votes.votes_root, &query ); + FD_BANK_MGR_DECL( bank_mgr, ctx->funk, fork->slot_ctx->funk_txn ); + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( bank_mgr ); + fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_root = fd_clock_timestamp_votes_votes_root_join( clock_timestamp_votes ); + fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_pool = fd_clock_timestamp_votes_votes_pool_join( clock_timestamp_votes ); + + fd_clock_timestamp_vote_t_mapnode_t * res = fd_clock_timestamp_vote_t_map_find( timestamp_votes_pool, timestamp_votes_root, &query ); fd_vote_update_msg_t * msg = (fd_vote_update_msg_t *)(dst + sizeof(ulong) + i*112U); memset( msg, 0, 112U ); @@ -2419,7 +2479,9 @@ after_credit( fd_replay_tile_ctx_t * ctx, /**************************************************************************************************/ fd_runtime_block_info_t runtime_block_info[1]; - runtime_block_info->signature_cnt = fork->slot_ctx->signature_cnt; + FD_BANK_MGR_DECL( bank_mgr, ctx->funk, fork->slot_ctx->funk_txn ); + ulong * signature_cnt = fd_bank_mgr_signature_cnt_query( bank_mgr ); + runtime_block_info->signature_cnt = *signature_cnt; ctx->block_finalizing = 0; @@ -2542,11 +2604,17 @@ after_credit( fd_replay_tile_ctx_t * ctx, /* Prepare bank for the next execution and write to debugging files */ /**********************************************************************/ - ulong prev_slot = child->slot_ctx->slot_bank.slot; - child->slot_ctx->slot_bank.slot = curr_slot; - child->slot_ctx->slot_bank.collected_execution_fees = 0UL; - child->slot_ctx->slot_bank.collected_priority_fees = 0UL; - child->slot_ctx->slot_bank.collected_rent = 0UL; + ulong prev_slot = child->slot_ctx->slot; + child->slot_ctx->slot = curr_slot; + + FD_BANK_MGR_DECL( bank_mgr_post, ctx->funk, ctx->slot_ctx->funk_txn ); + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( bank_mgr_post ); + *execution_fees = 0UL; + fd_bank_mgr_execution_fees_save( bank_mgr_post ); + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( bank_mgr ); + *priority_fees = 0UL; + fd_bank_mgr_priority_fees_save( bank_mgr ); if( FD_UNLIKELY( ctx->slots_replayed_file ) ) { FD_LOG_DEBUG(( "writing %lu to slots file", prev_slot )); @@ -2753,6 +2821,7 @@ unprivileged_init( fd_topo_t * topo, void * forks_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_forks_align(), fd_forks_footprint( FD_BLOCK_MAX ) ); void * ghost_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_ghost_align(), fd_ghost_footprint( FD_BLOCK_MAX ) ); void * tower_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_align(), fd_tower_footprint() ); + void * bank_mgr_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_bank_mgr_align(), fd_bank_mgr_footprint() ); for( ulong i = 0UL; ibmtree[i] = FD_SCRATCH_ALLOC_APPEND( l, FD_BMTREE_COMMIT_ALIGN, FD_BMTREE_COMMIT_FOOTPRINT(0) ); } @@ -2800,6 +2869,12 @@ unprivileged_init( fd_topo_t * topo, FD_LOG_NOTICE(( "Snapshot intervals full=%lu incremental=%lu", ctx->snapshot_interval, ctx->incremental_interval )); + /**********************************************************************/ + /* bank_mgr */ + /**********************************************************************/ + + ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( bank_mgr_mem ), ctx->funk, NULL ); + /**********************************************************************/ /* funk */ /**********************************************************************/ @@ -2959,10 +3034,15 @@ unprivileged_init( fd_topo_t * topo, ctx->bank_hash_cmp = fd_bank_hash_cmp_join( fd_bank_hash_cmp_new( bank_hash_cmp_shmem ) ); ctx->epoch_ctx = fd_exec_epoch_ctx_join( fd_exec_epoch_ctx_new( epoch_ctx_mem, tile->replay.max_vote_accounts ) ); - if( FD_UNLIKELY( sscanf( tile->replay.cluster_version, "%u.%u.%u", &ctx->epoch_ctx->epoch_bank.cluster_version[0], &ctx->epoch_ctx->epoch_bank.cluster_version[1], &ctx->epoch_ctx->epoch_bank.cluster_version[2] )!=3 ) ) { + FD_BANK_MGR_DECL( bank_mgr, ctx->funk, NULL ); + fd_cluster_version_t * cluster_version = fd_bank_mgr_cluster_version_modify( bank_mgr ); + + if( FD_UNLIKELY( sscanf( tile->replay.cluster_version, "%u.%u.%u", &cluster_version->major, &cluster_version->minor, &cluster_version->patch )!=3 ) ) { FD_LOG_ERR(( "failed to decode cluster version, configured as \"%s\"", tile->replay.cluster_version )); } - fd_features_enable_cleaned_up( &ctx->epoch_ctx->features, ctx->epoch_ctx->epoch_bank.cluster_version ); + fd_bank_mgr_cluster_version_save( bank_mgr ); + + fd_features_enable_cleaned_up( &ctx->epoch_ctx->features, cluster_version ); char const * one_off_features[16]; for (ulong i = 0; i < tile->replay.enable_features_cnt; i++) { diff --git a/src/discof/restart/fd_restart_tile.c b/src/discof/restart/fd_restart_tile.c index 6d7d8a0500..6f6c7beb84 100644 --- a/src/discof/restart/fd_restart_tile.c +++ b/src/discof/restart/fd_restart_tile.c @@ -287,15 +287,15 @@ after_frag( fd_restart_tile_ctx_t * ctx, FD_TEST( !fd_funk_rec_query_test( query ) ); /* Add a hard fork into the slot bank */ - ulong old_len = slot_bank->hard_forks.hard_forks_len; - ctx->new_hard_forks_len = old_len + 1; - ctx->new_hard_forks = fd_spad_alloc( ctx->runtime_spad, 8, ctx->new_hard_forks_len*sizeof(fd_slot_pair_t) ); - fd_memcpy( ctx->new_hard_forks, slot_bank->hard_forks.hard_forks, old_len*sizeof(fd_slot_pair_t) ); + // ulong old_len = slot_bank->hard_forks.hard_forks_len; + // ctx->new_hard_forks_len = old_len + 1; + // ctx->new_hard_forks = fd_spad_alloc( ctx->runtime_spad, 8, ctx->new_hard_forks_len*sizeof(fd_slot_pair_t) ); + // fd_memcpy( ctx->new_hard_forks, slot_bank->hard_forks.hard_forks, old_len*sizeof(fd_slot_pair_t) ); - ctx->new_hard_forks[ old_len ].slot = ctx->restart->heaviest_fork_slot; - ctx->new_hard_forks[ old_len ].val = 1; - slot_bank->hard_forks.hard_forks = ctx->new_hard_forks; - slot_bank->hard_forks.hard_forks_len = ctx->new_hard_forks_len; + // ctx->new_hard_forks[ old_len ].slot = ctx->restart->heaviest_fork_slot; + // ctx->new_hard_forks[ old_len ].val = 1; + // slot_bank->hard_forks.hard_forks = ctx->new_hard_forks; + // slot_bank->hard_forks.hard_forks_len = ctx->new_hard_forks_len; /* Write the slot bank back to funk, referencing fd_runtime_save_slot_bank */ int funk_err = 0; @@ -440,8 +440,9 @@ after_credit( fd_restart_tile_ctx_t * ctx, ulong buf_len = 0; uchar * buf = fd_chunk_to_laddr( ctx->gossip_out_mem, ctx->gossip_out_chunk ); + /* FIXME: this has an invalid slot number. */ fd_restart_init( ctx->restart, - slot_bank->slot, + 0UL, &slot_bank->banks_hash, epoch_stakes, &ctx->epoch_bank.epoch_schedule, diff --git a/src/discof/rpcserver/fd_rpc_service.c b/src/discof/rpcserver/fd_rpc_service.c index 0d18597ddb..d4affc843d 100644 --- a/src/discof/rpcserver/fd_rpc_service.c +++ b/src/discof/rpcserver/fd_rpc_service.c @@ -1463,8 +1463,9 @@ method_getSupply(struct json_values* values, fd_rpc_ctx_t * ctx) { return 0; } fd_webserver_t * ws = &ctx->global->ws; + ulong capitalization = ULONG_MAX; /* FIXME: This is broken */ fd_web_reply_sprintf( ws, "{\"jsonrpc\":\"2.0\",\"result\":{\"context\":{\"apiVersion\":\"" FIREDANCER_VERSION "\",\"slot\":%lu},\"value\":{\"circulating\":%lu,\"nonCirculating\":%lu,\"nonCirculatingAccounts\":[],\"total\":%lu}},\"id\":%s}", - slot, slot_bank->capitalization, 0UL, slot_bank->capitalization, ctx->call_id); + slot, capitalization, 0UL, capitalization, ctx->call_id); } FD_SPAD_FRAME_END; return 0; } @@ -1638,9 +1639,10 @@ method_getTransactionCount(struct json_values* values, fd_rpc_ctx_t * ctx) { fd_method_error( ctx, -1, "slot bank %lu not found", slot ); return 0; } + /* FIXME: should be the transaction count here */ fd_web_reply_sprintf( ws, "{\"jsonrpc\":\"2.0\",\"result\":%lu,\"id\":%s}" CRLF, - info->slot_exec.transaction_count, + 0UL, ctx->call_id ); } FD_SPAD_FRAME_END; return 0; @@ -1684,8 +1686,8 @@ method_getVoteAccounts(struct json_values* values, fd_rpc_ctx_t * ctx) { int needcomma = 0; - fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_root = slot_bank->timestamp_votes.votes_root; - fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_pool = slot_bank->timestamp_votes.votes_pool; + fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_root = NULL; + fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_pool = NULL; fd_vote_accounts_pair_t_mapnode_t * vote_acc_root = slot_bank->epoch_stakes.vote_accounts_root; fd_vote_accounts_pair_t_mapnode_t * vote_acc_pool = slot_bank->epoch_stakes.vote_accounts_pool; for( fd_vote_accounts_pair_t_mapnode_t* n = fd_vote_accounts_pair_t_map_minimum(vote_acc_pool, vote_acc_root); diff --git a/src/flamenco/fd_flamenco_base.h b/src/flamenco/fd_flamenco_base.h index 0897e4e2ee..568fd24e46 100644 --- a/src/flamenco/fd_flamenco_base.h +++ b/src/flamenco/fd_flamenco_base.h @@ -17,6 +17,7 @@ #define FD_FUNK_KEY_TYPE_ACC ((uchar)1) #define FD_FUNK_KEY_TYPE_ELF_CACHE ((uchar)2) +#define FD_FUNK_KEY_TYPE_BANK_MGR ((uchar)3) #define FD_FUNK_KEY_SLOT_BANK ((uchar)6) #define FD_FUNK_KEY_EPOCH_BANK ((uchar)7) @@ -95,6 +96,9 @@ typedef struct fd_exec_instr_ctx fd_exec_instr_ctx_t; struct fd_acc_mgr; typedef struct fd_acc_mgr fd_acc_mgr_t; +struct fd_bank_mgr; +typedef struct fd_bank_mgr fd_bank_mgr_t; + struct fd_capture_ctx; typedef struct fd_capture_ctx fd_capture_ctx_t; diff --git a/src/flamenco/features/Local.mk b/src/flamenco/features/Local.mk index 5c918a8a6c..538ed7dce5 100644 --- a/src/flamenco/features/Local.mk +++ b/src/flamenco/features/Local.mk @@ -1,2 +1,4 @@ +ifdef FD_HAS_INT128 $(call add-hdrs,fd_features.h fd_features_generated.h) $(call add-objs,fd_features fd_features_generated,fd_flamenco) +endif diff --git a/src/flamenco/features/fd_features.c b/src/flamenco/features/fd_features.c index 75d0904a7e..b07a76245a 100644 --- a/src/flamenco/features/fd_features.c +++ b/src/flamenco/features/fd_features.c @@ -19,13 +19,13 @@ fd_features_disable_all( fd_features_t * f ) { } void -fd_features_enable_cleaned_up( fd_features_t * f, uint cluster_version[3] ) { +fd_features_enable_cleaned_up( fd_features_t * f, fd_cluster_version_t const * cluster_version ) { for( fd_feature_id_t const * id = fd_feature_iter_init(); !fd_feature_iter_done( id ); id = fd_feature_iter_next( id ) ) { - if( ( id->cleaned_up[0]cleaned_up[0]==cluster_version[0] && id->cleaned_up[1]cleaned_up[0]==cluster_version[0] && id->cleaned_up[1]==cluster_version[1] && id->cleaned_up[2]<=cluster_version[2] ) ) { + if( ( id->cleaned_up[0]major ) || + ( id->cleaned_up[0]==cluster_version->major && id->cleaned_up[1]minor ) || + ( id->cleaned_up[0]==cluster_version->major && id->cleaned_up[1]==cluster_version->minor && id->cleaned_up[2]<=cluster_version->patch ) ) { fd_features_set( f, id, 0UL ); } else { fd_features_set( f, id, FD_FEATURE_DISABLED ); diff --git a/src/flamenco/features/fd_features.h b/src/flamenco/features/fd_features.h index fd8158acf0..71412b70fe 100644 --- a/src/flamenco/features/fd_features.h +++ b/src/flamenco/features/fd_features.h @@ -3,7 +3,7 @@ #include "../fd_flamenco_base.h" #include "fd_features_generated.h" - +#include "../types/fd_types.h" /* Macro FEATURE_ID_CNT expands to the number of features in fd_features_t. */ @@ -23,9 +23,9 @@ #define FD_FEATURE_SET_ACTIVE(_features, _feature_name, _slot) ((_features). _feature_name = _slot) #define FD_FEATURE_ACTIVE(_slot,_features,_feature_name) FD_FEATURE_ACTIVE_( _slot,_features,_feature_name ) -#define FD_FEATURE_JUST_ACTIVATED(_slot_ctx, _feature_name) FD_FEATURE_JUST_ACTIVATED_( _slot_ctx->slot_bank.slot, _slot_ctx->epoch_ctx->features, _feature_name ) +#define FD_FEATURE_JUST_ACTIVATED(_slot_ctx, _feature_name) FD_FEATURE_JUST_ACTIVATED_( _slot_ctx->slot, _slot_ctx->epoch_ctx->features, _feature_name ) #define FD_FEATURE_ACTIVE_OFFSET(_slot, _features, _offset) FD_FEATURE_ACTIVE_OFFSET_( _slot, _features, _offset ) -#define FD_FEATURE_JUST_ACTIVATED_OFFSET(_slot_ctx, _offset) FD_FEATURE_JUST_ACTIVATED_OFFSET_( _slot_ctx->slot_bank.slot, _slot_ctx->epoch_ctx->features, _offset ) +#define FD_FEATURE_JUST_ACTIVATED_OFFSET(_slot_ctx, _offset) FD_FEATURE_JUST_ACTIVATED_OFFSET_( _slot_ctx->slot, _slot_ctx->epoch_ctx->features, _offset ) /* fd_features_t is the current set of enabled feature flags. @@ -84,7 +84,7 @@ fd_features_enable_all( fd_features_t * ); of the Firedancer software and can't be disabled. */ void -fd_features_enable_cleaned_up( fd_features_t *, uint[3] ); +fd_features_enable_cleaned_up( fd_features_t *, fd_cluster_version_t const * ); /* fd_features_enable_one_offs enables all manually passed in features. */ diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index b16dcbc55d..698b6dbc89 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -4,6 +4,7 @@ #include "../runtime/fd_executor_err.h" #include "../runtime/fd_system_ids.h" #include "../runtime/fd_runtime.h" +#include "../runtime/fd_bank_mgr.h" #include "../runtime/context/fd_exec_slot_ctx.h" #include "../../ballet/siphash13/fd_siphash13.h" #include "../runtime/program/fd_program_util.h" @@ -55,17 +56,17 @@ validator( fd_inflation_t const * inflation, double year) { https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2095 */ static FD_FN_CONST ulong get_inflation_start_slot( fd_exec_slot_ctx_t * slot_ctx ) { - ulong devnet_and_testnet = FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, devnet_and_testnet ) ? slot_ctx->epoch_ctx->features.devnet_and_testnet : ULONG_MAX; + ulong devnet_and_testnet = FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, devnet_and_testnet ) ? slot_ctx->epoch_ctx->features.devnet_and_testnet : ULONG_MAX; ulong enable = ULONG_MAX; - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, full_inflation_vote ) && - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, full_inflation_enable ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, full_inflation_vote ) && + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, full_inflation_enable ) ) { enable = slot_ctx->epoch_ctx->features.full_inflation_enable; } ulong min_slot = fd_ulong_min( enable, devnet_and_testnet ); if( min_slot == ULONG_MAX ) { - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, pico_inflation ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, pico_inflation ) ) { min_slot = slot_ctx->epoch_ctx->features.pico_inflation; } else { min_slot = 0; @@ -93,9 +94,8 @@ get_inflation_num_slots( fd_exec_slot_ctx_t * slot_ctx, /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2121 */ static double slot_in_year_for_inflation( fd_exec_slot_ctx_t * slot_ctx ) { - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong num_slots = get_inflation_num_slots( slot_ctx, &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot ); - return (double)num_slots / (double)epoch_bank->slots_per_year; + ulong num_slots = get_inflation_num_slots( slot_ctx, &slot_ctx->epoch_ctx->epoch_bank.epoch_schedule, slot_ctx->slot ); + return (double)num_slots / (double)*(fd_bank_mgr_slots_per_year_query( slot_ctx->bank_mgr )); } /* For a given stake and vote_state, calculate how many points were earned (credits * stake) and new value @@ -274,10 +274,11 @@ get_slots_in_epoch( ulong epoch, /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank.rs#L2082 */ static double -epoch_duration_in_years( fd_epoch_bank_t const * epoch_bank, +epoch_duration_in_years( fd_exec_slot_ctx_t * slot_ctx, + fd_epoch_bank_t const * epoch_bank, ulong prev_epoch ) { ulong slots_in_epoch = get_slots_in_epoch( prev_epoch, epoch_bank ); - return (double)slots_in_epoch / (double) epoch_bank->slots_per_year; + return (double)slots_in_epoch / (double)*(fd_bank_mgr_slots_per_year_query( slot_ctx->bank_mgr )); } /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank.rs#L2128 */ @@ -288,10 +289,12 @@ calculate_previous_epoch_inflation_rewards( fd_exec_slot_ctx_t * fd_prev_epoch_inflation_rewards_t * rewards ) { double slot_in_year = slot_in_year_for_inflation( slot_ctx ); + fd_inflation_t * inflation = fd_bank_mgr_inflation_query( slot_ctx->bank_mgr ); + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - rewards->validator_rate = validator( &epoch_bank->inflation, slot_in_year ); - rewards->foundation_rate = foundation( &epoch_bank->inflation, slot_in_year ); - rewards->prev_epoch_duration_in_years = epoch_duration_in_years( epoch_bank, prev_epoch ); + rewards->validator_rate = validator( inflation, slot_in_year ); + rewards->foundation_rate = foundation( inflation, slot_in_year ); + rewards->prev_epoch_duration_in_years = epoch_duration_in_years( slot_ctx, epoch_bank, prev_epoch ); rewards->validator_rewards = (ulong)(rewards->validator_rate * (double)prev_epoch_capitalization * rewards->prev_epoch_duration_in_years); 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 )); } @@ -299,11 +302,11 @@ calculate_previous_epoch_inflation_rewards( fd_exec_slot_ctx_t * /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/programs/stake/src/lib.rs#L29 */ static ulong get_minimum_stake_delegation( fd_exec_slot_ctx_t * slot_ctx ) { - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, stake_minimum_delegation_for_rewards ) ) { + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, stake_minimum_delegation_for_rewards ) ) { return 0UL; } - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, stake_raise_minimum_delegation_to_1_sol ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, stake_raise_minimum_delegation_to_1_sol ) ) { return LAMPORTS_PER_SOL; } @@ -385,7 +388,7 @@ calculate_reward_points_partitioned( fd_exec_slot_ctx_t * slot_ctx, int _err[1]; ulong new_warmup_cooldown_rate_epoch_val = 0UL; ulong * new_warmup_cooldown_rate_epoch = &new_warmup_cooldown_rate_epoch_val; - int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot_bank.slot, + int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot, slot_ctx->sysvar_cache, &slot_ctx->epoch_ctx->features, slot_ctx->runtime_wksp, @@ -451,7 +454,7 @@ calculate_stake_vote_rewards_account( fd_epoch_info_t const * fd_pubkey_t const * stake_acc = &stake_info->account; fd_stake_t const * stake = &stake_info->stake; - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, stake_minimum_delegation_for_rewards ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, stake_minimum_delegation_for_rewards ) ) { if( stake->delegation.stakeslot_bank.slot, + int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot, slot_ctx->sysvar_cache, &slot_ctx->epoch_ctx->features, slot_ctx->runtime_wksp, @@ -755,7 +758,7 @@ hash_rewards_into_partitions( fd_exec_slot_ctx_t * slot_c These will all use the same pool - we do not re-allocate the stake rewards, only move them into partitions. */ result->partitioned_stake_rewards.pool = stake_reward_calculation->pool; ulong num_partitions = get_reward_distribution_num_blocks( &fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx )->epoch_schedule, - slot_ctx->slot_bank.slot, + slot_ctx->slot, stake_reward_calculation->stake_rewards_len ); result->partitioned_stake_rewards.partitions_len = num_partitions; result->partitioned_stake_rewards.partitions = fd_spad_alloc( runtime_spad, @@ -818,9 +821,9 @@ calculate_rewards_for_partitioning( fd_exec_slot_ctx_t * slot_ fd_spad_t * runtime_spad ) { /* https://github.com/anza-xyz/agave/blob/7117ed9653ce19e8b2dea108eff1f3eb6a3378a7/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L227 */ fd_prev_epoch_inflation_rewards_t rewards; - calculate_previous_epoch_inflation_rewards( slot_ctx, slot_ctx->slot_bank.capitalization, prev_epoch, &rewards ); - fd_slot_bank_t const * slot_bank = &slot_ctx->slot_bank; + ulong * capitalization = fd_bank_mgr_capitalization_query( slot_ctx->bank_mgr ); + calculate_previous_epoch_inflation_rewards( slot_ctx, *capitalization, prev_epoch, &rewards ); fd_calculate_validator_rewards_result_t validator_result[1] = {0}; calculate_validator_rewards( slot_ctx, @@ -848,7 +851,8 @@ calculate_rewards_for_partitioning( fd_exec_slot_ctx_t * slot_ result->validator_rate = rewards.validator_rate; result->foundation_rate = rewards.foundation_rate; result->prev_epoch_duration_in_years = rewards.prev_epoch_duration_in_years; - result->capitalization = slot_bank->capitalization; + + result->capitalization = *(fd_bank_mgr_capitalization_query( slot_ctx->bank_mgr )); result->point_value = validator_result->point_value; } @@ -899,7 +903,7 @@ calculate_rewards_and_distribute_vote_rewards( fd_exec_slot_ctx_t * FD_LOG_ERR(( "Unable to modify vote account" )); } - vote_rec->vt->set_slot( vote_rec, slot_ctx->slot_bank.slot ); + vote_rec->vt->set_slot( vote_rec, slot_ctx->slot ); if( FD_UNLIKELY( vote_rec->vt->checked_add_lamports( vote_rec, vote_reward_node->elem.vote_rewards ) ) ) { FD_LOG_ERR(( "Adding lamports to vote account would cause overflow" )); @@ -918,7 +922,9 @@ calculate_rewards_and_distribute_vote_rewards( fd_exec_slot_ctx_t * FD_LOG_ERR(( "Unexpected rewards calculation result" )); } - slot_ctx->slot_bank.capitalization += result->distributed_rewards; + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); + *capitalization += result->distributed_rewards; + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); /* Cheap because this doesn't copy all the rewards, just pointers to the dlist */ result->stake_rewards_by_partition = rewards_calc_result->stake_rewards_by_partition; @@ -942,7 +948,7 @@ distribute_epoch_reward_to_stake_acc( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_ERR(( "Unable to modify stake account" )); } - stake_acc_rec->vt->set_slot( stake_acc_rec, slot_ctx->slot_bank.slot ); + stake_acc_rec->vt->set_slot( stake_acc_rec, slot_ctx->slot ); fd_stake_state_v2_t stake_state[1] = {0}; if( fd_stake_get_state( stake_acc_rec, stake_state ) != 0 ) { @@ -1028,8 +1034,8 @@ distribute_epoch_rewards_in_partition( fd_partitioned_stake_rewards_dlist_t * pa } /* Update the epoch rewards sysvar with the amount distributed and burnt */ - if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { + if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { fd_sysvar_epoch_rewards_distribute( slot_ctx, lamports_distributed + lamports_burned, runtime_spad ); @@ -1037,7 +1043,9 @@ distribute_epoch_rewards_in_partition( fd_partitioned_stake_rewards_dlist_t * pa FD_LOG_DEBUG(( "lamports burned: %lu, lamports distributed: %lu", lamports_burned, lamports_distributed )); - slot_ctx->slot_bank.capitalization += lamports_distributed; + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); + *capitalization += lamports_distributed; + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); } /* Process reward distribution for the block if it is inside reward interval. @@ -1054,21 +1062,22 @@ fd_distribute_partitioned_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, (void)exec_spads; (void)exec_spad_cnt; + ulong * block_height = fd_bank_mgr_block_height_query( slot_ctx->bank_mgr ); + if( slot_ctx->slot_bank.epoch_reward_status.discriminant == fd_epoch_reward_status_enum_Inactive ) { return; } fd_start_block_height_and_rewards_t * status = &slot_ctx->slot_bank.epoch_reward_status.inner.Active; - fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; - ulong height = slot_bank->block_height; + ulong height = *block_height; fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank_const( slot_ctx->epoch_ctx ); ulong distribution_starting_block_height = status->distribution_starting_block_height; ulong distribution_end_exclusive = distribution_starting_block_height + status->partitioned_stake_rewards.partitions_len; /* TODO: track current epoch in epoch ctx? */ - ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_bank->slot, NULL ); + ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot, NULL ); if( FD_UNLIKELY( get_slots_in_epoch( epoch, epoch_bank ) <= status->partitioned_stake_rewards.partitions_len ) ) { FD_LOG_ERR(( "Should not be distributing rewards" )); } @@ -1148,7 +1157,7 @@ fd_begin_partitioned_rewards( fd_exec_slot_ctx_t * slot_ctx, runtime_spad ); /* https://github.com/anza-xyz/agave/blob/9a7bf72940f4b3cd7fc94f54e005868ce707d53d/runtime/src/bank/partitioned_epoch_rewards/calculation.rs#L62 */ - ulong distribution_starting_block_height = slot_ctx->slot_bank.block_height + REWARD_CALCULATION_NUM_BLOCKS; + ulong distribution_starting_block_height = *(fd_bank_mgr_block_height_query( slot_ctx->bank_mgr )) + REWARD_CALCULATION_NUM_BLOCKS; /* Set the epoch reward status to be active */ set_epoch_reward_status_active( slot_ctx, @@ -1201,12 +1210,12 @@ fd_rewards_recalculate_partitioned_rewards( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_NOTICE(( "epoch rewards is active" )); fd_epoch_schedule_t * epoch_schedule = &fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx )->epoch_schedule; - ulong epoch = fd_slot_to_epoch( epoch_schedule, slot_ctx->slot_bank.slot, NULL ); + ulong epoch = fd_slot_to_epoch( epoch_schedule, slot_ctx->slot, NULL ); ulong rewarded_epoch = fd_ulong_sat_sub( epoch, 1UL ); int _err[1] = {0}; ulong * new_warmup_cooldown_rate_epoch = fd_spad_alloc( runtime_spad, alignof(ulong), sizeof(ulong) ); - int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot_bank.slot, + int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot, slot_ctx->sysvar_cache, &slot_ctx->epoch_ctx->features, slot_ctx->runtime_wksp, diff --git a/src/flamenco/runtime/Local.mk b/src/flamenco/runtime/Local.mk index b05efdab93..7fc04eddb2 100644 --- a/src/flamenco/runtime/Local.mk +++ b/src/flamenco/runtime/Local.mk @@ -33,6 +33,9 @@ $(call add-objs,fd_cost_tracker,fd_flamenco) $(call add-hdrs,fd_runtime_public.h) $(call add-objs,fd_runtime_public,fd_flamenco) +$(call add-hdrs,fd_bank_mgr.h) +$(call add-objs,fd_bank_mgr,fd_flamenco) + $(call add-hdrs, tests/fd_dump_pb.h) $(call add-objs, tests/fd_dump_pb,fd_flamenco) diff --git a/src/flamenco/runtime/context/fd_exec_epoch_ctx.c b/src/flamenco/runtime/context/fd_exec_epoch_ctx.c index f7ba385bc6..ab800a953a 100644 --- a/src/flamenco/runtime/context/fd_exec_epoch_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_epoch_ctx.c @@ -2,6 +2,7 @@ #include #include "../sysvar/fd_sysvar_stake_history.h" #include "../fd_runtime_public.h" +#include "../fd_bank_mgr.h" /* TODO remove this */ #define MAX_LG_SLOT_CNT 10UL @@ -64,11 +65,11 @@ fd_exec_epoch_ctx_new( void * mem, fd_exec_epoch_ctx_bank_mem_setup( self ); - fd_features_disable_all( &self->features ); - self->epoch_bank.cluster_version[0] = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MAJOR; - self->epoch_bank.cluster_version[1] = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MINOR; - self->epoch_bank.cluster_version[2] = FD_DEFAULT_AGAVE_CLUSTER_VERSION_PATCH; - fd_features_enable_cleaned_up( &self->features, self->epoch_bank.cluster_version ); + // fd_features_disable_all( &self->features ); + // self->epoch_bank.cluster_version.major = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MAJOR; + // self->epoch_bank.cluster_version.minor = FD_DEFAULT_AGAVE_CLUSTER_VERSION_MINOR; + // self->epoch_bank.cluster_version.patch = FD_DEFAULT_AGAVE_CLUSTER_VERSION_PATCH; + // fd_features_enable_cleaned_up( &self->features, &self->epoch_bank.cluster_version ); FD_COMPILER_MFENCE(); self->magic = FD_EXEC_EPOCH_CTX_MAGIC; @@ -233,7 +234,6 @@ fd_exec_epoch_ctx_from_prev( fd_exec_epoch_ctx_t * self, self->bank_hash_cmp = prev->bank_hash_cmp; self->runtime_public = prev->runtime_public; - self->total_epoch_stake = 0UL; self->runtime_public->features = prev->features; /* large memcpy */ diff --git a/src/flamenco/runtime/context/fd_exec_epoch_ctx.h b/src/flamenco/runtime/context/fd_exec_epoch_ctx.h index 82847549f1..c46c017b8f 100644 --- a/src/flamenco/runtime/context/fd_exec_epoch_ctx.h +++ b/src/flamenco/runtime/context/fd_exec_epoch_ctx.h @@ -34,7 +34,6 @@ struct __attribute__((aligned(64UL))) fd_exec_epoch_ctx { fd_bank_hash_cmp_t * bank_hash_cmp; fd_runtime_public_t * runtime_public; int constipate_root; /* Used for constipation in offline replay. */ - ulong total_epoch_stake; }; #define FD_EXEC_EPOCH_CTX_ALIGN (alignof(fd_exec_epoch_ctx_t)) diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.c b/src/flamenco/runtime/context/fd_exec_slot_ctx.c index e0d47c33a2..44186ce0d1 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.c @@ -1,5 +1,6 @@ #include "fd_exec_slot_ctx.h" #include "fd_exec_epoch_ctx.h" +#include "../fd_bank_mgr.h" #include "../sysvar/fd_sysvar_epoch_schedule.h" #include "../program/fd_vote_program.h" #include "../../../ballet/lthash/fd_lthash.h" @@ -161,8 +162,6 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_solana_manifest_t const * manifest, fd_spad_t * runtime_spad ) { - fd_valloc_t valloc = fd_spad_virtual( runtime_spad ); - fd_exec_epoch_ctx_t * epoch_ctx = slot_ctx->epoch_ctx; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( epoch_ctx ); @@ -241,85 +240,184 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, /* Copy over fields */ - slot_ctx->slot_bank.parent_signature_cnt = oldbank->signature_count; - slot_ctx->slot_bank.tick_height = oldbank->tick_height; + slot_bank->prev_slot = oldbank->parent_slot; + fd_memcpy(&slot_bank->banks_hash, &oldbank->hash, sizeof(oldbank->hash)); + fd_memcpy(&slot_ctx->slot_bank.prev_banks_hash, &oldbank->parent_hash, sizeof(oldbank->parent_hash)); + fd_memcpy( &epoch_bank->epoch_schedule, &oldbank->epoch_schedule, sizeof(fd_epoch_schedule_t) ); + epoch_bank->rent = oldbank->rent_collector.rent; + fd_memcpy( &epoch_bank->rent, &oldbank->rent_collector.rent, sizeof(fd_rent_t) ); + fd_memcpy( &epoch_bank->rent_epoch_schedule, &oldbank->rent_collector.epoch_schedule, sizeof(fd_epoch_schedule_t) ); - if( oldbank->blockhash_queue.last_hash ) { - slot_bank->poh = *oldbank->blockhash_queue.last_hash; - } - slot_bank->slot = oldbank->slot; - slot_bank->prev_slot = oldbank->parent_slot; - slot_bank->banks_hash = oldbank->hash; - slot_ctx->slot_bank.prev_banks_hash = oldbank->parent_hash; - slot_bank->fee_rate_governor = oldbank->fee_rate_governor; - slot_bank->lamports_per_signature = manifest->lamports_per_signature; - slot_ctx->prev_lamports_per_signature = manifest->lamports_per_signature; - slot_ctx->slot_bank.parent_signature_cnt = oldbank->signature_count; - if( oldbank->hashes_per_tick ) { - epoch_bank->hashes_per_tick = *oldbank->hashes_per_tick; - } else { - epoch_bank->hashes_per_tick = 0; - } - epoch_bank->ticks_per_slot = oldbank->ticks_per_slot; - epoch_bank->ns_per_slot = oldbank->ns_per_slot; - epoch_bank->genesis_creation_time = oldbank->genesis_creation_time; - epoch_bank->slots_per_year = oldbank->slots_per_year; - slot_bank->max_tick_height = oldbank->max_tick_height; - epoch_bank->inflation = oldbank->inflation; - epoch_bank->epoch_schedule = oldbank->epoch_schedule; - epoch_bank->rent = oldbank->rent_collector.rent; - epoch_bank->rent_epoch_schedule = oldbank->rent_collector.epoch_schedule; - if( manifest->epoch_account_hash ) { - slot_bank->epoch_account_hash = *manifest->epoch_account_hash; + fd_funk_t * funk = slot_ctx->funk; + fd_funk_txn_t * funk_txn = slot_ctx->funk_txn; + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, funk, funk_txn ); + if( FD_UNLIKELY( !bank_mgr ) ) { + FD_LOG_ERR(( "Could not allocate bank manager" )); } - slot_bank->collected_rent = oldbank->collected_rent; - // did they not change the bank?! - slot_bank->collected_execution_fees = oldbank->collector_fees; - slot_bank->collected_priority_fees = 0; - slot_bank->capitalization = oldbank->capitalization; - slot_bank->block_height = oldbank->block_height; - slot_bank->transaction_count = oldbank->transaction_count; + /* Block Hash Queue */ + + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_modify( bank_mgr ); + + uchar * last_hash_mem = (uchar *)fd_ulong_align_up( (ulong)bhq + sizeof(fd_block_hash_queue_global_t), alignof(fd_hash_t) ); + uchar * ages_pool_mem = (uchar *)fd_ulong_align_up( (ulong)last_hash_mem + sizeof(fd_hash_t), fd_hash_hash_age_pair_t_map_align() ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( ages_pool_mem, 400 ) ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = NULL; + + bhq->last_hash_index = oldbank->blockhash_queue.last_hash_index; if( oldbank->blockhash_queue.last_hash ) { - slot_bank->block_hash_queue.last_hash = fd_valloc_malloc( valloc, FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); - *slot_bank->block_hash_queue.last_hash = *oldbank->blockhash_queue.last_hash; + fd_memcpy( last_hash_mem, oldbank->blockhash_queue.last_hash, sizeof(fd_hash_t) ); } else { - slot_bank->block_hash_queue.last_hash = NULL; + fd_memset( last_hash_mem, 0, sizeof(fd_hash_t) ); } + bhq->last_hash_offset = (ulong)last_hash_mem - (ulong)bhq; - slot_bank->block_hash_queue.last_hash_index = oldbank->blockhash_queue.last_hash_index; - slot_bank->block_hash_queue.max_age = oldbank->blockhash_queue.max_age; - slot_bank->block_hash_queue.ages_root = NULL; - - /* FIXME: Avoid using magic number for allocations */ - uchar * pool_mem = fd_spad_alloc_check( runtime_spad, fd_hash_hash_age_pair_t_map_align(), fd_hash_hash_age_pair_t_map_footprint( 400 ) ); - slot_bank->block_hash_queue.ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( pool_mem, 400 ) ); - for ( ulong i = 0; i < oldbank->blockhash_queue.ages_len; i++ ) { + for( ulong i=0UL; iblockhash_queue.ages_len; i++ ) { fd_hash_hash_age_pair_t * elem = &oldbank->blockhash_queue.ages[i]; - fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( slot_bank->block_hash_queue.ages_pool ); + fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( ages_pool ); node->elem = *elem; - fd_hash_hash_age_pair_t_map_insert( slot_bank->block_hash_queue.ages_pool, &slot_bank->block_hash_queue.ages_root, node ); + fd_hash_hash_age_pair_t_map_insert( ages_pool, &ages_root, node ); } + bhq->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)bhq; + bhq->ages_root_offset = (ulong)ages_root - (ulong)bhq; - /* FIXME: Remove the magic number here. */ - if( !slot_ctx->slot_bank.timestamp_votes.votes_pool ) { - pool_mem = fd_spad_alloc_check( runtime_spad, fd_clock_timestamp_vote_t_map_align(), fd_clock_timestamp_vote_t_map_footprint( 15000UL ) ); - slot_ctx->slot_bank.timestamp_votes.votes_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new( pool_mem, 15000UL ) ); + bhq->max_age = oldbank->blockhash_queue.max_age; + + fd_bank_mgr_block_hash_queue_save( bank_mgr ); + + /* Slot */ + + ulong * slot_ptr = fd_bank_mgr_slot_modify( bank_mgr ); + *slot_ptr = oldbank->slot; + fd_bank_mgr_slot_save( bank_mgr ); + slot_ctx->slot = oldbank->slot; + + /* Fee Rate Governor */ + + fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( bank_mgr ); + *fee_rate_governor = oldbank->fee_rate_governor; + fd_bank_mgr_fee_rate_governor_save( bank_mgr ); + + /* Capitalization */ + + ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + *capitalization = oldbank->capitalization; + fd_bank_mgr_capitalization_save( bank_mgr ); + + /* Lamports Per Signature */ + + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( bank_mgr ); + *lamports_per_signature = manifest->lamports_per_signature; + fd_bank_mgr_lamports_per_signature_save( bank_mgr ); + + /* Previous Lamports Per Signature */ + + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( bank_mgr ); + *prev_lamports_per_signature = manifest->lamports_per_signature; + fd_bank_mgr_prev_lamports_per_signature_save( bank_mgr ); + + /* Transaction Count */ + + ulong * transaction_count = fd_bank_mgr_transaction_count_modify( bank_mgr ); + *transaction_count = oldbank->transaction_count; + fd_bank_mgr_transaction_count_save( bank_mgr ); + + /* Parent Signature Count */ + + ulong * parent_signature_cnt = fd_bank_mgr_parent_signature_cnt_modify( bank_mgr ); + *parent_signature_cnt = oldbank->signature_count; + fd_bank_mgr_parent_signature_cnt_save( bank_mgr ); + + /* Tick Height */ + + ulong * tick_height = fd_bank_mgr_tick_height_modify( bank_mgr ); + *tick_height = oldbank->tick_height; + fd_bank_mgr_tick_height_save( bank_mgr ); + + /* Max Tick Height */ + + ulong * max_tick_height = fd_bank_mgr_max_tick_height_modify( bank_mgr ); + *max_tick_height = oldbank->max_tick_height; + fd_bank_mgr_max_tick_height_save( bank_mgr ); + + /* Hashes Per Tick */ + + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( bank_mgr ); + *hashes_per_tick = !!oldbank->hashes_per_tick ? *oldbank->hashes_per_tick : 0UL; + fd_bank_mgr_hashes_per_tick_save( bank_mgr ); + + /* NS Per Slot */ + + uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_modify( bank_mgr ); + *ns_per_slot = oldbank->ns_per_slot; + fd_bank_mgr_ns_per_slot_save( bank_mgr ); + + /* Ticks Per Slot */ + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_modify( bank_mgr ); + *ticks_per_slot = oldbank->ticks_per_slot; + fd_bank_mgr_ticks_per_slot_save( bank_mgr ); + + /* Genesis Creation Time */ + + ulong * genesis_creation_time = fd_bank_mgr_genesis_creation_time_modify( bank_mgr ); + *genesis_creation_time = oldbank->genesis_creation_time; + fd_bank_mgr_genesis_creation_time_save( bank_mgr ); + + /* Slots Per Year */ + + double * slots_per_year = fd_bank_mgr_slots_per_year_modify( bank_mgr ); + *slots_per_year = oldbank->slots_per_year; + fd_bank_mgr_slots_per_year_save( bank_mgr ); + + /* Inflation */ + + fd_inflation_t * inflation = fd_bank_mgr_inflation_modify( bank_mgr ); + *inflation = oldbank->inflation; + fd_bank_mgr_inflation_save( bank_mgr ); + + /* Block Height */ + + ulong * block_height = fd_bank_mgr_block_height_modify( bank_mgr ); + *block_height = oldbank->block_height; + fd_bank_mgr_block_height_save( bank_mgr ); + + /* Epoch Account Hash */ + + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_modify( bank_mgr ); + if( manifest->epoch_account_hash ) { + *epoch_account_hash = *manifest->epoch_account_hash; + } else { + memset( epoch_account_hash, 0, sizeof(fd_hash_t) ); } - recover_clock( slot_ctx, runtime_spad ); + fd_bank_mgr_epoch_account_hash_save( bank_mgr ); - /* Pass in the hard forks */ - /* The hard forks should be deep copied over. - TODO:This should be in the epoch bank and not the slot bank. */ - slot_bank->hard_forks.hard_forks_len = oldbank->hard_forks.hard_forks_len; - slot_bank->hard_forks.hard_forks = fd_valloc_malloc( valloc, - FD_SLOT_PAIR_ALIGN, - oldbank->hard_forks.hard_forks_len * sizeof(fd_slot_pair_t) ); - memcpy( slot_bank->hard_forks.hard_forks, oldbank->hard_forks.hard_forks, - oldbank->hard_forks.hard_forks_len * sizeof(fd_slot_pair_t) ); + /* Execution Fees */ + + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( bank_mgr ); + *execution_fees = oldbank->collector_fees; + fd_bank_mgr_execution_fees_save( bank_mgr ); + + /* Priority Fees */ + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( bank_mgr ); + *priority_fees = 0UL; + fd_bank_mgr_priority_fees_save( bank_mgr ); + + /* PoH */ + + if( oldbank->blockhash_queue.last_hash ) { + fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + *poh = *oldbank->blockhash_queue.last_hash; + fd_bank_mgr_poh_save( bank_mgr ); + } + + /* Last Restart Slot */ /* Update last restart slot https://github.com/solana-labs/solana/blob/30531d7a5b74f914dde53bfbb0bc2144f2ac92bb/runtime/src/bank.rs#L2152 @@ -328,8 +426,9 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, To find the last restart slot, take the highest hard fork slot number that is less or equal than the current slot number. (There might be some hard forks in the future, ignore these) */ + fd_sol_sysvar_last_restart_slot_t * last_restart_slot = fd_bank_mgr_last_restart_slot_modify( bank_mgr ); do { - slot_bank->last_restart_slot.slot = 0UL; + last_restart_slot->slot = 0UL; if( FD_UNLIKELY( oldbank->hard_forks.hard_forks_len == 0 ) ) { /* SIMD-0047: The first restart slot should be `0` */ break; @@ -339,16 +438,42 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_slot_pair_t const * tail = head + oldbank->hard_forks.hard_forks_len - 1UL; for( fd_slot_pair_t const *pair = tail; pair >= head; pair-- ) { - if( pair->slot <= slot_bank->slot ) { - slot_bank->last_restart_slot.slot = pair->slot; + if( pair->slot <= slot_ctx->slot ) { + last_restart_slot->slot = pair->slot; break; } } } while (0); + fd_bank_mgr_last_restart_slot_save( bank_mgr ); + + /* FIXME: Remove the magic number here. */ + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( bank_mgr ); + uchar * clock_pool_mem = (uchar *)fd_ulong_align_up( (ulong)clock_timestamp_votes + sizeof(fd_clock_timestamp_votes_global_t), fd_clock_timestamp_vote_t_map_align() ); + fd_clock_timestamp_vote_t_mapnode_t * clock_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new(clock_pool_mem, 15000UL ) ); + clock_timestamp_votes->votes_pool_offset = (ulong)fd_clock_timestamp_vote_t_map_leave( clock_pool) - (ulong)clock_timestamp_votes; + clock_timestamp_votes->votes_root_offset = 0UL; + fd_bank_mgr_clock_timestamp_votes_save( bank_mgr ); + + recover_clock( slot_ctx, runtime_spad ); + + + + /* Pass in the hard forks */ + + /* The hard forks should be deep copied over. */ + /* FIXME: The hard forks are only currently used for wen restart + and snapshot creation which is not actively supported. */ + // slot_bank->hard_forks.hard_forks_len = oldbank->hard_forks.hard_forks_len; + // slot_bank->hard_forks.hard_forks = fd_valloc_malloc( valloc, + // FD_SLOT_PAIR_ALIGN, + // oldbank->hard_forks.hard_forks_len * sizeof(fd_slot_pair_t) ); + // memcpy( slot_bank->hard_forks.hard_forks, oldbank->hard_forks.hard_forks, + // oldbank->hard_forks.hard_forks_len * sizeof(fd_slot_pair_t) ); + /* Move EpochStakes */ do { - ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_bank->slot, NULL ); + ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot, NULL ); /* We need to save the vote accounts for the current epoch and the next epoch as it is used to calculate the leader schedule at the epoch @@ -379,9 +504,9 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, If the snapshot does not, we should use the stakes at the end of the E-1 epoch, instead of E-2 as we do for all other epochs. */ - if( manifest->bank.epoch_stakes[i].key==epoch+2UL ) { - slot_ctx->slot_bank.has_use_preceeding_epoch_stakes = 0; - } + // if( manifest->bank.epoch_stakes[i].key==epoch+2UL ) { + // slot_ctx->slot_bank.has_use_preceeding_epoch_stakes = 0; + // } } for( ulong i=0UL; iversioned_epoch_stakes_len; i++ ) { @@ -390,6 +515,12 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, curr_stakes.vote_accounts_root = manifest->versioned_epoch_stakes[i].val.inner.Current.stakes.vote_accounts.vote_accounts_root; manifest->versioned_epoch_stakes[i].val.inner.Current.stakes.vote_accounts.vote_accounts_pool = NULL; manifest->versioned_epoch_stakes[i].val.inner.Current.stakes.vote_accounts.vote_accounts_root = NULL; + + /* We want to save the total epoch stake for the current epoch */ + ulong * total_epoch_stake = fd_bank_mgr_total_epoch_stake_modify( bank_mgr ); + *total_epoch_stake = manifest->versioned_epoch_stakes[i].val.inner.Current.total_stake; + fd_bank_mgr_total_epoch_stake_save( bank_mgr ); + } if( manifest->versioned_epoch_stakes[i].epoch == epoch+1UL ) { next_stakes.vote_accounts_pool = manifest->versioned_epoch_stakes[i].val.inner.Current.stakes.vote_accounts.vote_accounts_pool; @@ -398,13 +529,16 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, manifest->versioned_epoch_stakes[i].val.inner.Current.stakes.vote_accounts.vote_accounts_root = NULL; } - if( manifest->versioned_epoch_stakes[i].epoch==epoch+2UL ) { - slot_ctx->slot_bank.has_use_preceeding_epoch_stakes = 0; - } + // if( manifest->versioned_epoch_stakes[i].epoch==epoch+2UL ) { + // slot_ctx->slot_bank.has_use_preceeding_epoch_stakes = 0; + // } } - slot_ctx->slot_bank.has_use_preceeding_epoch_stakes = 1; - slot_ctx->slot_bank.use_preceeding_epoch_stakes = epoch + 2UL; + ulong * use_prev_stakes = fd_bank_mgr_use_prev_epoch_stake_modify( bank_mgr ); + *use_prev_stakes = epoch + 2UL; + fd_bank_mgr_use_prev_epoch_stake_save( bank_mgr ); + + // slot_ctx->slot_bank.use_preceeding_epoch_stakes = epoch + 2UL; if( FD_UNLIKELY( (!curr_stakes.vote_accounts_root) | (!next_stakes.vote_accounts_root) ) ) { FD_LOG_WARNING(( "snapshot missing EpochStakes for epochs %lu and/or %lu", epoch, epoch+1UL )); @@ -412,7 +546,7 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, } /* Move current EpochStakes */ - pool_mem = fd_spad_alloc_check( runtime_spad, fd_vote_accounts_pair_t_map_align(), fd_vote_accounts_pair_t_map_footprint( 100000 ) ); + uchar * pool_mem = fd_spad_alloc_check( runtime_spad, fd_vote_accounts_pair_t_map_align(), fd_vote_accounts_pair_t_map_footprint( 100000 ) ); slot_ctx->slot_bank.epoch_stakes.vote_accounts_pool = fd_vote_accounts_pair_t_map_join( fd_vote_accounts_pair_t_map_new( pool_mem, 100000 ) ); /* FIXME: Remove magic constant */ slot_ctx->slot_bank.epoch_stakes.vote_accounts_root = NULL; @@ -435,22 +569,21 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, elem ); } - /* Move next EpochStakes - TODO Can we derive this instead of trusting the snapshot? */ + /* Move next EpochStakes */ fd_vote_accounts_pair_t_mapnode_t * pool = next_stakes.vote_accounts_pool; fd_vote_accounts_pair_t_mapnode_t * root = next_stakes.vote_accounts_root; - for ( fd_vote_accounts_pair_t_mapnode_t * n = fd_vote_accounts_pair_t_map_minimum(pool, root); - n; - n = fd_vote_accounts_pair_t_map_successor(pool, n) ) { + for( fd_vote_accounts_pair_t_mapnode_t * n = fd_vote_accounts_pair_t_map_minimum( pool, root ); + n; + n = fd_vote_accounts_pair_t_map_successor( pool, n ) ) { fd_vote_accounts_pair_t_mapnode_t * elem = fd_vote_accounts_pair_t_map_acquire( epoch_bank->next_epoch_stakes.vote_accounts_pool ); FD_TEST( elem ); elem->elem = n->elem; - epoch_ctx->total_epoch_stake += n->elem.stake; + // epoch_ctx->total_epoch_stake += n->elem.stake; fd_vote_accounts_pair_t_map_insert( epoch_bank->next_epoch_stakes.vote_accounts_pool, @@ -460,20 +593,29 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, } } while(0); + FD_LOG_WARNING(("Recovered EpochStakes of size %lu", fd_vote_accounts_size( &epoch_bank->next_epoch_stakes ))); + if ( NULL != manifest->lthash ) slot_ctx->slot_bank.lthash = *manifest->lthash; else fd_lthash_zero( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ); - /* Allocate all the memory for the rent fresh accounts lists */ - fd_rent_fresh_accounts_new( &slot_bank->rent_fresh_accounts ); - slot_bank->rent_fresh_accounts.total_count = 0UL; - slot_bank->rent_fresh_accounts.fresh_accounts_len = FD_RENT_FRESH_ACCOUNTS_MAX; - slot_bank->rent_fresh_accounts.fresh_accounts = fd_spad_alloc( - runtime_spad, - FD_RENT_FRESH_ACCOUNT_ALIGN, - sizeof(fd_rent_fresh_account_t) * FD_RENT_FRESH_ACCOUNTS_MAX ); - fd_memset( slot_bank->rent_fresh_accounts.fresh_accounts, 0, sizeof(fd_rent_fresh_account_t) * FD_RENT_FRESH_ACCOUNTS_MAX ); + + fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( bank_mgr ); + + /* Setup rent fresh accounts */ + rent_fresh_accounts->total_count = 0UL; + rent_fresh_accounts->fresh_accounts_len = FD_RENT_FRESH_ACCOUNTS_MAX; + + fd_rent_fresh_account_t * fresh_accounts = (fd_rent_fresh_account_t *)fd_ulong_align_up( (ulong)rent_fresh_accounts + sizeof(fd_rent_fresh_accounts_global_t), FD_RENT_FRESH_ACCOUNT_ALIGN ); + memset( fresh_accounts, 0, rent_fresh_accounts->fresh_accounts_len * sizeof(fd_rent_fresh_account_t) ); + fd_rent_fresh_accounts_fresh_accounts_update( rent_fresh_accounts, fresh_accounts ); + + fd_bank_mgr_rent_fresh_accounts_save( bank_mgr ); + + /* Setup next epoch stakes */ + + return slot_ctx; } diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.h b/src/flamenco/runtime/context/fd_exec_slot_ctx.h index 716ae4ca9d..46ea116f7a 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.h +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.h @@ -16,8 +16,14 @@ struct __attribute__((aligned(8UL))) fd_exec_slot_ctx { ulong magic; /* ==FD_EXEC_SLOT_CTX_MAGIC */ + ulong slot; + fd_funk_txn_t * funk_txn; + /* FIXME: Kind of a gross hack. */ + uchar bank_mgr_mem[48]__attribute__((aligned(8UL))); + fd_bank_mgr_t * bank_mgr; + /* External joins, pointers to be set by caller */ fd_funk_t * funk; @@ -34,9 +40,7 @@ struct __attribute__((aligned(8UL))) fd_exec_slot_ctx { ulong part_width; /* TODO remove this stuff */ - ulong signature_cnt; fd_hash_t account_delta_hash; - ulong prev_lamports_per_signature; ulong parent_transaction_count; ulong txn_count; ulong nonvote_txn_count; diff --git a/src/flamenco/runtime/context/fd_exec_txn_ctx.c b/src/flamenco/runtime/context/fd_exec_txn_ctx.c index a2a5abfa75..d83b53c8c8 100644 --- a/src/flamenco/runtime/context/fd_exec_txn_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_txn_ctx.c @@ -3,6 +3,7 @@ #include "../fd_executor.h" #include "../../vm/fd_vm.h" #include "../fd_system_ids.h" +#include "../fd_bank_mgr.h" #include "fd_exec_epoch_ctx.h" void * diff --git a/src/flamenco/runtime/context/fd_exec_txn_ctx.h b/src/flamenco/runtime/context/fd_exec_txn_ctx.h index 99dcfe27f7..335522e00c 100644 --- a/src/flamenco/runtime/context/fd_exec_txn_ctx.h +++ b/src/flamenco/runtime/context/fd_exec_txn_ctx.h @@ -66,45 +66,46 @@ struct __attribute__((aligned(8UL))) fd_exec_txn_ctx { uint flags; + /* FIXME: Kind of a gross hack. */ + uchar bank_mgr_mem[48]__attribute__((aligned(8UL))); + fd_bank_mgr_t * bank_mgr; + /* All pointers starting here are valid local joins in txn execution. */ - fd_features_t features; - fd_sysvar_cache_t const * sysvar_cache; - fd_txncache_t * status_cache; - ulong prev_lamports_per_signature; - int enable_exec_recording; - ulong total_epoch_stake; - fd_bank_hash_cmp_t * bank_hash_cmp; - fd_funk_txn_t * funk_txn; - fd_funk_t funk[1]; - fd_wksp_t * runtime_pub_wksp; - ulong slot; - fd_fee_rate_governor_t fee_rate_governor; - fd_block_hash_queue_t block_hash_queue; - - fd_epoch_schedule_t schedule; - fd_rent_t rent; - double slots_per_year; - fd_stakes_t stakes; - - fd_spad_t * spad; /* Sized out to handle the worst case footprint of single transaction execution. */ - fd_wksp_t * spad_wksp; /* Workspace for the spad. */ + fd_features_t features; + fd_sysvar_cache_t const * sysvar_cache; + fd_txncache_t * status_cache; + int enable_exec_recording; + fd_bank_hash_cmp_t * bank_hash_cmp; + fd_funk_txn_t * funk_txn; + fd_funk_t funk[1]; + fd_wksp_t * runtime_pub_wksp; + ulong slot; + fd_fee_rate_governor_t fee_rate_governor; + fd_block_hash_queue_global_t const * block_hash_queue; + + fd_epoch_schedule_t schedule; + fd_rent_t rent; + fd_stakes_t stakes; + + fd_spad_t * spad; /* Sized out to handle the worst case footprint of single transaction execution. */ + fd_wksp_t * spad_wksp; /* Workspace for the spad. */ /* Fields below here are not guaranteed to be local joins in txn execution. */ - ulong paid_fees; - ulong compute_unit_limit; /* Compute unit limit for this transaction. */ - ulong compute_unit_price; /* Compute unit price for this transaction. */ - ulong compute_meter; /* Remaining compute units */ - ulong heap_size; /* Heap size for VMs for this transaction. */ - ulong loaded_accounts_data_size_limit; /* Loaded accounts data size limit for this transaction. */ - ulong loaded_accounts_data_size; /* The actual transaction loaded data size */ - uint prioritization_fee_type; /* The type of prioritization fee to use. */ - fd_txn_t const * txn_descriptor; /* Descriptor of the transaction. */ - fd_rawtxn_b_t _txn_raw[1]; /* Raw bytes of the transaction. */ - uint custom_err; /* When a custom error is returned, this is where the numeric value gets stashed */ - uchar instr_stack_sz; /* Current depth of the instruction execution stack. */ - fd_exec_instr_ctx_t instr_stack[FD_MAX_INSTRUCTION_STACK_DEPTH]; /* Instruction execution stack. */ - fd_exec_instr_ctx_t * failed_instr; - int instr_err_idx; + ulong paid_fees; + ulong compute_unit_limit; /* Compute unit limit for this transaction. */ + ulong compute_unit_price; /* Compute unit price for this transaction. */ + ulong compute_meter; /* Remaining compute units */ + ulong heap_size; /* Heap size for VMs for this transaction. */ + ulong loaded_accounts_data_size_limit; /* Loaded accounts data size limit for this transaction. */ + ulong loaded_accounts_data_size; /* The actual transaction loaded data size */ + uint prioritization_fee_type; /* The type of prioritization fee to use. */ + fd_txn_t const * txn_descriptor; /* Descriptor of the transaction. */ + fd_rawtxn_b_t _txn_raw[1]; /* Raw bytes of the transaction. */ + uint custom_err; /* When a custom error is returned, this is where the numeric value gets stashed */ + uchar instr_stack_sz; /* Current depth of the instruction execution stack. */ + fd_exec_instr_ctx_t instr_stack[FD_MAX_INSTRUCTION_STACK_DEPTH]; /* Instruction execution stack. */ + fd_exec_instr_ctx_t * failed_instr; + int instr_err_idx; /* During sanitization, v0 transactions are allowed to have up to 256 accounts: https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/sdk/program/src/message/versions/v0/mod.rs#L139 Nonetheless, when Agave prepares a sanitized batch for execution and tries to lock accounts, a lower limit is enforced: diff --git a/src/flamenco/runtime/fd_bank_mgr.c b/src/flamenco/runtime/fd_bank_mgr.c new file mode 100644 index 0000000000..3a57f0467d --- /dev/null +++ b/src/flamenco/runtime/fd_bank_mgr.c @@ -0,0 +1,90 @@ +#include "fd_bank_mgr.h" + +static inline fd_funk_rec_key_t +fd_bank_mgr_cache_key( ulong entry_id ) { + fd_funk_rec_key_t id; + memcpy( id.uc, &entry_id, sizeof(ulong) ); + memset( id.uc + sizeof(ulong), 0, sizeof(fd_funk_rec_key_t) - sizeof(ulong) ); + + id.uc[ FD_FUNK_REC_KEY_FOOTPRINT - 1 ] = FD_FUNK_KEY_TYPE_BANK_MGR; + + return id; +} + +ulong +fd_bank_mgr_align( void ) { + return alignof(fd_bank_mgr_t); +} + +ulong +fd_bank_mgr_footprint( void ) { + return sizeof(fd_bank_mgr_t); +} + +void * +fd_bank_mgr_new( void * mem ) { + return mem; +} + +fd_bank_mgr_t * +fd_bank_mgr_join( void * mem, fd_funk_t * funk, fd_funk_txn_t * funk_txn ) { + + if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_bank_mgr_align() ) ) ) { + FD_LOG_ERR(( "Bank manager mem not aligned" )); + return NULL; + } + + fd_bank_mgr_t * bank_mgr = (fd_bank_mgr_t * )mem; + + bank_mgr->funk = funk; + bank_mgr->funk_txn = funk_txn; + memset( &bank_mgr->query, 0, sizeof(fd_funk_rec_query_t) ); + + return bank_mgr; +} + +#define BANK_MGR_FUNCTION_IMPL(type, name, id, footprint, align) \ +type * \ +fd_bank_mgr_##name##_query( fd_bank_mgr_t * bank_mgr ) { \ + for(;;) { \ + fd_funk_rec_query_t query = {0}; \ + fd_funk_rec_key_t key = fd_bank_mgr_cache_key( fd_bank_mgr_##name##_id ); \ + fd_funk_rec_t const * rec = fd_funk_rec_query_try_global( bank_mgr->funk, \ + bank_mgr->funk_txn, \ + &key, \ + NULL, \ + &query ); \ + if( FD_UNLIKELY( !rec ) ) { \ + return NULL; \ + } \ + \ + if( FD_LIKELY( fd_funk_rec_query_test( &query )==FD_FUNK_SUCCESS ) ) \ + return (type *)fd_ulong_align_up( (ulong)fd_funk_val( rec, fd_funk_wksp( bank_mgr->funk ) ), \ + fd_bank_mgr_##name##_align ); \ + } \ +} \ + \ +type * \ +fd_bank_mgr_##name##_modify( fd_bank_mgr_t * bank_mgr ) { \ + fd_funk_rec_key_t key = fd_bank_mgr_cache_key( fd_bank_mgr_##name##_id ); \ + fd_funk_rec_try_clone_safe( bank_mgr->funk, \ + bank_mgr->funk_txn, \ + &key, \ + fd_bank_mgr_##name##_align, \ + fd_bank_mgr_##name##_footprint ); \ + fd_funk_rec_t * mod_rec = fd_funk_rec_modify( bank_mgr->funk, \ + bank_mgr->funk_txn, \ + &key, \ + &bank_mgr->query ); \ + if( FD_UNLIKELY( !mod_rec ) ) { \ + FD_LOG_CRIT(( "Failed to modify bank manager record" )); \ + } \ + return fd_funk_val( mod_rec, fd_funk_wksp( bank_mgr->funk ) ); \ +} \ +int \ +fd_bank_mgr_##name##_save( fd_bank_mgr_t * bank_mgr ) { \ + fd_funk_rec_modify_publish( &bank_mgr->query ); \ + fd_memset( &bank_mgr->query, 0, sizeof(fd_funk_rec_query_t) ); \ + return 0; \ +} +FD_BANK_MGR_ITER(BANK_MGR_FUNCTION_IMPL) diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h new file mode 100644 index 0000000000..fd35e786af --- /dev/null +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -0,0 +1,145 @@ +#include "../../funk/fd_funk.h" +#include "../fd_flamenco_base.h" +#include "../types/fd_types.h" + +/* The bank manager is a wrapper on top of funk that manages on-chain + state not represented by accounts. In practice, this on-chain state + is a direct parallel to the Bank data structure in the Agave client. + + More specifically, the bank manager is fork-aware and thread-safe. + + Each "member" of the bank manager is represented by a funk record. + The rationale behind this is to make the bank fork-aware by + leveraging the fact that funk already is. Also, by separating out + each member of the bank into its own funk record means that we will + not need to copy the entire bank while forking. A record will only + be copied if it is modified in a slot. Each bank manager record must + not contain gaddrs or local pointers -- all data must be accessed + directly or with an offset. + + The standard usage pattern of the bank manager is to first refresh a + local join for each slot via a call to fd_bank_mgr_join(). + If this join is not refreshed with the latest funk txn, then the + caller may receive stale data. There are two ways to access the + data after a join has been established: + 1. non-mutable: call _query(). The data returned by this call should + not be modified and will return a direct pointer to the data in + the funk record map. The caller is responsible for checking the + return value of this function. _query() will not acquire a lock on + the underlying hash chain as the query is done speculatively. + 2. mutable: call _modify() followed by a _save(). _modify() will + first try to clone a previous incarnation of the record into the + funk txn for the current join of the bank manager. If the record + is not found, a new record will be created and allocated. The + caller is responsible for checking the return value of this + function. The record can then be modified and a call to _save() + will publish the changes to the on-chain state. + + The underlying implementation involves first holding a lock on the + hash chain for the record and cloning it if needed. Afterward, a + lock is held to actually modify the record. The function returns + a pointer to the modifiable record. If _save() is not called, a + lock will be held indefinitely. The caller is responsible for + ensuring that the lock on the record (and hash chain) is released. +*/ + +/* TODO: make this struct opaque. */ +struct fd_bank_mgr { + fd_funk_t * funk; + fd_funk_txn_t * funk_txn; + fd_funk_rec_map_query_t query; +}; +typedef struct fd_bank_mgr fd_bank_mgr_t; + +ulong +fd_bank_mgr_align( void ); + +ulong +fd_bank_mgr_footprint( void ); + +void * +fd_bank_mgr_new( void * mem ); + +fd_bank_mgr_t * +fd_bank_mgr_join( void * mem, fd_funk_t * funk, fd_funk_txn_t * funk_txn ); + +#define BANK_MGR_FUNCTIONS(type, name, id, footprint, align) \ +static const ulong fd_bank_mgr_##name##_id = id; \ +static const ulong fd_bank_mgr_##name##_footprint = footprint; \ +static const ulong fd_bank_mgr_##name##_align = align; \ +type * \ +fd_bank_mgr_##name##_query( fd_bank_mgr_t * bank_mgr ); \ + \ +type * \ +fd_bank_mgr_##name##_modify( fd_bank_mgr_t * bank_mgr ); \ + \ +int \ +fd_bank_mgr_##name##_save( fd_bank_mgr_t * bank_mgr ); \ + \ +static FD_FN_UNUSED int \ +fd_bank_mgr_##name##_save_cleanup( fd_bank_mgr_t ** bank_mgr ) { \ + fd_bank_mgr_##name##_save( *bank_mgr ); \ + return 0; \ +} + + + +/* These are some convenience wrapper macros for the bank manager. */ + +#define FD_BANK_MGR_DECL(bank_mgr, funk, funk_txn) \ +fd_bank_mgr_t _##bank_mgr##_obj; \ +fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( &_##bank_mgr##_obj ), funk, funk_txn ); \ +if( FD_UNLIKELY( !bank_mgr ) ) { \ + FD_LOG_CRIT(( "Failed to join bank manager" )); \ +} + +#define FD_BANK_MGR_MODIFY_BEGIN(bank_mgr, type_name, ptr) do { \ + fd_bank_mgr_t * _bank_mgr __attribute__((cleanup(fd_bank_mgr_##type_name##_save_cleanup))) = (bank_mgr); \ + ptr = fd_bank_mgr_##type_name##_modify( _bank_mgr ); \ + if( FD_UNLIKELY( !ptr ) ) { \ + FD_LOG_CRIT(( "Failed to modify bank manager record" )); \ + } \ + do + +#define FD_BANK_MGR_MODIFY_END while(0); } while(0) + + +/* FIXME: Size out all data structures to their max bounded size. */ +/* FIXME: Flip order for footprind and align. */ +/* Add new members to the bank manager here. */ +/* Type, name, id, footprint, align */ +#define FD_BANK_MGR_ITER(X) \ + X(fd_block_hash_queue_global_t, block_hash_queue, 0UL, 50000UL, 1024UL) \ + X(ulong, slot, 1UL, 8UL, 8UL ) \ + X(fd_fee_rate_governor_t, fee_rate_governor, 2UL, 40UL, 8UL ) \ + X(ulong, capitalization, 3UL, 8UL, 8UL ) \ + X(ulong, lamports_per_signature, 4UL, 8UL, 8UL ) \ + X(ulong, prev_lamports_per_signature, 5UL, 8UL, 8UL ) \ + X(ulong, transaction_count, 6UL, 8UL, 8UL ) \ + X(ulong, parent_signature_cnt, 7UL, 8UL, 8UL ) \ + X(ulong, tick_height, 8UL, 8UL, 8UL ) \ + X(ulong, max_tick_height, 9UL, 8UL, 8UL ) \ + X(ulong, hashes_per_tick, 10UL, 8UL, 8UL ) \ + X(uint128, ns_per_slot, 11UL, 16UL, 16UL ) \ + X(ulong, ticks_per_slot, 12UL, 8UL, 8UL ) \ + X(ulong, genesis_creation_time, 13UL, 8UL, 8UL ) \ + X(double, slots_per_year, 14UL, 8UL, 8UL ) \ + X(fd_inflation_t, inflation, 15UL, 48UL, 8UL ) \ + X(ulong, total_epoch_stake, 16UL, 8UL, 8UL ) \ + X(ulong, eah_start_slot, 17UL, 8UL, 8UL ) \ + X(ulong, eah_stop_slot, 18UL, 8UL, 8UL ) \ + X(ulong, eah_interval, 19UL, 8UL, 8UL ) \ + X(ulong, block_height, 20UL, 8UL, 8UL ) \ + X(fd_hash_t, epoch_account_hash, 21UL, 32UL, 8UL ) \ + X(ulong, execution_fees, 22UL, 8UL, 8UL ) \ + X(ulong, priority_fees, 23UL, 8UL, 8UL ) \ + X(fd_clock_timestamp_votes_global_t, clock_timestamp_votes, 24UL, 2000000UL, 1024UL) \ + X(ulong, signature_cnt, 25UL, 8UL, 8UL ) \ + X(fd_account_keys_global_t, stake_account_keys, 26UL, 160000000UL, 1024UL) \ + X(fd_account_keys_global_t, vote_account_keys, 27UL, 3200000UL, 1024UL) \ + X(ulong, use_prev_epoch_stake, 28UL, 8UL, 8UL ) \ + X(fd_hash_t, poh, 29UL, 32UL, 8UL ) \ + X(fd_sol_sysvar_last_restart_slot_t, last_restart_slot, 30UL, 8UL, 8UL ) \ + X(fd_rent_fresh_accounts_global_t, rent_fresh_accounts, 31UL, 50000UL, 8UL ) \ + X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) +FD_BANK_MGR_ITER(BANK_MGR_FUNCTIONS) diff --git a/src/flamenco/runtime/fd_blockstore.c b/src/flamenco/runtime/fd_blockstore.c index 1e8b4c746f..822dc4acdf 100644 --- a/src/flamenco/runtime/fd_blockstore.c +++ b/src/flamenco/runtime/fd_blockstore.c @@ -246,9 +246,13 @@ fd_blockstore_delete( void * shblockstore ) { } while(0); fd_blockstore_t * -fd_blockstore_init( fd_blockstore_t * blockstore, int fd, ulong fd_size_max, fd_slot_bank_t const * slot_bank ) { +fd_blockstore_init( fd_blockstore_t * blockstore, + int fd, + ulong fd_size_max, + fd_slot_bank_t const * slot_bank, + ulong slot ) { - if ( fd_size_max < FD_BLOCKSTORE_ARCHIVE_MIN_SIZE ) { + if( fd_size_max < FD_BLOCKSTORE_ARCHIVE_MIN_SIZE ) { FD_LOG_ERR(( "archive file size too small" )); return NULL; } @@ -259,7 +263,7 @@ fd_blockstore_init( fd_blockstore_t * blockstore, int fd, ulong fd_size_max, fd_ /* initialize fields using slot bank */ - ulong smr = slot_bank->slot; + ulong smr = slot; blockstore->shmem->lps = smr; blockstore->shmem->hcs = smr; @@ -275,10 +279,7 @@ fd_blockstore_init( fd_blockstore_t * blockstore, int fd, ulong fd_size_max, fd_ ele->parent_slot = slot_bank->prev_slot; memset( ele->child_slots, UCHAR_MAX, FD_BLOCKSTORE_CHILD_SLOT_MAX * sizeof( ulong ) ); ele->child_slot_cnt = 0; - ele->block_height = slot_bank->block_height; - ele->block_hash = *slot_bank->block_hash_queue.last_hash; - ele->bank_hash = slot_bank->banks_hash; - ele->in_poh_hash = slot_bank->poh; + // ele->in_poh_hash = slot_bank->poh; ele->flags = fd_uchar_set_bit( fd_uchar_set_bit( fd_uchar_set_bit( diff --git a/src/flamenco/runtime/fd_blockstore.h b/src/flamenco/runtime/fd_blockstore.h index f57d9f6a54..4416569328 100644 --- a/src/flamenco/runtime/fd_blockstore.h +++ b/src/flamenco/runtime/fd_blockstore.h @@ -576,7 +576,11 @@ fd_blockstore_delete( void * shblockstore ); file. */ fd_blockstore_t * -fd_blockstore_init( fd_blockstore_t * blockstore, int fd, ulong fd_size_max, fd_slot_bank_t const * slot_bank ); +fd_blockstore_init( fd_blockstore_t * blockstore, + int fd, + ulong fd_size_max, + fd_slot_bank_t const * slot_bank, + ulong slot ); /* fd_blockstore_fini finalizes a blockstore. diff --git a/src/flamenco/runtime/fd_blockstore_tool.c b/src/flamenco/runtime/fd_blockstore_tool.c index d737ff657a..55a2743ce1 100644 --- a/src/flamenco/runtime/fd_blockstore_tool.c +++ b/src/flamenco/runtime/fd_blockstore_tool.c @@ -66,15 +66,10 @@ usage( void ) { fd_buf_shred_pool_reset( blockstore->shred_pool, 0 ); \ FD_TEST( blockstore ); \ fd_slot_bank_t slot_bank = { \ - .slot = 1, \ .prev_slot = 0, \ .banks_hash = { .hash = {0} }, \ - .block_height = 1, \ }; \ fd_slot_bank_new( &slot_bank ); \ - fd_hash_t fake_hash = { .hash = {1} }; \ - slot_bank.block_hash_queue.last_hash = &fake_hash; \ - slot_bank.block_hash_queue.last_hash_index = 0; \ int fd = open( "dummy.archv", O_RDWR | O_CREAT, 0666 ); \ FD_TEST( fd > 0 ); @@ -203,7 +198,7 @@ initialize_rocksdb( fd_wksp_t * wksp, static void aggregate_entries( fd_wksp_t * wksp, const char * folder, const char * csv, ulong st, ulong end ){ INITIALIZE_BLOCKSTORE( blockstore ); - FD_TEST( fd_blockstore_init( blockstore, fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &slot_bank ) ); + FD_TEST( fd_blockstore_init( blockstore, fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &slot_bank, 1UL ) ); ulong populated_slots[end - st + 1]; memset( populated_slots, -1, sizeof(populated_slots) ); @@ -296,7 +291,7 @@ aggregate_entries( fd_wksp_t * wksp, const char * folder, const char * csv, ulon static void aggregate_batch_entries( fd_wksp_t * wksp, const char * folder, const char * csv, ulong st, ulong end ){ INITIALIZE_BLOCKSTORE( blockstore ); - FD_TEST( fd_blockstore_init( blockstore, fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &slot_bank ) ); + FD_TEST( fd_blockstore_init( blockstore, fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &slot_bank, 1UL ) ); ulong populated_slots[end - st + 1]; memset( populated_slots, -1, sizeof(populated_slots) ); @@ -343,7 +338,7 @@ aggregate_batch_entries( fd_wksp_t * wksp, const char * folder, const char * csv static void investigate_shred( fd_wksp_t * wksp, const char * folder, ulong st, ulong end ){ INITIALIZE_BLOCKSTORE( blockstore ); - FD_TEST( fd_blockstore_init( blockstore, fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &slot_bank ) ); + FD_TEST( fd_blockstore_init( blockstore, fd, FD_BLOCKSTORE_ARCHIVE_MIN_SIZE, &slot_bank, 1UL ) ); ulong populated_slots[end - st + 1]; memset( populated_slots, -1, sizeof(populated_slots) ); diff --git a/src/flamenco/runtime/fd_cost_tracker.c b/src/flamenco/runtime/fd_cost_tracker.c index dea6b0e381..107d101884 100644 --- a/src/flamenco/runtime/fd_cost_tracker.c +++ b/src/flamenco/runtime/fd_cost_tracker.c @@ -323,7 +323,7 @@ fd_cost_tracker_init( fd_cost_tracker_t * self, fd_spad_t * spad ) { // Set limits appropriately self->account_cost_limit = FD_MAX_WRITABLE_ACCOUNT_UNITS; - self->block_cost_limit = FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, raise_block_limits_to_50m ) ? FD_MAX_BLOCK_UNITS_SIMD_0207 : FD_MAX_BLOCK_UNITS; + self->block_cost_limit = FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, raise_block_limits_to_50m ) ? FD_MAX_BLOCK_UNITS_SIMD_0207 : FD_MAX_BLOCK_UNITS; self->vote_cost_limit = FD_MAX_VOTE_UNITS; /* Init cost tracker map diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 91a3de818d..01f02da8c6 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -4,6 +4,8 @@ #include "fd_hashes.h" #include "fd_runtime.h" #include "fd_runtime_err.h" +#include "fd_bank_mgr.h" + #include "context/fd_exec_slot_ctx.h" #include "context/fd_exec_txn_ctx.h" #include "context/fd_exec_instr_ctx.h" @@ -464,7 +466,7 @@ load_transaction_account( fd_exec_txn_ctx_t * txn_ctx, txn_ctx->collected_rent += fd_runtime_collect_rent_from_account( txn_ctx->slot, &txn_ctx->schedule, &txn_ctx->rent, - txn_ctx->slots_per_year, + *(fd_bank_mgr_slots_per_year_query( txn_ctx->bank_mgr )), &txn_ctx->features, acct, epoch ); @@ -838,7 +840,7 @@ fd_executor_validate_transaction_fee_payer( fd_exec_txn_ctx_t * txn_ctx ) { txn_ctx->collected_rent += fd_runtime_collect_rent_from_account( txn_ctx->slot, &txn_ctx->schedule, &txn_ctx->rent, - txn_ctx->slots_per_year, + *(fd_bank_mgr_slots_per_year_query( txn_ctx->bank_mgr )), &txn_ctx->features, fee_payer_rec, epoch ); @@ -907,6 +909,7 @@ fd_executor_setup_accessed_accounts_for_txn( fd_exec_txn_ctx_t * txn_ctx ) { accts_alt ); txn_ctx->accounts_cnt += txn_ctx->txn_descriptor->addr_table_adtl_cnt; if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) return err; + } return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -1234,18 +1237,22 @@ fd_txn_reclaim_accounts( fd_exec_txn_ctx_t * txn_ctx ) { } int -fd_executor_is_blockhash_valid_for_age( fd_block_hash_queue_t const * block_hash_queue, - fd_hash_t const * blockhash, - ulong max_age ) { +fd_executor_is_blockhash_valid_for_age( fd_block_hash_queue_global_t const * block_hash_queue, + fd_hash_t const * blockhash, + ulong max_age ) { fd_hash_hash_age_pair_t_mapnode_t key; fd_memcpy( key.elem.key.uc, blockhash, sizeof(fd_hash_t) ); - fd_hash_hash_age_pair_t_mapnode_t * hash_age = fd_hash_hash_age_pair_t_map_find( block_hash_queue->ages_pool, block_hash_queue->ages_root, &key ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_block_hash_queue_ages_pool_join( block_hash_queue ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_block_hash_queue_ages_root_join( block_hash_queue ); + + fd_hash_hash_age_pair_t_mapnode_t * hash_age = fd_hash_hash_age_pair_t_map_find( ages_pool, ages_root, &key ); if( hash_age==NULL ) { return 0; } + ulong age = block_hash_queue->last_hash_index-hash_age->elem.val.hash_index; - return ( age<=max_age ); + return age<=max_age; } void @@ -1278,18 +1285,23 @@ fd_exec_txn_ctx_from_exec_slot_ctx( fd_exec_slot_ctx_t const * slot_ctx, ctx->bank_hash_cmp = slot_ctx->epoch_ctx->bank_hash_cmp; - ctx->prev_lamports_per_signature = slot_ctx->prev_lamports_per_signature; ctx->enable_exec_recording = slot_ctx->enable_exec_recording; - ctx->total_epoch_stake = slot_ctx->epoch_ctx->total_epoch_stake; - ctx->slot = slot_ctx->slot_bank.slot; - ctx->fee_rate_governor = slot_ctx->slot_bank.fee_rate_governor; - ctx->block_hash_queue = slot_ctx->slot_bank.block_hash_queue; /* MAKE GLOBAL */ + ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); + + ctx->block_hash_queue = fd_bank_mgr_block_hash_queue_query( ctx->bank_mgr ); + ulong * slot = fd_bank_mgr_slot_query( ctx->bank_mgr ); + ctx->slot = !!slot ? *slot : 0UL; + + fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_query( ctx->bank_mgr ); + if( fee_rate_governor ) { + ctx->fee_rate_governor = *fee_rate_governor; + } + /* Distribute rewards */ fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank_const( slot_ctx->epoch_ctx ); ctx->schedule = epoch_bank->epoch_schedule; ctx->rent = epoch_bank->rent; - ctx->slots_per_year = epoch_bank->slots_per_year; ctx->stakes = epoch_bank->stakes; } diff --git a/src/flamenco/runtime/fd_executor.h b/src/flamenco/runtime/fd_executor.h index 43fc9deafb..7268024866 100644 --- a/src/flamenco/runtime/fd_executor.h +++ b/src/flamenco/runtime/fd_executor.h @@ -97,9 +97,9 @@ void fd_txn_reclaim_accounts( fd_exec_txn_ctx_t * txn_ctx ); int -fd_executor_is_blockhash_valid_for_age( fd_block_hash_queue_t const * block_hash_queue, - fd_hash_t const * blockhash, - ulong max_age ); +fd_executor_is_blockhash_valid_for_age( fd_block_hash_queue_global_t const * block_hash_queue, + fd_hash_t const * blockhash, + ulong max_age ); /* fd_io_strerror converts an FD_EXECUTOR_INSTR_ERR_{...} code into a human readable cstr. The lifetime of the returned pointer is diff --git a/src/flamenco/runtime/fd_hashes.c b/src/flamenco/runtime/fd_hashes.c index be2be5b133..5d74b66825 100644 --- a/src/flamenco/runtime/fd_hashes.c +++ b/src/flamenco/runtime/fd_hashes.c @@ -1,5 +1,6 @@ #include "fd_hashes.h" #include "fd_acc_mgr.h" +#include "fd_bank_mgr.h" #include "fd_blockstore.h" #include "fd_runtime.h" #include "fd_borrowed_account.h" @@ -149,15 +150,23 @@ fd_hash_account_deltas( fd_pubkey_hash_pair_list_t * lists, ulong lists_len, fd_ void -fd_calculate_epoch_accounts_hash_values(fd_exec_slot_ctx_t * slot_ctx) { +fd_calculate_epoch_accounts_hash_values( fd_exec_slot_ctx_t * slot_ctx ) { ulong slot_idx = 0; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot, &slot_idx ); + ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot, &slot_idx ); - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, accounts_lt_hash) ) { - epoch_bank->eah_start_slot = ULONG_MAX; - epoch_bank->eah_stop_slot = ULONG_MAX; - epoch_bank->eah_interval = ULONG_MAX; + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, accounts_lt_hash) ) { + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_modify( slot_ctx->bank_mgr ); + *eah_start_slot = ULONG_MAX; + fd_bank_mgr_eah_start_slot_save( slot_ctx->bank_mgr ); + + ulong * eah_stop_slot = fd_bank_mgr_eah_stop_slot_modify( slot_ctx->bank_mgr ); + *eah_stop_slot = ULONG_MAX; + fd_bank_mgr_eah_stop_slot_save( slot_ctx->bank_mgr ); + + ulong * eah_interval = fd_bank_mgr_eah_interval_modify( slot_ctx->bank_mgr ); + *eah_interval = ULONG_MAX; + fd_bank_mgr_eah_interval_save( slot_ctx->bank_mgr ); return; } @@ -173,31 +182,52 @@ fd_calculate_epoch_accounts_hash_values(fd_exec_slot_ctx_t * slot_ctx) { const ulong CALCULATION_INTERVAL_BUFFER = 150UL; const ulong MINIMUM_CALCULATION_INTERVAL = MAX_LOCKOUT_HISTORY + CALCULATION_INTERVAL_BUFFER; - if (calculation_interval < MINIMUM_CALCULATION_INTERVAL) { - epoch_bank->eah_start_slot = ULONG_MAX; - epoch_bank->eah_stop_slot = ULONG_MAX; - epoch_bank->eah_interval = ULONG_MAX; + if( calculation_interval < MINIMUM_CALCULATION_INTERVAL ) { + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_modify( slot_ctx->bank_mgr ); + *eah_start_slot = ULONG_MAX; + fd_bank_mgr_eah_start_slot_save( slot_ctx->bank_mgr ); + + ulong * eah_stop_slot = fd_bank_mgr_eah_stop_slot_modify( slot_ctx->bank_mgr ); + *eah_stop_slot = ULONG_MAX; + fd_bank_mgr_eah_stop_slot_save( slot_ctx->bank_mgr ); + + ulong * eah_interval = fd_bank_mgr_eah_interval_modify( slot_ctx->bank_mgr ); + *eah_interval = ULONG_MAX; + fd_bank_mgr_eah_interval_save( slot_ctx->bank_mgr ); + return; } - epoch_bank->eah_start_slot = first_slot_in_epoch + calculation_offset_start; - if (slot_ctx->slot_bank.slot > epoch_bank->eah_start_slot) - epoch_bank->eah_start_slot = ULONG_MAX; - epoch_bank->eah_stop_slot = first_slot_in_epoch + calculation_offset_stop; - if (slot_ctx->slot_bank.slot > epoch_bank->eah_stop_slot) - epoch_bank->eah_stop_slot = ULONG_MAX; - epoch_bank->eah_interval = calculation_interval; + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_modify( slot_ctx->bank_mgr ); + + *eah_start_slot = first_slot_in_epoch + calculation_offset_start; + if( slot_ctx->slot > *eah_start_slot ) { + *eah_start_slot = ULONG_MAX; + } + fd_bank_mgr_eah_start_slot_save( slot_ctx->bank_mgr ); + + ulong * eah_end_slot = fd_bank_mgr_eah_stop_slot_modify( slot_ctx->bank_mgr ); + *eah_end_slot = first_slot_in_epoch + calculation_offset_stop; + if( slot_ctx->slot > *eah_end_slot ) { + *eah_end_slot = ULONG_MAX; + } + fd_bank_mgr_eah_stop_slot_save( slot_ctx->bank_mgr ); + + ulong * eah_interval = fd_bank_mgr_eah_interval_modify( slot_ctx->bank_mgr ); + *eah_interval = calculation_interval; + fd_bank_mgr_eah_interval_save( slot_ctx->bank_mgr ); + } // https://github.com/solana-labs/solana/blob/b0dcaf29e358c37a0fcb8f1285ce5fff43c8ec55/runtime/src/bank/epoch_accounts_hash_utils.rs#L13 static int -fd_should_include_epoch_accounts_hash(fd_exec_slot_ctx_t * slot_ctx) { - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, accounts_lt_hash) ) +fd_should_include_epoch_accounts_hash( fd_exec_slot_ctx_t * slot_ctx ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, accounts_lt_hash) ) { return 0; + } - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong calculation_stop = epoch_bank->eah_stop_slot; - return slot_ctx->slot_bank.prev_slot < calculation_stop && (slot_ctx->slot_bank.slot >= calculation_stop); + ulong calculation_stop = *fd_bank_mgr_eah_stop_slot_query( slot_ctx->bank_mgr ); + return slot_ctx->slot_bank.prev_slot < calculation_stop && (slot_ctx->slot >= calculation_stop); } // slot_ctx should be const. @@ -208,11 +238,25 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, fd_pubkey_hash_pair_t * dirty_keys, ulong dirty_key_cnt ) { slot_ctx->slot_bank.prev_banks_hash = slot_ctx->slot_bank.banks_hash; - slot_ctx->slot_bank.parent_signature_cnt = slot_ctx->signature_cnt; - slot_ctx->prev_lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; - slot_ctx->parent_transaction_count = slot_ctx->slot_bank.transaction_count; - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) { + ulong * signature_cnt_bm = fd_bank_mgr_signature_cnt_query( slot_ctx->bank_mgr ); + ulong signature_cnt = !!signature_cnt_bm ? *signature_cnt_bm : 0UL; + ulong * parent_signature_cnt = fd_bank_mgr_parent_signature_cnt_modify( slot_ctx->bank_mgr ); + *parent_signature_cnt = signature_cnt; + fd_bank_mgr_parent_signature_cnt_save( slot_ctx->bank_mgr ); + + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( slot_ctx->bank_mgr ); + + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *prev_lamports_per_signature = *lamports_per_signature; + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); + + ulong * transaction_count = fd_bank_mgr_transaction_count_query( slot_ctx->bank_mgr ); + slot_ctx->parent_transaction_count = *transaction_count; + + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_query( slot_ctx->bank_mgr ); + + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) { sort_pubkey_hash_pair_inplace( dirty_keys, dirty_key_cnt ); fd_pubkey_hash_pair_list_t list1 = { .pairs = dirty_keys, .pairs_len = dirty_key_cnt }; fd_hash_account_deltas(&list1, 1, &slot_ctx->account_delta_hash ); @@ -221,15 +265,17 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, fd_sha256_t sha; fd_sha256_init( &sha ); fd_sha256_append( &sha, (uchar const *) &slot_ctx->slot_bank.banks_hash, sizeof( fd_hash_t ) ); - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) fd_sha256_append( &sha, (uchar const *) &slot_ctx->account_delta_hash, sizeof( fd_hash_t ) ); - fd_sha256_append( &sha, (uchar const *) &slot_ctx->signature_cnt, sizeof( ulong ) ); - fd_sha256_append( &sha, (uchar const *) &slot_ctx->slot_bank.poh, sizeof( fd_hash_t ) ); + fd_sha256_append( &sha, (uchar const *) &signature_cnt, sizeof( ulong ) ); + + fd_hash_t * poh = fd_bank_mgr_poh_query( slot_ctx->bank_mgr ); + fd_sha256_append( &sha, (uchar const *) poh, sizeof( fd_hash_t ) ); fd_sha256_fini( &sha, hash->hash ); // https://github.com/anza-xyz/agave/blob/766cd682423b8049ddeac3c0ec6cebe0a1356e9e/runtime/src/bank.rs#L5250 - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, accounts_lt_hash ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, accounts_lt_hash ) ) { fd_sha256_init( &sha ); fd_sha256_append( &sha, (uchar const *) &hash->hash, sizeof( fd_hash_t ) ); fd_sha256_append( &sha, (uchar const *) &slot_ctx->slot_bank.lthash.lthash, sizeof( slot_ctx->slot_bank.lthash.lthash ) ); @@ -238,15 +284,15 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, if (fd_should_include_epoch_accounts_hash(slot_ctx)) { fd_sha256_init( &sha ); fd_sha256_append( &sha, (uchar const *) &hash->hash, sizeof( fd_hash_t ) ); - fd_sha256_append( &sha, (uchar const *) &slot_ctx->slot_bank.epoch_account_hash.hash, sizeof( fd_hash_t ) ); + fd_sha256_append( &sha, (uchar const *) epoch_account_hash, sizeof( fd_hash_t ) ); fd_sha256_fini( &sha, hash->hash ); } } - if( capture_ctx != NULL && capture_ctx->capture != NULL && slot_ctx->slot_bank.slot>=capture_ctx->solcap_start_slot ) { + if( capture_ctx != NULL && capture_ctx->capture != NULL && slot_ctx->slot>=capture_ctx->solcap_start_slot ) { uchar *lthash = NULL; - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, accounts_lt_hash ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, accounts_lt_hash ) ) { lthash = (uchar *)fd_alloca_check( 1UL, 32UL ); fd_lthash_hash((fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash, lthash); } @@ -255,13 +301,13 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, capture_ctx->capture, hash->hash, slot_ctx->slot_bank.prev_banks_hash.hash, - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ? NULL : slot_ctx->account_delta_hash.hash, + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ? NULL : slot_ctx->account_delta_hash.hash, lthash, - &slot_ctx->slot_bank.poh.hash, - slot_ctx->signature_cnt ); + poh, + signature_cnt ); } - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) { FD_LOG_NOTICE(( "\n\n[Replay]\n" "slot: %lu\n" "bank hash: %s\n" @@ -269,12 +315,12 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, "lthash: %s\n" "signature_count: %lu\n" "last_blockhash: %s\n", - slot_ctx->slot_bank.slot, + slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( hash->hash ), FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.prev_banks_hash.hash ), FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ), - slot_ctx->signature_cnt, - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.poh.hash ) )); + signature_cnt, + FD_BASE58_ENC_32_ALLOCA( poh->hash ) )); } else { FD_LOG_NOTICE(( "\n\n[Replay]\n" "slot: %lu\n" @@ -284,13 +330,13 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, "lthash: %s\n" "signature_count: %lu\n" "last_blockhash: %s\n", - slot_ctx->slot_bank.slot, + slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( hash->hash ), FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.prev_banks_hash.hash ), FD_BASE58_ENC_32_ALLOCA( slot_ctx->account_delta_hash.hash ), FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ), - slot_ctx->signature_cnt, - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.poh.hash ) )); + signature_cnt, + FD_BASE58_ENC_32_ALLOCA( poh->hash ) )); } } @@ -401,7 +447,7 @@ fd_account_hash_task( void * tpool, slot_ctx->funk_txn, task_info, lthash, - slot_ctx->slot_bank.slot, + slot_ctx->slot, &slot_ctx->epoch_ctx->features ); } @@ -502,7 +548,7 @@ fd_update_hash_bank_exec_hash( fd_exec_slot_ctx_t * slot_ctx, /* Update hash */ acc_rec->vt->set_hash( acc_rec, task_info->acc_hash ); - acc_rec->vt->set_slot( acc_rec, slot_ctx->slot_bank.slot ); + acc_rec->vt->set_slot( acc_rec, slot_ctx->slot ); fd_txn_account_mutable_fini( acc_rec, funk, txn ); @@ -526,14 +572,14 @@ fd_update_hash_bank_exec_hash( fd_exec_slot_ctx_t * slot_ctx, "rent_epoch: %lu, " "data_len: %lu", acc_key_string, - slot_ctx->slot_bank.slot, + slot_ctx->slot, acc_rec->vt->get_lamports( acc_rec ), owner_string, acc_rec->vt->is_executable( acc_rec ) ? "true" : "false", acc_rec->vt->get_rent_epoch( acc_rec ), acc_rec->vt->get_data_len( acc_rec ) )); - if( capture_ctx != NULL && capture_ctx->capture != NULL && slot_ctx->slot_bank.slot>=capture_ctx->solcap_start_slot ) { + if( capture_ctx != NULL && capture_ctx->capture != NULL && slot_ctx->slot>=capture_ctx->solcap_start_slot ) { fd_account_meta_t const * acc_meta = fd_funk_get_acc_meta_readonly( slot_ctx->funk, slot_ctx->funk_txn, task_info->acc_pubkey, @@ -562,7 +608,10 @@ fd_update_hash_bank_exec_hash( fd_exec_slot_ctx_t * slot_ctx, /* Sort and hash "dirty keys" to the accounts delta hash. */ - slot_ctx->signature_cnt = signature_cnt; + ulong * signature_cnt_bm = fd_bank_mgr_signature_cnt_modify( slot_ctx->bank_mgr ); + *signature_cnt_bm = signature_cnt; + fd_bank_mgr_signature_cnt_save( slot_ctx->bank_mgr ); + fd_hash_bank( slot_ctx, capture_ctx, hash, dirty_keys, dirty_key_cnt); for( ulong i = 0; i < task_data->info_sz; i++ ) { @@ -648,11 +697,11 @@ fd_update_hash_bank_tpool( fd_exec_slot_ctx_t * slot_ctx, for( ulong i=0UL; iinfo_sz; i++ ) { fd_accounts_hash_task_info_t * task_info = &task_data->info[i]; fd_account_hash( slot_ctx->funk, - slot_ctx->funk_txn, - task_info, - <_hashes[ 0 ], - slot_ctx->slot_bank.slot, - &slot_ctx->epoch_ctx->features ); + slot_ctx->funk_txn, + task_info, + <_hashes[ 0 ], + slot_ctx->slot, + &slot_ctx->epoch_ctx->features ); } } @@ -942,14 +991,14 @@ fd_accounts_hash_counter_and_gather_tpool_cb( void * para_arg_1, int fd_accounts_hash( fd_funk_t * funk, - fd_slot_bank_t * slot_bank, + ulong slot, fd_hash_t * accounts_hash, fd_spad_t * runtime_spad, fd_features_t * features, fd_exec_para_cb_ctx_t * exec_para_ctx, - fd_lthash_value_t * lt_hash ) { + fd_lthash_value_t * lt_hash ) { - int lthash_enabled = (NULL != lt_hash) && (FD_FEATURE_ACTIVE( slot_bank->slot, *features, snapshots_lt_hash ) || FD_FEATURE_ACTIVE( slot_bank->slot, *features, accounts_lt_hash ) ); + int lthash_enabled = (NULL != lt_hash) && (FD_FEATURE_ACTIVE( slot, *features, snapshots_lt_hash ) || FD_FEATURE_ACTIVE( slot, *features, accounts_lt_hash ) ); FD_LOG_NOTICE(("accounts_hash start")); @@ -1071,10 +1120,10 @@ fd_accounts_hash_inc_only( fd_exec_slot_ctx_t * slot_ctx, fd_hash_account_current( (uchar *) metadata->hash, NULL, metadata, fd_type_pun_const(rec->pair.key->uc), fd_account_meta_get_data(metadata), FD_HASH_JUST_ACCOUNT_HASH, &slot_ctx->epoch_ctx->features ); } else if( do_hash_verify ) { uchar hash[32]; - // ulong old_slot = slot_ctx->slot_bank.slot; - // slot_ctx->slot_bank.slot = metadata->slot; + // ulong old_slot = slot_ctx->slot; + // slot_ctx->slot = metadata->slot; fd_hash_account_current( (uchar *) &hash, NULL, metadata, fd_type_pun_const(rec->pair.key->uc), fd_account_meta_get_data(metadata), FD_HASH_JUST_ACCOUNT_HASH, &slot_ctx->epoch_ctx->features ); - // slot_ctx->slot_bank.slot = old_slot; + // slot_ctx->slot = old_slot; if ( fd_account_meta_exists( metadata ) && memcmp( metadata->hash, &hash, 32 ) != 0 ) { FD_LOG_WARNING(( "snapshot hash (%s) doesn't match calculated hash (%s)", FD_BASE58_ENC_32_ALLOCA( metadata->hash ), FD_BASE58_ENC_32_ALLOCA( &hash ) )); } @@ -1200,6 +1249,7 @@ fd_snapshot_service_hash( fd_hash_t * accounts_hash, fd_tpool_t * tpool, fd_spad_t * runtime_spad, fd_features_t * features ) { + (void)epoch_bank; fd_sha256_t h; @@ -1208,14 +1258,18 @@ fd_snapshot_service_hash( fd_hash_t * accounts_hash, .para_arg_1 = tpool }; - fd_accounts_hash( funk, slot_bank, accounts_hash, runtime_spad, features, &exec_para_ctx, NULL ); + /* FIXME: this has an invalid slot number. */ + (void)slot_bank; + fd_accounts_hash( funk, 0UL, accounts_hash, runtime_spad, features, &exec_para_ctx, NULL ); + - int should_include_eah = epoch_bank->eah_stop_slot != ULONG_MAX && epoch_bank->eah_start_slot == ULONG_MAX; + // int should_include_eah = epoch_bank->eah_stop_slot != ULONG_MAX && epoch_bank->eah_start_slot == ULONG_MAX; + int should_include_eah = 0; if( should_include_eah ) { fd_sha256_init( &h ); fd_sha256_append( &h, (uchar const *) accounts_hash, sizeof( fd_hash_t ) ); - fd_sha256_append( &h, (uchar const *) slot_bank->epoch_account_hash.hash, sizeof( fd_hash_t ) ); + // fd_sha256_append( &h, (uchar const *) slot_bank->epoch_account_hash.hash, sizeof( fd_hash_t ) ); fd_sha256_fini( &h, snapshot_hash ); } else { *snapshot_hash = *accounts_hash; @@ -1237,12 +1291,14 @@ fd_snapshot_service_inc_hash( fd_hash_t * accounts_hash, fd_sha256_t h; fd_accounts_hash_inc_no_txn( funk, accounts_hash, pubkeys, pubkeys_len, 0UL, spad, features ); - int should_include_eah = epoch_bank->eah_stop_slot != ULONG_MAX && epoch_bank->eah_start_slot == ULONG_MAX; + int should_include_eah = 0; + (void)epoch_bank; + (void)slot_bank; if( should_include_eah ) { fd_sha256_init( &h ); fd_sha256_append( &h, (uchar const *) accounts_hash, sizeof( fd_hash_t ) ); - fd_sha256_append( &h, (uchar const *) slot_bank->epoch_account_hash.hash, sizeof( fd_hash_t ) ); + // fd_sha256_append( &h, (uchar const *) slot_bank->epoch_account_hash.hash, sizeof( fd_hash_t ) ); fd_sha256_fini( &h, snapshot_hash ); } else { *snapshot_hash = *accounts_hash; diff --git a/src/flamenco/runtime/fd_hashes.h b/src/flamenco/runtime/fd_hashes.h index e490637788..1d626d9bd1 100644 --- a/src/flamenco/runtime/fd_hashes.h +++ b/src/flamenco/runtime/fd_hashes.h @@ -152,12 +152,12 @@ fd_hash_account_current( uchar hash [ static 32 ], int fd_accounts_hash( fd_funk_t * funk, - fd_slot_bank_t * slot_bank, + ulong slot, fd_hash_t * accounts_hash, fd_spad_t * runtime_spad, fd_features_t * features, fd_exec_para_cb_ctx_t * exec_para_ctx, - fd_lthash_value_t * lt_hash ); + fd_lthash_value_t * lt_hash ); /* Generate a non-incremental hash of the entire account database, including the epoch account hash. It differs from fd_snapshot_hash in that this version diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 925f6b2a2f..4e821b5a11 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -5,6 +5,7 @@ #include "fd_runtime_err.h" #include "fd_runtime_init.h" #include "fd_pubkey_utils.h" +#include "fd_bank_mgr.h" #include "fd_executor.h" #include "fd_cost_tracker.h" @@ -98,15 +99,17 @@ void fd_runtime_register_new_fresh_account( fd_exec_slot_ctx_t * slot_ctx, fd_pubkey_t const * pubkey ) { + fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( slot_ctx->bank_mgr ); + fd_rent_fresh_account_t * fresh_accounts = fd_rent_fresh_accounts_fresh_accounts_join( rent_fresh_accounts ); + /* Insert the new account into the partition */ ulong partition = fd_rent_key_to_partition( pubkey, slot_ctx->part_width, slot_ctx->slots_per_epoch ); - fd_rent_fresh_accounts_t * rent_fresh_accounts = &slot_ctx->slot_bank.rent_fresh_accounts; /* See if there is an unused fresh account we can re-use */ fd_rent_fresh_account_t * rent_fresh_account = NULL; for( ulong i = 0; i < rent_fresh_accounts->fresh_accounts_len; i++ ) { - if( FD_UNLIKELY( rent_fresh_accounts->fresh_accounts[ i ].present == 0UL ) ) { - rent_fresh_account = &rent_fresh_accounts->fresh_accounts[ i ]; + if( FD_UNLIKELY( fresh_accounts[ i ].present == 0UL ) ) { + rent_fresh_account = &fresh_accounts[ i ]; break; } } @@ -120,20 +123,26 @@ fd_runtime_register_new_fresh_account( fd_exec_slot_ctx_t * slot_ctx, rent_fresh_account->present = 1UL; rent_fresh_accounts->total_count++; + + fd_bank_mgr_rent_fresh_accounts_save( slot_ctx->bank_mgr ); } void fd_runtime_repartition_fresh_account_partitions( fd_exec_slot_ctx_t * slot_ctx ) { /* Update the partition in each rent fresh account */ - fd_rent_fresh_accounts_t * rent_fresh_accounts = &slot_ctx->slot_bank.rent_fresh_accounts; + fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( slot_ctx->bank_mgr ); + fd_rent_fresh_account_t * fresh_accounts = fd_rent_fresh_accounts_fresh_accounts_join( rent_fresh_accounts ); + for( ulong i = 0UL; i < rent_fresh_accounts->fresh_accounts_len; i++ ) { - fd_rent_fresh_account_t * rent_fresh_account = &rent_fresh_accounts->fresh_accounts[ i ]; + fd_rent_fresh_account_t * rent_fresh_account = &fresh_accounts[ i ]; if( FD_UNLIKELY( rent_fresh_account->present == 1UL ) ) { rent_fresh_account->partition = fd_rent_key_to_partition( &rent_fresh_account->pubkey, slot_ctx->part_width, slot_ctx->slots_per_epoch ); } } + + fd_bank_mgr_rent_fresh_accounts_save( slot_ctx->bank_mgr ); } void @@ -297,9 +306,11 @@ fd_runtime_run_incinerator( fd_exec_slot_ctx_t * slot_ctx ) { return -1; } - slot_ctx->slot_bank.capitalization = fd_ulong_sat_sub( slot_ctx->slot_bank.capitalization, rec->vt->get_lamports( rec ) ); - rec->vt->set_lamports( rec, 0UL ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); + *capitalization = fd_ulong_sat_sub( *capitalization, rec->vt->get_lamports( rec ) ); + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); + rec->vt->set_lamports( rec, 0UL ); fd_txn_account_mutable_fini( rec, slot_ctx->funk, slot_ctx->funk_txn ); return 0; @@ -315,6 +326,9 @@ fd_runtime_slot_count_in_two_day( ulong ticks_per_slot ) { // https://github.com/firedancer-io/solana/blob/d8292b427adf8367d87068a3a88f6fd3ed8916a5/runtime/src/bank.rs#L5594 static int fd_runtime_use_multi_epoch_collection( fd_exec_slot_ctx_t const * slot_ctx, ulong slot ) { + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( slot_ctx->bank_mgr ); + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); fd_epoch_schedule_t const * schedule = &epoch_bank->epoch_schedule; @@ -322,7 +336,7 @@ fd_runtime_use_multi_epoch_collection( fd_exec_slot_ctx_t const * slot_ctx, ulon ulong epoch = fd_slot_to_epoch( schedule, slot, &off ); ulong slots_per_normal_epoch = fd_epoch_slot_cnt( schedule, schedule->first_normal_epoch ); - ulong slot_count_in_two_day = fd_runtime_slot_count_in_two_day( epoch_bank->ticks_per_slot ); + ulong slot_count_in_two_day = fd_runtime_slot_count_in_two_day( *ticks_per_slot ); int use_multi_epoch_collection = ( epoch >= schedule->first_normal_epoch ) && ( slots_per_normal_epoch < slot_count_in_two_day ); @@ -332,6 +346,9 @@ fd_runtime_use_multi_epoch_collection( fd_exec_slot_ctx_t const * slot_ctx, ulon FD_FN_UNUSED static ulong fd_runtime_num_rent_partitions( fd_exec_slot_ctx_t const * slot_ctx, ulong slot ) { + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( slot_ctx->bank_mgr ); + fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); fd_epoch_schedule_t const * schedule = &epoch_bank->epoch_schedule; @@ -339,7 +356,7 @@ fd_runtime_num_rent_partitions( fd_exec_slot_ctx_t const * slot_ctx, ulong slot ulong epoch = fd_slot_to_epoch( schedule, slot, &off ); ulong slots_per_epoch = fd_epoch_slot_cnt( schedule, epoch ); - ulong slot_count_in_two_day = fd_runtime_slot_count_in_two_day( epoch_bank->ticks_per_slot ); + ulong slot_count_in_two_day = fd_runtime_slot_count_in_two_day( *ticks_per_slot ); int use_multi_epoch_collection = fd_runtime_use_multi_epoch_collection( slot_ctx, slot ); @@ -354,6 +371,9 @@ fd_runtime_num_rent_partitions( fd_exec_slot_ctx_t const * slot_ctx, ulong slot // https://github.com/anza-xyz/agave/blob/2bdcc838c18d262637524274cbb2275824eb97b8/accounts-db/src/accounts_partition.rs#L30 static ulong fd_runtime_get_rent_partition( fd_exec_slot_ctx_t const * slot_ctx, ulong slot ) { + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( slot_ctx->bank_mgr ); + int use_multi_epoch_collection = fd_runtime_use_multi_epoch_collection( slot_ctx, slot ); fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); @@ -362,7 +382,7 @@ fd_runtime_get_rent_partition( fd_exec_slot_ctx_t const * slot_ctx, ulong slot ) ulong off; ulong epoch = fd_slot_to_epoch( schedule, slot, &off ); ulong slot_count_per_epoch = fd_epoch_slot_cnt( schedule, epoch ); - ulong slot_count_in_two_day = fd_runtime_slot_count_in_two_day( epoch_bank->ticks_per_slot ); + ulong slot_count_in_two_day = fd_runtime_slot_count_in_two_day( *ticks_per_slot ); ulong base_epoch; ulong epoch_count_in_cycle; @@ -422,20 +442,22 @@ fd_runtime_update_rent_epoch_account( fd_exec_slot_ctx_t * slot_ctx, https://github.com/anza-xyz/agave/blob/v2.1.14/runtime/src/bank.rs#L2921 */ static void fd_runtime_update_rent_epoch( fd_exec_slot_ctx_t * slot_ctx ) { - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_partitioned_rent_collection ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, disable_partitioned_rent_collection ) ) { return; } - fd_rent_fresh_accounts_t * rent_fresh_accounts = &slot_ctx->slot_bank.rent_fresh_accounts; + fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( slot_ctx->bank_mgr ); + fd_rent_fresh_account_t * fresh_accounts = fd_rent_fresh_accounts_fresh_accounts_join( rent_fresh_accounts ); /* Common case: do nothing if we have no rent fresh accounts */ if( FD_LIKELY( rent_fresh_accounts->total_count == 0UL ) ) { + fd_bank_mgr_rent_fresh_accounts_save( slot_ctx->bank_mgr ); return; } ulong slot0 = (slot_ctx->slot_bank.prev_slot == 0) ? 0 : slot_ctx->slot_bank.prev_slot + 1; /* Accomodate skipped slots */ - ulong slot1 = slot_ctx->slot_bank.slot; + ulong slot1 = slot_ctx->slot; for( ulong s = slot0; s <= slot1; ++s ) { @@ -443,7 +465,7 @@ fd_runtime_update_rent_epoch( fd_exec_slot_ctx_t * slot_ctx ) { /* Iterate over each rent fresh account, updating rent_epoch if it is in this slots partition */ for( ulong i = 0UL; i < rent_fresh_accounts->fresh_accounts_len; i++ ) { - fd_rent_fresh_account_t * rent_fresh_account = &rent_fresh_accounts->fresh_accounts[ i ]; + fd_rent_fresh_account_t * rent_fresh_account = &fresh_accounts[ i ]; if( FD_UNLIKELY( ( rent_fresh_account->present == 1UL ) && rent_fresh_account->partition == partition ) ) { /* Update the rent epoch value for this account */ @@ -455,6 +477,7 @@ fd_runtime_update_rent_epoch( fd_exec_slot_ctx_t * slot_ctx ) { } } } + fd_bank_mgr_rent_fresh_accounts_save( slot_ctx->bank_mgr ); } static void @@ -464,17 +487,21 @@ fd_runtime_freeze( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { fd_sysvar_recent_hashes_update( slot_ctx, runtime_spad ); - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar) ) + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar) ) fd_sysvar_fees_update( slot_ctx, runtime_spad ); ulong fees = 0UL; ulong burn = 0UL; - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, reward_full_priority_fee ) ) { - ulong half_fee = slot_ctx->slot_bank.collected_execution_fees / 2; - fees = fd_ulong_sat_add( slot_ctx->slot_bank.collected_priority_fees, slot_ctx->slot_bank.collected_execution_fees - half_fee ); + + ulong * execution_fees = fd_bank_mgr_execution_fees_query( slot_ctx->bank_mgr ); + ulong * priority_fees = fd_bank_mgr_priority_fees_query( slot_ctx->bank_mgr ); + + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, reward_full_priority_fee ) ) { + ulong half_fee = *execution_fees / 2; + fees = fd_ulong_sat_add( *priority_fees, *execution_fees - half_fee ); burn = half_fee; } else { - ulong total_fees = fd_ulong_sat_add( slot_ctx->slot_bank.collected_execution_fees, slot_ctx->slot_bank.collected_priority_fees ); + ulong total_fees = fd_ulong_sat_add( *execution_fees, *priority_fees ); ulong half_fee = total_fees / 2; fees = total_fees - half_fee; burn = half_fee; @@ -486,7 +513,7 @@ fd_runtime_freeze( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { do { /* do_create=1 because we might wanna pay fees to a leader account that we've purged due to 0 balance. */ - fd_pubkey_t const * leader = fd_epoch_leaders_get( fd_exec_epoch_ctx_leaders( slot_ctx->epoch_ctx ), slot_ctx->slot_bank.slot ); + fd_pubkey_t const * leader = fd_epoch_leaders_get( fd_exec_epoch_ctx_leaders( slot_ctx->epoch_ctx ), slot_ctx->slot ); int err = fd_txn_account_init_from_funk_mutable( rec, leader, slot_ctx->funk, slot_ctx->funk_txn, 1, 0UL ); if( FD_UNLIKELY(err) ) { FD_LOG_WARNING(("fd_runtime_freeze: fd_txn_account_init_from_funk_mutable for leader (%s) failed (%d)", FD_BASE58_ENC_32_ALLOCA( leader ), err)); @@ -494,7 +521,7 @@ fd_runtime_freeze( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { break; } - if ( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, validate_fee_collector_account ) ) ) { + if ( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, validate_fee_collector_account ) ) ) { ulong _burn; if( FD_UNLIKELY( _burn=fd_runtime_validate_fee_collector( slot_ctx, rec, fees ) ) ) { if( FD_UNLIKELY( _burn!=fees ) ) { @@ -508,7 +535,7 @@ fd_runtime_freeze( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { /* TODO: is it ok to not check the overflow error here? */ rec->vt->checked_add_lamports( rec, fees ); - rec->vt->set_slot( rec, slot_ctx->slot_bank.slot ); + rec->vt->set_slot( rec, slot_ctx->slot ); slot_ctx->block_rewards.post_balance = rec->vt->get_lamports( rec ); fd_txn_account_mutable_fini( rec, slot_ctx->funk, slot_ctx->funk_txn ); @@ -517,18 +544,26 @@ fd_runtime_freeze( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { slot_ctx->block_rewards.leader = *leader; } while(0); - ulong old = slot_ctx->slot_bank.capitalization; - slot_ctx->slot_bank.capitalization = fd_ulong_sat_sub( slot_ctx->slot_bank.capitalization, burn); - FD_LOG_DEBUG(( "fd_runtime_freeze: burn %lu, capitalization %lu->%lu ", burn, old, slot_ctx->slot_bank.capitalization)); + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); + + ulong old = *capitalization; + *capitalization = fd_ulong_sat_sub( *capitalization, burn ); + FD_LOG_DEBUG(( "fd_runtime_freeze: burn %lu, capitalization %lu->%lu ", burn, old, *capitalization)); - slot_ctx->slot_bank.collected_execution_fees = 0; - slot_ctx->slot_bank.collected_priority_fees = 0; + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); + + execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); + *execution_fees = 0UL; + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); + + priority_fees = fd_bank_mgr_priority_fees_modify( slot_ctx->bank_mgr ); + *priority_fees = 0UL; + fd_bank_mgr_priority_fees_save( slot_ctx->bank_mgr ); } fd_runtime_run_incinerator( slot_ctx ); - FD_LOG_DEBUG(( "fd_runtime_freeze: capitalization %lu ", slot_ctx->slot_bank.capitalization)); - slot_ctx->slot_bank.collected_rent = 0; + /* At this point we want to invalidate the sysvar cache entries. */ fd_sysvar_cache_invalidate( slot_ctx->sysvar_cache ); @@ -733,7 +768,7 @@ fd_runtime_write_transaction_status( fd_capture_ctx_t * capture_ctx, } fd_solcap_Transaction txn = { - .slot = slot_ctx->slot_bank.slot, + .slot = slot_ctx->slot, .fd_txn_err = exec_txn_err, .fd_custom_err = txn_ctx->custom_err, .solana_txn_err = solana_txn_err, @@ -980,21 +1015,22 @@ fd_runtime_block_sysvar_update_pre_execute( fd_exec_slot_ctx_t * slot_ctx, // FeeRateGovernor::new_derived(&parent.fee_rate_governor, parent.signature_count()) // ); /* https://github.com/firedancer-io/solana/blob/dab3da8e7b667d7527565bddbdbecf7ec1fb868e/runtime/src/bank.rs#L1312-L1314 */ - fd_sysvar_fees_new_derived( slot_ctx, - slot_ctx->slot_bank.fee_rate_governor, - slot_ctx->slot_bank.parent_signature_cnt ); + + ulong * parent_signature_cnt = fd_bank_mgr_parent_signature_cnt_query( slot_ctx->bank_mgr ); + + fd_sysvar_fees_new_derived( slot_ctx, *parent_signature_cnt ); // TODO: move all these out to a fd_sysvar_update() call... long clock_update_time = -fd_log_wallclock(); fd_sysvar_clock_update( slot_ctx, runtime_spad ); clock_update_time += fd_log_wallclock(); double clock_update_time_ms = (double)clock_update_time * 1e-6; - FD_LOG_INFO(( "clock updated - slot: %lu, elapsed: %6.6f ms", slot_ctx->slot_bank.slot, clock_update_time_ms )); - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar ) ) { + FD_LOG_INFO(( "clock updated - slot: %lu, elapsed: %6.6f ms", slot_ctx->slot, clock_update_time_ms )); + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar ) ) { fd_sysvar_fees_update( slot_ctx, runtime_spad ); } // It has to go into the current txn previous info but is not in slot 0 - if( slot_ctx->slot_bank.slot != 0 ) { + if( slot_ctx->slot != 0 ) { fd_sysvar_slot_hashes_update( slot_ctx, runtime_spad ); } fd_sysvar_last_restart_slot_update( slot_ctx, runtime_spad ); @@ -1483,16 +1519,25 @@ int fd_runtime_block_execute_prepare( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { - if( slot_ctx->blockstore && slot_ctx->slot_bank.slot != 0UL ) { + + if( slot_ctx->blockstore && slot_ctx->slot != 0UL ) { fd_blockstore_block_height_update( slot_ctx->blockstore, - slot_ctx->slot_bank.slot, - slot_ctx->slot_bank.block_height ); + slot_ctx->slot, + *(fd_bank_mgr_block_height_query( slot_ctx->bank_mgr )) ); } - slot_ctx->slot_bank.collected_execution_fees = 0UL; - slot_ctx->slot_bank.collected_priority_fees = 0UL; - slot_ctx->slot_bank.collected_rent = 0UL; - slot_ctx->signature_cnt = 0UL; + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); + *execution_fees = 0UL; + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( slot_ctx->bank_mgr ); + *priority_fees = 0UL; + fd_bank_mgr_priority_fees_save( slot_ctx->bank_mgr ); + + ulong * signature_cnt = fd_bank_mgr_signature_cnt_modify( slot_ctx->bank_mgr ); + *signature_cnt = 0UL; + fd_bank_mgr_signature_cnt_save( slot_ctx->bank_mgr ); + slot_ctx->txn_count = 0UL; slot_ctx->nonvote_txn_count = 0UL; slot_ctx->failed_txn_count = 0UL; @@ -1816,7 +1861,8 @@ fd_runtime_pre_execute_check( fd_execute_txn_task_info_t * task_info, /* fd_runtime_finalize_txn is a helper used by the non-tpool transaction executor to finalize borrowed account changes back into funk. It also - handles txncache insertion and updates to the vote/stake cache. */ + handles txncache insertion and updates to the vote/stake cache. + TODO: This function should probably be moved to fd_executor.c. */ void fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, @@ -1824,22 +1870,35 @@ fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, fd_execute_txn_task_info_t * task_info, fd_spad_t * finalize_spad ) { + /* for all accounts, if account->is_verified==true, propagate update + to cache entry. */ + /* Store transaction info including logs */ // fd_runtime_finalize_txns_update_blockstore_meta( slot_ctx, task_info, 1UL ); /* Collect fees */ - FD_ATOMIC_FETCH_AND_ADD( &slot_ctx->slot_bank.collected_execution_fees, task_info->txn_ctx->execution_fee ); - FD_ATOMIC_FETCH_AND_ADD( &slot_ctx->slot_bank.collected_priority_fees, task_info->txn_ctx->priority_fee ); - FD_ATOMIC_FETCH_AND_ADD( &slot_ctx->slot_bank.collected_rent, task_info->txn_ctx->collected_rent ); + + fd_bank_mgr_t * bank_mgr = task_info->txn_ctx->bank_mgr; + + ulong * execution_fee = fd_bank_mgr_execution_fees_modify( bank_mgr ); + *execution_fee += task_info->txn_ctx->execution_fee; + fd_bank_mgr_execution_fees_save( bank_mgr ); + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( bank_mgr ); + *priority_fees += task_info->txn_ctx->priority_fee; + fd_bank_mgr_priority_fees_save( bank_mgr ); fd_exec_txn_ctx_t * txn_ctx = task_info->txn_ctx; int exec_txn_err = task_info->exec_res; /* For ledgers that contain txn status, decode and write out for solcap */ - if( capture_ctx != NULL && capture_ctx->capture && capture_ctx->capture_txns && slot_ctx->slot_bank.slot>=capture_ctx->solcap_start_slot ) { + if( capture_ctx != NULL && capture_ctx->capture && capture_ctx->capture_txns && slot_ctx->slot>=capture_ctx->solcap_start_slot ) { fd_runtime_write_transaction_status( capture_ctx, slot_ctx, txn_ctx, exec_txn_err ); } - FD_ATOMIC_FETCH_AND_ADD( &slot_ctx->signature_cnt, txn_ctx->txn_descriptor->signature_cnt ); + + ulong * signature_cnt = fd_bank_mgr_signature_cnt_modify( bank_mgr ); + *signature_cnt += txn_ctx->txn_descriptor->signature_cnt; + fd_bank_mgr_signature_cnt_save( bank_mgr ); // if( slot_ctx->status_cache ) { // fd_txncache_insert_t status_insert = {0}; @@ -1847,7 +1906,7 @@ fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, // fd_txncache_insert_t * curr_insert = &status_insert; // curr_insert->blockhash = ((uchar *)txn_ctx->_txn_raw->raw + txn_ctx->txn_descriptor->recent_blockhash_off); - // curr_insert->slot = slot_ctx->slot_bank.slot; + // curr_insert->slot = slot_ctx->slot; // fd_hash_t * hash = &txn_ctx->blake_txn_msg_hash; // curr_insert->txnhash = hash->uc; // curr_insert->result = &result; @@ -1971,7 +2030,7 @@ fd_runtime_prepare_and_execute_txn( fd_exec_slot_ctx_t const * slot_ctx, fd_spad_t * exec_spad, fd_capture_ctx_t * capture_ctx ) { - uchar dump_txn = !!( capture_ctx && slot_ctx->slot_bank.slot >= capture_ctx->dump_proto_start_slot && capture_ctx->dump_txn_to_pb ); + uchar dump_txn = !!( capture_ctx && slot_ctx->slot >= capture_ctx->dump_proto_start_slot && capture_ctx->dump_txn_to_pb ); int res = 0; fd_exec_txn_ctx_t * txn_ctx = task_info->txn_ctx; @@ -2129,6 +2188,8 @@ fd_runtime_process_txns_in_microblock_stream( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_ERR(( "failed to allocate txn ctx" )); } + task_infos[ curr_exec_idx ].txn_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( task_infos[ curr_exec_idx ].txn_ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); + fd_tpool_exec( tpool, worker_idx, fd_runtime_prepare_execute_finalize_txn_task, slot_ctx, (ulong)capture_ctx, (ulong)task_infos[curr_exec_idx].txn, &task_infos[ curr_exec_idx ], exec_spads[ worker_idx ], 0UL, @@ -2144,7 +2205,7 @@ fd_runtime_process_txns_in_microblock_stream( fd_exec_slot_ctx_t * slot_ctx, /* Verify cost tracker limits (only for offline replay) https://github.com/anza-xyz/agave/blob/v2.2.0/ledger/src/blockstore_processor.rs#L284-L299 */ - if( cost_tracker_opt!=NULL && FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, apply_cost_tracker_during_replay ) ) { + if( cost_tracker_opt!=NULL && FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, apply_cost_tracker_during_replay ) ) { for( ulong i=exec_idx_start; islot_bank.slot )); + FD_LOG_WARNING(( "Block cost limits exceeded for slot %lu", slot_ctx->slot )); break; } } @@ -2195,7 +2256,6 @@ static void fd_update_stake_delegations( fd_exec_slot_ctx_t * slot_ctx, fd_epoch_info_t * temp_info ) { fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; fd_stakes_t * stakes = &epoch_bank->stakes; /* In one pass, iterate over all the new stake infos and insert the updated values into the epoch stakes cache @@ -2213,8 +2273,26 @@ fd_update_stake_delegations( fd_exec_slot_ctx_t * slot_ctx, } } - fd_account_keys_pair_t_map_release_tree( slot_bank->stake_account_keys.account_keys_pool, slot_bank->stake_account_keys.account_keys_root ); - slot_bank->stake_account_keys.account_keys_root = NULL; + // fd_bank_mgr_t bank_mgr_obj; + // fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_query( slot_ctx->bank_mgr ); + if( FD_UNLIKELY( stake_account_keys==NULL ) ) { + return; + } + + stake_account_keys = fd_bank_mgr_stake_account_keys_modify( slot_ctx->bank_mgr ); + + fd_account_keys_pair_t_mapnode_t * account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); + fd_account_keys_pair_t_mapnode_t * account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); + + fd_account_keys_pair_t_map_release_tree( account_keys_pool, account_keys_root ); + account_keys_root = NULL; + + fd_account_keys_account_keys_pool_update( stake_account_keys, account_keys_pool ); + fd_account_keys_account_keys_root_update( stake_account_keys, account_keys_root ); + + fd_bank_mgr_stake_account_keys_save( slot_ctx->bank_mgr ); } /* Replace the stakes in T-2 (slot_ctx->slot_bank.epoch_stakes) by the stakes at T-1 (epoch_bank->next_epoch_stakes) */ @@ -2378,7 +2456,7 @@ fd_new_target_program_data_account( fd_exec_slot_ctx_t * slot_ctx, .discriminant = fd_bpf_upgradeable_loader_state_enum_program_data, .inner = { .program_data = { - .slot = slot_ctx->slot_bank.slot, + .slot = slot_ctx->slot, .upgrade_authority_address = config_upgrade_authority_address } } @@ -2528,7 +2606,7 @@ fd_migrate_builtin_to_core_bpf( fd_exec_slot_ctx_t * slot_ctx, goto fail; } new_target_program_account->vt->set_data_len( new_target_program_account, SIZE_OF_PROGRAM ); - new_target_program_account->vt->set_slot( new_target_program_account, slot_ctx->slot_bank.slot ); + new_target_program_account->vt->set_slot( new_target_program_account, slot_ctx->slot ); /* Create a new target program account. This modifies the existing record. */ err = fd_new_target_program_account( slot_ctx, target_program_data_address, new_target_program_account ); @@ -2553,7 +2631,7 @@ fd_migrate_builtin_to_core_bpf( fd_exec_slot_ctx_t * slot_ctx, goto fail; } new_target_program_data_account->vt->set_data_len( new_target_program_data_account, new_target_program_data_account_sz ); - new_target_program_data_account->vt->set_slot( new_target_program_data_account, slot_ctx->slot_bank.slot ); + new_target_program_data_account->vt->set_slot( new_target_program_data_account, slot_ctx->slot ); err = fd_new_target_program_data_account( slot_ctx, upgrade_authority_address, @@ -2581,13 +2659,16 @@ fd_migrate_builtin_to_core_bpf( fd_exec_slot_ctx_t * slot_ctx, /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L281-L284 */ ulong lamports_to_fund = new_target_program_account->vt->get_lamports( new_target_program_account ) + new_target_program_data_account->vt->get_lamports( new_target_program_data_account ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); + /* Update capitalization. https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L286-L297 */ if( lamports_to_burn>lamports_to_fund ) { - slot_ctx->slot_bank.capitalization -= lamports_to_burn - lamports_to_fund; + *capitalization -= lamports_to_burn - lamports_to_fund; } else { - slot_ctx->slot_bank.capitalization += lamports_to_fund - lamports_to_burn; + *capitalization += lamports_to_fund - lamports_to_burn; } + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); /* Reclaim the source buffer account https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L305 */ @@ -2630,7 +2711,7 @@ fd_apply_builtin_program_feature_transitions( fd_exec_slot_ctx_t * slot_ctx, fd_builtin_program_t const * builtins = fd_builtins(); for( ulong i=0UL; islot_bank.slot, slot_ctx->epoch_ctx->features, builtins[i].core_bpf_migration_config->enable_feature_offset ) ) { + if( builtins[i].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET( slot_ctx->slot, slot_ctx->epoch_ctx->features, builtins[i].core_bpf_migration_config->enable_feature_offset ) ) { FD_LOG_NOTICE(( "Migrating builtin program %s to core BPF", FD_BASE58_ENC_32_ALLOCA( builtins[i].pubkey->key ) )); fd_migrate_builtin_to_core_bpf( slot_ctx, builtins[i].core_bpf_migration_config->upgrade_authority_address, @@ -2649,7 +2730,7 @@ fd_apply_builtin_program_feature_transitions( fd_exec_slot_ctx_t * slot_ctx, /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6776-L6793 */ fd_stateless_builtin_program_t const * stateless_builtins = fd_stateless_builtins(); for( ulong i=0UL; islot_bank.slot, slot_ctx->epoch_ctx->features, stateless_builtins[i].core_bpf_migration_config->enable_feature_offset ) ) { + if( stateless_builtins[i].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET( slot_ctx->slot, slot_ctx->epoch_ctx->features, stateless_builtins[i].core_bpf_migration_config->enable_feature_offset ) ) { FD_LOG_NOTICE(( "Migrating stateless builtin program %s to core BPF", FD_BASE58_ENC_32_ALLOCA( stateless_builtins[i].pubkey->key ) )); fd_migrate_builtin_to_core_bpf( slot_ctx, stateless_builtins[i].core_bpf_migration_config->upgrade_authority_address, @@ -2706,7 +2787,7 @@ fd_feature_activate( fd_exec_slot_ctx_t * slot_ctx, } feature->has_activated_at = 1; - feature->activated_at = slot_ctx->slot_bank.slot; + feature->activated_at = slot_ctx->slot; fd_bincode_encode_ctx_t encode_ctx = { .data = modify_acct_rec->vt->get_data_mut( modify_acct_rec ), .dataend = modify_acct_rec->vt->get_data_mut( modify_acct_rec ) + modify_acct_rec->vt->get_data_len( modify_acct_rec ), @@ -2768,7 +2849,7 @@ fd_runtime_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, ulong slot; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot, &slot ); + ulong epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot, &slot ); /* Activate new features https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6587-L6598 */ @@ -2781,23 +2862,34 @@ fd_runtime_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, /* Change the speed of the poh clock https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6627-L6649 */ + if( FD_FEATURE_JUST_ACTIVATED( slot_ctx, update_hashes_per_tick6 ) ) { - epoch_bank->hashes_per_tick = UPDATED_HASHES_PER_TICK6; + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); + *hashes_per_tick = UPDATED_HASHES_PER_TICK6; + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); } else if( FD_FEATURE_JUST_ACTIVATED( slot_ctx, update_hashes_per_tick5 ) ) { - epoch_bank->hashes_per_tick = UPDATED_HASHES_PER_TICK5; + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); + *hashes_per_tick = UPDATED_HASHES_PER_TICK5; + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); } else if( FD_FEATURE_JUST_ACTIVATED( slot_ctx, update_hashes_per_tick4 ) ) { - epoch_bank->hashes_per_tick = UPDATED_HASHES_PER_TICK4; + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); + *hashes_per_tick = UPDATED_HASHES_PER_TICK4; + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); } else if( FD_FEATURE_JUST_ACTIVATED( slot_ctx, update_hashes_per_tick3 ) ) { - epoch_bank->hashes_per_tick = UPDATED_HASHES_PER_TICK3; + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); + *hashes_per_tick = UPDATED_HASHES_PER_TICK3; + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); } else if( FD_FEATURE_JUST_ACTIVATED( slot_ctx, update_hashes_per_tick2 ) ) { - epoch_bank->hashes_per_tick = UPDATED_HASHES_PER_TICK2; + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); + *hashes_per_tick = UPDATED_HASHES_PER_TICK2; + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); } /* Get the new rate activation epoch */ int _err[1]; ulong new_rate_activation_epoch_val = 0UL; ulong * new_rate_activation_epoch = &new_rate_activation_epoch_val; - int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot_bank.slot, + int is_some = fd_new_warmup_cooldown_rate_epoch( slot_ctx->slot, slot_ctx->sysvar_cache, &slot_ctx->epoch_ctx->features, slot_ctx->runtime_wksp, @@ -2813,7 +2905,9 @@ fd_runtime_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, /* If appropiate, use the stakes at T-1 to generate the leader schedule instead of T-2. This is due to a subtlety in how Agave's stake caches interact when loading from snapshots. See the comment in fd_exec_slot_ctx_recover_. */ - if( slot_ctx->slot_bank.has_use_preceeding_epoch_stakes && slot_ctx->slot_bank.use_preceeding_epoch_stakes == epoch ) { + + ulong * use_prev_stakes = fd_bank_mgr_use_prev_epoch_stake_query( slot_ctx->bank_mgr ); + if( use_prev_stakes && *use_prev_stakes == epoch ) { fd_update_epoch_stakes( slot_ctx ); } @@ -2858,9 +2952,12 @@ fd_runtime_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, runtime_spad ); /* Distribute rewards */ - fd_hash_t const * parent_blockhash = slot_ctx->slot_bank.block_hash_queue.last_hash; - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) { + + fd_block_hash_queue_global_t const * bhq = fd_bank_mgr_block_hash_queue_query( slot_ctx->bank_mgr ); + fd_hash_t const * parent_blockhash = fd_block_hash_queue_last_hash_join( bhq ); + + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) { FD_LOG_NOTICE(( "fd_begin_partitioned_rewards" )); fd_begin_partitioned_rewards( slot_ctx, parent_blockhash, @@ -2888,7 +2985,7 @@ fd_runtime_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, fd_update_next_epoch_stakes( slot_ctx ); /* Update current leaders using slot_ctx->slot_bank.epoch_stakes (new T-2 stakes) */ - fd_runtime_update_leaders( slot_ctx, slot_ctx->slot_bank.slot, runtime_spad ); + fd_runtime_update_leaders( slot_ctx, slot_ctx->slot, runtime_spad ); fd_calculate_epoch_accounts_hash_values( slot_ctx ); @@ -3326,7 +3423,7 @@ fd_runtime_init_program( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_slot_history_init( slot_ctx, runtime_spad ); fd_sysvar_slot_hashes_init( slot_ctx, runtime_spad ); fd_sysvar_epoch_schedule_init( slot_ctx ); - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar ) ) { + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar ) ) { fd_sysvar_fees_init( slot_ctx ); } fd_sysvar_rent_init( slot_ctx ); @@ -3342,51 +3439,90 @@ fd_runtime_init_bank_from_genesis( fd_exec_slot_ctx_t * slot_ctx, fd_genesis_solana_t const * genesis_block, fd_hash_t const * genesis_hash, fd_spad_t * runtime_spad ) { - slot_ctx->slot_bank.slot = 0UL; + slot_ctx->slot = 0UL; - memcpy( &slot_ctx->slot_bank.poh, genesis_hash->hash, FD_SHA256_HASH_SZ ); - memset( slot_ctx->slot_bank.banks_hash.hash, 0, FD_SHA256_HASH_SZ ); + fd_hash_t * poh_bm = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); + fd_memcpy( poh_bm->hash, genesis_hash->hash, FD_SHA256_HASH_SZ ); + fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); - slot_ctx->slot_bank.fee_rate_governor = genesis_block->fee_rate_governor; - slot_ctx->slot_bank.lamports_per_signature = 0UL; - slot_ctx->prev_lamports_per_signature = 0UL; + memset( slot_ctx->slot_bank.banks_hash.hash, 0, FD_SHA256_HASH_SZ ); fd_poh_config_t const * poh = &genesis_block->poh_config; fd_exec_epoch_ctx_t * epoch_ctx = slot_ctx->epoch_ctx; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( epoch_ctx ); - if( poh->has_hashes_per_tick ) { - epoch_bank->hashes_per_tick = poh->hashes_per_tick; - } else { - epoch_bank->hashes_per_tick = 0UL; - } - epoch_bank->ticks_per_slot = genesis_block->ticks_per_slot; - epoch_bank->genesis_creation_time = genesis_block->creation_time; uint128 target_tick_duration = ((uint128)poh->target_tick_duration.seconds * 1000000000UL + (uint128)poh->target_tick_duration.nanoseconds); - epoch_bank->ns_per_slot = target_tick_duration * epoch_bank->ticks_per_slot; - epoch_bank->slots_per_year = SECONDS_PER_YEAR * (1000000000.0 / (double)target_tick_duration) / (double)epoch_bank->ticks_per_slot; - epoch_bank->genesis_creation_time = genesis_block->creation_time; - slot_ctx->slot_bank.max_tick_height = epoch_bank->ticks_per_slot * (slot_ctx->slot_bank.slot + 1); epoch_bank->epoch_schedule = genesis_block->epoch_schedule; - epoch_bank->inflation = genesis_block->inflation; epoch_bank->rent = genesis_block->rent; - slot_ctx->slot_bank.block_height = 0UL; - slot_ctx->slot_bank.block_hash_queue.ages_root = NULL; - uchar * pool_mem = fd_spad_alloc( runtime_spad, fd_hash_hash_age_pair_t_map_align(), fd_hash_hash_age_pair_t_map_footprint( FD_HASH_FOOTPRINT * 400 ) ); - slot_ctx->slot_bank.block_hash_queue.ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( pool_mem, FD_HASH_FOOTPRINT * 400 ) ); - fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( slot_ctx->slot_bank.block_hash_queue.ages_pool ); + ulong * block_height = fd_bank_mgr_block_height_modify( slot_ctx->bank_mgr ); + *block_height = 0UL; + fd_bank_mgr_block_height_save( slot_ctx->bank_mgr ); + + fd_inflation_t * inflation = fd_bank_mgr_inflation_modify( slot_ctx->bank_mgr ); + *inflation = genesis_block->inflation; + fd_bank_mgr_inflation_save( slot_ctx->bank_mgr ); + + fd_block_hash_queue_global_t * block_hash_queue = fd_bank_mgr_block_hash_queue_modify( slot_ctx->bank_mgr ); + uchar * last_hash_mem = (uchar *)fd_ulong_align_up( (ulong)block_hash_queue + sizeof(fd_block_hash_queue_global_t), alignof(fd_hash_t) ); + uchar * ages_pool_mem = (uchar *)fd_ulong_align_up( (ulong)last_hash_mem + sizeof(fd_hash_t), fd_hash_hash_age_pair_t_map_align() ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( ages_pool_mem, 400 ) ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = NULL; + + fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( ages_pool ); node->elem = (fd_hash_hash_age_pair_t){ .key = *genesis_hash, - .val = (fd_hash_age_t){ .hash_index = 0UL, .fee_calculator = (fd_fee_calculator_t){.lamports_per_signature = 0UL}, .timestamp = (ulong)fd_log_wallclock() } + .val = (fd_hash_age_t){ .hash_index = 0UL, .fee_calculator = (fd_fee_calculator_t){ .lamports_per_signature = 0UL }, .timestamp = (ulong)fd_log_wallclock() } }; - fd_hash_hash_age_pair_t_map_insert( slot_ctx->slot_bank.block_hash_queue.ages_pool, &slot_ctx->slot_bank.block_hash_queue.ages_root, node ); - slot_ctx->slot_bank.block_hash_queue.last_hash_index = 0UL; - slot_ctx->slot_bank.block_hash_queue.last_hash = fd_spad_alloc( runtime_spad, FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); - fd_memcpy( slot_ctx->slot_bank.block_hash_queue.last_hash, genesis_hash, FD_HASH_FOOTPRINT ); - slot_ctx->slot_bank.block_hash_queue.max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; + fd_hash_hash_age_pair_t_map_insert( ages_pool, &ages_root, node ); + fd_memcpy( last_hash_mem, genesis_hash, FD_HASH_FOOTPRINT ); + + block_hash_queue->last_hash_index = 0UL; + block_hash_queue->last_hash_offset = (ulong)last_hash_mem - (ulong)block_hash_queue; + block_hash_queue->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)block_hash_queue; + block_hash_queue->ages_root_offset = (ulong)ages_root - (ulong)block_hash_queue; + block_hash_queue->max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; + fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); + + fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_query( slot_ctx->bank_mgr ); + *fee_rate_governor = genesis_block->fee_rate_governor; + fd_bank_mgr_fee_rate_governor_save( slot_ctx->bank_mgr ); + + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *lamports_per_signature = 0UL; + fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); + + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *prev_lamports_per_signature = 0UL; + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); + + ulong * max_tick_height = fd_bank_mgr_max_tick_height_modify( slot_ctx->bank_mgr ); + *max_tick_height = genesis_block->ticks_per_slot * (slot_ctx->slot + 1); + fd_bank_mgr_max_tick_height_save( slot_ctx->bank_mgr ); + + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); + *hashes_per_tick = !!poh->hashes_per_tick ? poh->hashes_per_tick : 0UL; + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); + + uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_modify( slot_ctx->bank_mgr ); + *ns_per_slot = target_tick_duration * genesis_block->ticks_per_slot; + fd_bank_mgr_ns_per_slot_save( slot_ctx->bank_mgr ); + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_modify( slot_ctx->bank_mgr ); + *ticks_per_slot = genesis_block->ticks_per_slot; + fd_bank_mgr_ticks_per_slot_save( slot_ctx->bank_mgr ); - slot_ctx->signature_cnt = 0UL; + ulong * genesis_creation_time = fd_bank_mgr_genesis_creation_time_modify( slot_ctx->bank_mgr ); + *genesis_creation_time = genesis_block->creation_time; + fd_bank_mgr_genesis_creation_time_save( slot_ctx->bank_mgr ); + + double * slots_per_year = fd_bank_mgr_slots_per_year_modify( slot_ctx->bank_mgr ); + *slots_per_year = SECONDS_PER_YEAR * (1000000000.0 / (double)target_tick_duration) / (double)genesis_block->ticks_per_slot; + fd_bank_mgr_slots_per_year_save( slot_ctx->bank_mgr ); + + ulong * signature_cnt = fd_bank_mgr_signature_cnt_modify( slot_ctx->bank_mgr ); + *signature_cnt = 0UL; + fd_bank_mgr_signature_cnt_save( slot_ctx->bank_mgr ); /* Derive epoch stakes */ @@ -3526,7 +3662,7 @@ fd_runtime_init_bank_from_genesis( fd_exec_slot_ctx_t * slot_ctx, } } - pool_mem = fd_spad_alloc( runtime_spad, fd_vote_accounts_pair_t_map_align(), fd_vote_accounts_pair_t_map_footprint( FD_HASH_FOOTPRINT * 400 ) ); + uchar * pool_mem = fd_spad_alloc( runtime_spad, fd_vote_accounts_pair_t_map_align(), fd_vote_accounts_pair_t_map_footprint( FD_HASH_FOOTPRINT * 400 ) ); slot_ctx->slot_bank.epoch_stakes.vote_accounts_pool = fd_vote_accounts_pair_t_map_join( fd_vote_accounts_pair_t_map_new( pool_mem, FD_HASH_FOOTPRINT * 400 ) ); slot_ctx->slot_bank.epoch_stakes.vote_accounts_root = NULL; @@ -3577,30 +3713,45 @@ fd_runtime_init_bank_from_genesis( fd_exec_slot_ctx_t * slot_ctx, .stake_history = {0} }; - slot_ctx->slot_bank.capitalization = capitalization; - pool_mem = fd_spad_alloc( runtime_spad, - fd_clock_timestamp_vote_t_map_align(), - fd_clock_timestamp_vote_t_map_footprint( FD_HASH_FOOTPRINT * 400 ) ); - slot_ctx->slot_bank.timestamp_votes.votes_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new( pool_mem, 10000 ) ); /* FIXME: remove magic constant */ - slot_ctx->slot_bank.timestamp_votes.votes_root = NULL; + ulong * capitalization_bm = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); + *capitalization_bm = capitalization; + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( slot_ctx->bank_mgr ); + uchar * clock_pool_mem = (uchar *)fd_ulong_align_up( (ulong)clock_timestamp_votes + sizeof(fd_clock_timestamp_votes_global_t), fd_clock_timestamp_vote_t_map_align() ); + fd_clock_timestamp_vote_t_mapnode_t * clock_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new(clock_pool_mem, 15000UL ) ); + clock_timestamp_votes->votes_pool_offset = (ulong)fd_clock_timestamp_vote_t_map_leave( clock_pool) - (ulong)clock_timestamp_votes; + clock_timestamp_votes->votes_root_offset = 0UL; + fd_bank_mgr_clock_timestamp_votes_save( slot_ctx->bank_mgr ); } static int fd_runtime_process_genesis_block( fd_exec_slot_ctx_t * slot_ctx, fd_capture_ctx_t * capture_ctx, fd_spad_t * runtime_spad ) { - ulong hashcnt_per_slot = slot_ctx->epoch_ctx->epoch_bank.hashes_per_tick * slot_ctx->epoch_ctx->epoch_bank.ticks_per_slot; + + fd_hash_t poh_old = *fd_bank_mgr_poh_query( slot_ctx->bank_mgr ); + + fd_hash_t * poh = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); + ulong hashcnt_per_slot = *(fd_bank_mgr_hashes_per_tick_query( slot_ctx->bank_mgr )) * *(fd_bank_mgr_ticks_per_slot_query( slot_ctx->bank_mgr )); while( hashcnt_per_slot-- ) { - fd_sha256_hash( slot_ctx->slot_bank.poh.uc, sizeof(fd_hash_t), slot_ctx->slot_bank.poh.uc ); + fd_sha256_hash( poh->hash, sizeof(fd_hash_t), &poh_old ); } + fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); + + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); + *execution_fees = 0UL; + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( slot_ctx->bank_mgr ); + *priority_fees = 0UL; + fd_bank_mgr_priority_fees_save( slot_ctx->bank_mgr ); + + ulong * signature_cnt = fd_bank_mgr_signature_cnt_modify( slot_ctx->bank_mgr ); + *signature_cnt = 0UL; + fd_bank_mgr_signature_cnt_save( slot_ctx->bank_mgr ); - slot_ctx->slot_bank.collected_execution_fees = 0UL; - slot_ctx->slot_bank.collected_priority_fees = 0UL; - slot_ctx->slot_bank.collected_rent = 0UL; - slot_ctx->signature_cnt = 0UL; slot_ctx->txn_count = 0UL; - slot_ctx->nonvote_txn_count = 0UL; slot_ctx->failed_txn_count = 0UL; slot_ctx->nonvote_failed_txn_count = 0UL; slot_ctx->total_compute_units_used = 0UL; @@ -3609,7 +3760,7 @@ fd_runtime_process_genesis_block( fd_exec_slot_ctx_t * slot_ctx, fd_runtime_update_leaders( slot_ctx, 0, runtime_spad ); - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_partitioned_rent_collection ) ) { + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, disable_partitioned_rent_collection ) ) { fd_funk_t * funk = slot_ctx->funk; fd_funk_txn_t * txn = slot_ctx->funk_txn; @@ -3633,7 +3784,7 @@ fd_runtime_process_genesis_block( fd_exec_slot_ctx_t * slot_ctx, int result = fd_update_hash_bank_tpool( slot_ctx, capture_ctx, &slot_ctx->slot_bank.banks_hash, - slot_ctx->signature_cnt, + 0UL, NULL, runtime_spad ); if( FD_UNLIKELY( result != FD_EXECUTOR_INSTR_SUCCESS ) ) { @@ -3658,6 +3809,11 @@ fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx, return; } + slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( slot_ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); + if( FD_UNLIKELY( !slot_ctx->bank_mgr ) ) { + FD_LOG_CRIT(( "failed to join bank mgr" )); + } + struct stat sbuf; if( FD_UNLIKELY( stat( genesis_filepath, &sbuf) < 0 ) ) { FD_LOG_ERR(( "cannot open %s : %s", genesis_filepath, strerror(errno) )); @@ -3700,7 +3856,6 @@ fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx, fd_sha256_hash( buf, sz, genesis_hash.uc ); fd_memcpy( epoch_bank->genesis_hash.uc, genesis_hash.uc, sizeof(fd_hash_t) ); - epoch_bank->cluster_type = genesis_block->cluster_type; if( !is_snapshot ) { fd_runtime_init_bank_from_genesis( slot_ctx, @@ -3748,7 +3903,7 @@ fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx, fd_features_restore( slot_ctx, runtime_spad ); - slot_ctx->slot_bank.slot = 0UL; + slot_ctx->slot = 0UL; int err = fd_runtime_process_genesis_block( slot_ctx, capture_ctx, runtime_spad ); if( FD_UNLIKELY( err ) ) { @@ -3756,14 +3911,24 @@ fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx, } } - slot_ctx->slot_bank.stake_account_keys.account_keys_root = NULL; - uchar * pool_mem = fd_spad_alloc( runtime_spad, fd_account_keys_pair_t_map_align(), fd_account_keys_pair_t_map_footprint( 100000UL ) ); - slot_ctx->slot_bank.stake_account_keys.account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); - slot_ctx->slot_bank.vote_account_keys.account_keys_root = NULL; - pool_mem = fd_spad_alloc( runtime_spad, fd_account_keys_pair_t_map_align(), fd_account_keys_pair_t_map_footprint( 100000UL ) ); - slot_ctx->slot_bank.vote_account_keys.account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( slot_ctx->bank_mgr ); + uchar * pool_mem = (uchar *)fd_ulong_align_up( (ulong)stake_account_keys + sizeof(fd_account_keys_global_t), fd_account_keys_pair_t_map_align() ); + fd_account_keys_pair_t_mapnode_t * stake_account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); + fd_account_keys_pair_t_mapnode_t * stake_account_keys_root = NULL; + fd_account_keys_account_keys_pool_update( stake_account_keys, stake_account_keys_pool ); + fd_account_keys_account_keys_root_update( stake_account_keys, stake_account_keys_root ); + fd_bank_mgr_stake_account_keys_save( slot_ctx->bank_mgr ); + + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( slot_ctx->bank_mgr ); + pool_mem = (uchar *)fd_ulong_align_up( (ulong)vote_account_keys + sizeof(fd_account_keys_global_t), fd_account_keys_pair_t_map_align() ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = NULL; + + fd_account_keys_account_keys_pool_update( vote_account_keys, vote_account_keys_pool ); + fd_account_keys_account_keys_root_update( vote_account_keys, vote_account_keys_root ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); } /******************************************************************************/ @@ -3924,17 +4089,22 @@ fd_runtime_block_verify_tpool( fd_exec_slot_ctx_t * slot_ctx, poh_verification_info_cnt * sizeof(fd_poh_verification_info_t) ); fd_runtime_block_verify_info_collect( block_info, &tmp_in_poh_hash, poh_verification_info ); + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + ulong * tick_height = fd_bank_mgr_tick_height_query( bank_mgr ); + ulong * max_tick_height = fd_bank_mgr_max_tick_height_query( bank_mgr ); + uchar * block_data = fd_spad_alloc( runtime_spad, 128UL, FD_SHRED_DATA_PAYLOAD_MAX_PER_SLOT ); ulong tick_res = fd_runtime_block_verify_ticks( slot_ctx->blockstore, - slot_ctx->slot_bank.slot, + slot_ctx->slot, block_data, FD_SHRED_DATA_PAYLOAD_MAX_PER_SLOT, - slot_ctx->slot_bank.tick_height, - slot_ctx->slot_bank.max_tick_height, - slot_ctx->epoch_ctx->epoch_bank.hashes_per_tick + *tick_height, + *max_tick_height, + *(fd_bank_mgr_hashes_per_tick_query( bank_mgr )) ); if( FD_UNLIKELY( tick_res != FD_BLOCK_OK ) ) { - FD_LOG_WARNING(( "failed to verify ticks res %lu slot %lu", tick_res, slot_ctx->slot_bank.slot )); + FD_LOG_WARNING(( "failed to verify ticks res %lu slot %lu", tick_res, slot_ctx->slot )); return FD_RUNTIME_EXECUTE_GENERIC_ERR; } @@ -3966,7 +4136,7 @@ fd_runtime_publish_old_txns( fd_exec_slot_ctx_t * slot_ctx, fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); if( capture_ctx != NULL ) { - fd_runtime_checkpt( capture_ctx, slot_ctx, slot_ctx->slot_bank.slot ); + fd_runtime_checkpt( capture_ctx, slot_ctx, slot_ctx->slot ); } int do_eah = 0; @@ -4008,11 +4178,14 @@ fd_runtime_publish_old_txns( fd_exec_slot_ctx_t * slot_ctx, } } - if( txn->xid.ul[0] >= epoch_bank->eah_start_slot ) { - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, accounts_lt_hash ) ) { + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_query( slot_ctx->bank_mgr ); + if( txn->xid.ul[0] >= *eah_start_slot ) { + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, accounts_lt_hash ) ) { do_eah = 1; } - epoch_bank->eah_start_slot = ULONG_MAX; + eah_start_slot = fd_bank_mgr_eah_start_slot_modify( slot_ctx->bank_mgr ); + *eah_start_slot = ULONG_MAX; + fd_bank_mgr_eah_start_slot_save( slot_ctx->bank_mgr ); } break; @@ -4028,12 +4201,15 @@ fd_runtime_publish_old_txns( fd_exec_slot_ctx_t * slot_ctx, .para_arg_1 = tpool }; + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_query( slot_ctx->bank_mgr ); + fd_accounts_hash( slot_ctx->funk, - &slot_ctx->slot_bank, - &slot_ctx->slot_bank.epoch_account_hash, + slot_ctx->slot, + epoch_account_hash, runtime_spad, &slot_ctx->epoch_ctx->features, - &exec_para_ctx, NULL ); + &exec_para_ctx, + NULL ); } return 0; @@ -4048,8 +4224,8 @@ fd_runtime_block_execute_tpool( fd_exec_slot_ctx_t * slot_ctx, ulong exec_spad_cnt, fd_spad_t * runtime_spad ) { - if ( capture_ctx != NULL && capture_ctx->capture && slot_ctx->slot_bank.slot>=capture_ctx->solcap_start_slot ) { - fd_solcap_writer_set_slot( capture_ctx->capture, slot_ctx->slot_bank.slot ); + if ( capture_ctx != NULL && capture_ctx->capture && slot_ctx->slot>=capture_ctx->solcap_start_slot ) { + fd_solcap_writer_set_slot( capture_ctx->capture, slot_ctx->slot ); } long block_execute_time = -fd_log_wallclock(); @@ -4066,7 +4242,7 @@ fd_runtime_block_execute_tpool( fd_exec_slot_ctx_t * slot_ctx, /* Initialize the cost tracker when the feature is active */ fd_cost_tracker_t * cost_tracker = fd_spad_alloc( runtime_spad, FD_COST_TRACKER_ALIGN, sizeof(fd_cost_tracker_t) ); - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, apply_cost_tracker_during_replay ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, apply_cost_tracker_during_replay ) ) { fd_cost_tracker_init( cost_tracker, slot_ctx, runtime_spad ); } @@ -4079,6 +4255,8 @@ fd_runtime_block_execute_tpool( fd_exec_slot_ctx_t * slot_ctx, ulong mblock_txn_cnt = txn_cnt; to_exec_idx += txn_cnt; + /* UPDATE */ + if( !mblock_txn_cnt ) continue; res = fd_runtime_process_txns_in_microblock_stream( slot_ctx, @@ -4113,16 +4291,14 @@ fd_runtime_block_execute_tpool( fd_exec_slot_ctx_t * slot_ctx, return res; } - slot_ctx->slot_bank.transaction_count += txn_cnt; - block_finalize_time += fd_log_wallclock(); double block_finalize_time_ms = (double)block_finalize_time * 1e-6; - FD_LOG_INFO(( "finalized block successfully - slot: %lu, elapsed: %6.6f ms", slot_ctx->slot_bank.slot, block_finalize_time_ms )); + FD_LOG_INFO(( "finalized block successfully - slot: %lu, elapsed: %6.6f ms", slot_ctx->slot, block_finalize_time_ms )); block_execute_time += fd_log_wallclock(); double block_execute_time_ms = (double)block_execute_time * 1e-6; - FD_LOG_INFO(( "executed block successfully - slot: %lu, elapsed: %6.6f ms", slot_ctx->slot_bank.slot, block_execute_time_ms )); + FD_LOG_INFO(( "executed block successfully - slot: %lu, elapsed: %6.6f ms", slot_ctx->slot, block_execute_time_ms )); return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -4136,16 +4312,20 @@ fd_runtime_block_pre_execute_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, int * is_epoch_boundary ) { /* Update block height. */ - slot_ctx->slot_bank.block_height += 1UL; + ulong * block_height = fd_bank_mgr_block_height_modify( slot_ctx->bank_mgr ); + *block_height += 1UL; + fd_bank_mgr_block_height_save( slot_ctx->bank_mgr ); - if( slot_ctx->slot_bank.slot != 0UL ) { + if( slot_ctx->slot != 0UL ) { ulong slot_idx; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); ulong prev_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.prev_slot, &slot_idx ); - ulong new_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot, &slot_idx ); + ulong new_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot, &slot_idx ); if( FD_UNLIKELY( slot_idx==1UL && new_epoch==0UL ) ) { /* The block after genesis has a height of 1. */ - slot_ctx->slot_bank.block_height = 1UL; + ulong * block_height = fd_bank_mgr_block_height_modify( slot_ctx->bank_mgr ); + *block_height = 1UL; + fd_bank_mgr_block_height_save( slot_ctx->bank_mgr ); } if( FD_UNLIKELY( prev_epochslot_bank.slot != 0UL && ( - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { + if( slot_ctx->slot != 0UL && ( + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { fd_distribute_partitioned_epoch_rewards( slot_ctx, tpool, exec_spads, @@ -4176,6 +4356,7 @@ fd_runtime_block_pre_execute_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, int fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, + ulong slot, fd_block_t * block, fd_capture_ctx_t * capture_ctx, fd_tpool_t * tpool, @@ -4194,7 +4375,6 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, } fd_funk_t * funk = slot_ctx->funk; - ulong slot = slot_ctx->slot_bank.slot; long block_eval_time = -fd_log_wallclock(); fd_runtime_block_info_t block_info; @@ -4203,13 +4383,20 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, /* Start a new funk txn. */ - fd_funk_txn_xid_t xid = { .ul = { slot_ctx->slot_bank.slot, slot_ctx->slot_bank.slot } }; + fd_funk_txn_xid_t xid = { .ul = { slot, slot } }; fd_funk_txn_start_write( funk ); slot_ctx->funk_txn = fd_funk_txn_prepare( funk, slot_ctx->funk_txn, &xid, 1 ); fd_funk_txn_end_write( funk ); + slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( &slot_ctx->bank_mgr_mem ), funk, slot_ctx->funk_txn ); + + ulong * slot_ptr = fd_bank_mgr_slot_modify( slot_ctx->bank_mgr ); + *slot_ptr = slot; + fd_bank_mgr_slot_save( slot_ctx->bank_mgr ); + slot_ctx->slot = slot; + /* Capturing block-agnostic state in preparation for the epoch boundary */ - uchar dump_block = capture_ctx && slot_ctx->slot_bank.slot >= capture_ctx->dump_proto_start_slot && capture_ctx->dump_block_to_pb; + uchar dump_block = capture_ctx && slot >= capture_ctx->dump_proto_start_slot && capture_ctx->dump_block_to_pb; fd_exec_test_block_context_t * block_ctx = NULL; if( FD_UNLIKELY( dump_block ) ) { /* TODO: This probably should get allocated from a separate spad for the capture ctx */ @@ -4238,9 +4425,14 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, } *txn_cnt = block_info.txn_cnt; - if( FD_UNLIKELY( (ret = fd_runtime_block_verify_tpool( slot_ctx, &block_info, &slot_ctx->slot_bank.poh, &slot_ctx->slot_bank.poh, tpool, runtime_spad )) != FD_RUNTIME_EXECUTE_SUCCESS ) ) { + fd_hash_t poh_out = {0}; + fd_hash_t poh_in = *fd_bank_mgr_poh_query( slot_ctx->bank_mgr ); + if( FD_UNLIKELY( (ret = fd_runtime_block_verify_tpool( slot_ctx, &block_info, &poh_in, &poh_out, tpool, runtime_spad )) != FD_RUNTIME_EXECUTE_SUCCESS ) ) { break; } + fd_hash_t * poh = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); + fd_memcpy( poh->hash, poh_out.hash, sizeof(fd_hash_t) ); + fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); /* Dump the remainder of the block after preparation, POH verification, etc */ if( FD_UNLIKELY( dump_block ) ) { @@ -4251,6 +4443,8 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, break; } + poh = fd_bank_mgr_poh_query( slot_ctx->bank_mgr ); + } FD_SPAD_FRAME_END; } while( 0 ); @@ -4259,7 +4453,7 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, if( FD_UNLIKELY( FD_RUNTIME_EXECUTE_SUCCESS != ret ) ) { FD_LOG_WARNING(( "execution failure, code %d", ret )); /* Skip over slot next time */ - slot_ctx->slot_bank.slot = slot+1UL; + // slot_ctx->slot = slot+1UL; return ret; } @@ -4267,21 +4461,23 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, double block_eval_time_ms = (double)block_eval_time * 1e-6; double tps = (double) block_info.txn_cnt / ((double)block_eval_time * 1e-9); FD_LOG_INFO(( "evaluated block successfully - slot: %lu, elapsed: %6.6f ms, signatures: %lu, txns: %lu, tps: %6.6f, bank_hash: %s, leader: %s", - slot_ctx->slot_bank.slot, + slot, block_eval_time_ms, block_info.signature_cnt, block_info.txn_cnt, tps, FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ), - FD_BASE58_ENC_32_ALLOCA( fd_epoch_leaders_get( fd_exec_epoch_ctx_leaders( slot_ctx->epoch_ctx ), slot_ctx->slot_bank.slot ) ) )); + FD_BASE58_ENC_32_ALLOCA( fd_epoch_leaders_get( fd_exec_epoch_ctx_leaders( slot_ctx->epoch_ctx ), slot ) ) )); - slot_ctx->slot_bank.transaction_count += block_info.txn_cnt; + ulong * transaction_count = fd_bank_mgr_transaction_count_modify( slot_ctx->bank_mgr ); + *transaction_count += block_info.txn_cnt; + fd_bank_mgr_transaction_count_save( slot_ctx->bank_mgr ); fd_runtime_save_slot_bank( slot_ctx ); slot_ctx->slot_bank.prev_slot = slot; // FIXME: this shouldn't be doing this, it doesn't work with forking. punting changing it though - slot_ctx->slot_bank.slot = slot+1UL; + // slot_ctx->slot = slot+1UL; return 0; } diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 57688751ae..c06b89308c 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -630,6 +630,7 @@ fd_raw_block_txn_iter_ele( fd_raw_block_txn_iter_t iter, fd_txn_p_t * out_txn ); int fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, + ulong slot, fd_block_t * block, fd_capture_ctx_t * capture_ctx, fd_tpool_t * tpool, diff --git a/src/flamenco/runtime/fd_runtime_init.c b/src/flamenco/runtime/fd_runtime_init.c index e757bc4a89..dad02bf112 100644 --- a/src/flamenco/runtime/fd_runtime_init.c +++ b/src/flamenco/runtime/fd_runtime_init.c @@ -5,6 +5,7 @@ #include "context/fd_exec_epoch_ctx.h" #include "context/fd_exec_slot_ctx.h" #include "../../ballet/lthash/fd_lthash.h" +#include "fd_bank_mgr.h" #include "fd_system_ids.h" /* This file must not depend on fd_executor.h */ @@ -49,7 +50,7 @@ fd_runtime_save_epoch_bank( fd_exec_slot_ctx_t * slot_ctx ) { fd_funk_rec_publish( funk, prepare ); - FD_LOG_DEBUG(( "epoch frozen, slot=%lu bank_hash=%s poh_hash=%s", slot_ctx->slot_bank.slot, FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ), FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.poh.hash ) )); + FD_LOG_DEBUG(( "epoch frozen, slot=%lu bank_hash=%s", slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ) )); return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -98,10 +99,9 @@ int fd_runtime_save_slot_bank( fd_exec_slot_ctx_t * slot_ctx ) { fd_funk_rec_publish( funk, prepare ); - FD_LOG_DEBUG(( "slot frozen, slot=%lu bank_hash=%s poh_hash=%s", - slot_ctx->slot_bank.slot, - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ), - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.poh.hash ) )); + FD_LOG_DEBUG(( "slot frozen, slot=%lu bank_hash=%s", + slot_ctx->slot, + FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ) )); return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -192,15 +192,19 @@ fd_runtime_recover_banks( fd_exec_slot_ctx_t * slot_ctx, continue; } - FD_LOG_NOTICE(( "recovered slot_bank for slot=%ld banks_hash=%s poh_hash %s lthash %s", - (long)slot_ctx->slot_bank.slot, + FD_LOG_NOTICE(( "recovered slot_bank for slot=%ld banks_hash=%s lthash=%s", + (long)slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ), - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.poh.hash ), FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ) )); - slot_ctx->slot_bank.collected_execution_fees = 0; - slot_ctx->slot_bank.collected_priority_fees = 0; - slot_ctx->slot_bank.collected_rent = 0; + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); + *execution_fees = 0; + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( slot_ctx->bank_mgr ); + *priority_fees = 0; + fd_bank_mgr_priority_fees_save( slot_ctx->bank_mgr ); + slot_ctx->txn_count = 0; slot_ctx->nonvote_txn_count = 0; slot_ctx->failed_txn_count = 0; diff --git a/src/flamenco/runtime/fd_runtime_public.h b/src/flamenco/runtime/fd_runtime_public.h index a614bc8b85..478170b2bb 100644 --- a/src/flamenco/runtime/fd_runtime_public.h +++ b/src/flamenco/runtime/fd_runtime_public.h @@ -200,10 +200,8 @@ fd_writer_fseq_is_not_joined( ulong fseq ) { bincode serialized/deserialized. */ struct fd_runtime_public_epoch_msg { fd_features_t features; - ulong total_epoch_stake; fd_epoch_schedule_t epoch_schedule; fd_rent_t rent; - double slots_per_year; ulong stakes_encoded_gaddr; ulong stakes_encoded_sz; ulong bank_hash_cmp_gaddr; @@ -211,13 +209,9 @@ struct fd_runtime_public_epoch_msg { typedef struct fd_runtime_public_epoch_msg fd_runtime_public_epoch_msg_t; struct fd_runtime_public_slot_msg { - ulong slot; - ulong prev_lamports_per_signature; - fd_fee_rate_governor_t fee_rate_governor; - ulong sysvar_cache_gaddr; - ulong block_hash_queue_encoded_gaddr; - ulong block_hash_queue_encoded_sz; - int enable_exec_recording; + ulong slot; + ulong sysvar_cache_gaddr; + int enable_exec_recording; }; typedef struct fd_runtime_public_slot_msg fd_runtime_public_slot_msg_t; diff --git a/src/flamenco/runtime/fd_txn_account_private.h b/src/flamenco/runtime/fd_txn_account_private.h index 2ffa930f1c..c5981ad05f 100644 --- a/src/flamenco/runtime/fd_txn_account_private.h +++ b/src/flamenco/runtime/fd_txn_account_private.h @@ -16,6 +16,8 @@ struct __attribute__((aligned(8UL))) fd_txn_account_private_state { ulong meta_gaddr; ulong data_gaddr; + int is_verified; + /* Provide borrowing semantics. Used for single-threaded logic only, thus not comparable to a data synchronization lock. */ diff --git a/src/flamenco/runtime/program/fd_bpf_program_util.c b/src/flamenco/runtime/program/fd_bpf_program_util.c index 5bc7827d70..2c90e5c52a 100644 --- a/src/flamenco/runtime/program/fd_bpf_program_util.c +++ b/src/flamenco/runtime/program/fd_bpf_program_util.c @@ -197,7 +197,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx, uint min_sbpf_version, max_sbpf_version; fd_bpf_get_sbpf_versions( &min_sbpf_version, &max_sbpf_version, - slot_ctx->slot_bank.slot, + slot_ctx->slot, &slot_ctx->epoch_ctx->features ); if( fd_sbpf_elf_peek( &elf_info, program_data, program_data_len, /* deploy checks */ 0, min_sbpf_version, max_sbpf_version ) == NULL ) { FD_LOG_DEBUG(( "fd_sbpf_elf_peek() failed: %s", fd_sbpf_strerror() )); @@ -241,7 +241,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx, } fd_vm_syscall_register_slot( syscalls, - slot_ctx->slot_bank.slot, + slot_ctx->slot, &slot_ctx->epoch_ctx->features, 0 ); @@ -263,7 +263,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx, } fd_exec_instr_ctx_t dummy_instr_ctx = {0}; fd_exec_txn_ctx_t dummy_txn_ctx = {0}; - dummy_txn_ctx.slot = slot_ctx->slot_bank.slot; + dummy_txn_ctx.slot = slot_ctx->slot; dummy_txn_ctx.features = slot_ctx->epoch_ctx->features; dummy_instr_ctx.txn_ctx = &dummy_txn_ctx; vm = fd_vm_init( vm, @@ -286,7 +286,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx, 0U, NULL, 0, - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, bpf_account_data_direct_mapping ) ); + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, bpf_account_data_direct_mapping ) ); if( FD_UNLIKELY( !vm ) ) { FD_LOG_ERR(( "fd_vm_init() failed" )); @@ -304,7 +304,7 @@ fd_bpf_create_bpf_program_cache_entry( fd_exec_slot_ctx_t * slot_ctx, validated_prog->calldests = fd_sbpf_calldests_join( validated_prog->calldests_shmem ); validated_prog->entry_pc = prog->entry_pc; - validated_prog->last_updated_slot = slot_ctx->slot_bank.slot; + validated_prog->last_updated_slot = slot_ctx->slot; validated_prog->text_off = prog->text_off; validated_prog->text_cnt = prog->text_cnt; validated_prog->text_sz = prog->text_sz; diff --git a/src/flamenco/runtime/program/fd_builtin_programs.c b/src/flamenco/runtime/program/fd_builtin_programs.c index 5ef4bf7c77..0f9db5da6f 100644 --- a/src/flamenco/runtime/program/fd_builtin_programs.c +++ b/src/flamenco/runtime/program/fd_builtin_programs.c @@ -3,6 +3,7 @@ #include "../fd_acc_mgr.h" #include "../fd_system_ids.h" #include "../fd_system_ids_pp.h" +#include "../fd_bank_mgr.h" #define BUILTIN_PROGRAM(program_id, name, feature_offset, migration_config) \ { \ @@ -150,7 +151,11 @@ fd_write_builtin_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_mutable_fini( rec, funk, txn ); - slot_ctx->slot_bank.capitalization++; + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, funk, txn ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + (*capitalization)++; + fd_bank_mgr_capitalization_save( bank_mgr ); // err = fd_acc_mgr_commit( acc_mgr, rec, slot_ctx ); FD_TEST( !err ); @@ -160,10 +165,11 @@ fd_write_builtin_account( fd_exec_slot_ctx_t * slot_ctx, /* TODO: move this somewhere more appropiate */ static void write_inline_spl_native_mint_program_account( fd_exec_slot_ctx_t * slot_ctx ) { - // really?! really!? - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - if( epoch_bank->cluster_type != 3) + + if( true ) { + /* FIXME: stupid cluster version hackjob was here. */ return; + } fd_funk_t * funk = slot_ctx->funk; fd_funk_txn_t * txn = slot_ctx->funk_txn; @@ -194,9 +200,9 @@ void fd_builtin_programs_init( fd_exec_slot_ctx_t * slot_ctx ) { // https://github.com/anza-xyz/agave/blob/v2.0.1/runtime/src/bank/builtins/mod.rs#L33 fd_builtin_program_t const * builtins = fd_builtins(); for( ulong i=0UL; islot_bank.slot, slot_ctx->epoch_ctx->features, builtins[i].core_bpf_migration_config->enable_feature_offset ) ) { + if( builtins[i].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET( slot_ctx->slot, slot_ctx->epoch_ctx->features, builtins[i].core_bpf_migration_config->enable_feature_offset ) ) { continue; - } else if( builtins[i].enable_feature_offset!=NO_ENABLE_FEATURE_ID && !FD_FEATURE_ACTIVE_OFFSET( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, builtins[i].enable_feature_offset ) ) { + } else if( builtins[i].enable_feature_offset!=NO_ENABLE_FEATURE_ID && !FD_FEATURE_ACTIVE_OFFSET( slot_ctx->slot, slot_ctx->epoch_ctx->features, builtins[i].enable_feature_offset ) ) { continue; } else { fd_write_builtin_account( slot_ctx, *builtins[i].pubkey, builtins[i].data, strlen(builtins[i].data) ); @@ -204,25 +210,29 @@ void fd_builtin_programs_init( fd_exec_slot_ctx_t * slot_ctx ) { } //TODO: remove when no longer necessary - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, zk_token_sdk_enabled ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, zk_token_sdk_enabled ) ) { fd_write_builtin_account( slot_ctx, fd_solana_zk_token_proof_program_id, "zk_token_proof_program", 22UL ); } - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, zk_elgamal_proof_program_enabled ) ) { + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, zk_elgamal_proof_program_enabled ) ) { fd_write_builtin_account( slot_ctx, fd_solana_zk_elgamal_proof_program_id, "zk_elgamal_proof_program", 24UL ); } + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_cluster_version_t * cluster_version = fd_bank_mgr_cluster_version_query( bank_mgr ); + /* Precompiles have empty account data */ - if( slot_ctx->epoch_ctx->epoch_bank.cluster_version[0]<2 ) { + if( cluster_version &&cluster_version->major<2 ) { char data[1] = {1}; fd_write_builtin_account( slot_ctx, fd_solana_keccak_secp_256k_program_id, data, 1 ); fd_write_builtin_account( slot_ctx, fd_solana_ed25519_sig_verify_program_id, data, 1 ); - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, enable_secp256r1_precompile ) ) + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, enable_secp256r1_precompile ) ) fd_write_builtin_account( slot_ctx, fd_solana_secp256r1_program_id, data, 1 ); } else { fd_write_builtin_account( slot_ctx, fd_solana_keccak_secp_256k_program_id, "", 0 ); fd_write_builtin_account( slot_ctx, fd_solana_ed25519_sig_verify_program_id, "", 0 ); - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, enable_secp256r1_precompile ) ) + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, enable_secp256r1_precompile ) ) fd_write_builtin_account( slot_ctx, fd_solana_secp256r1_program_id, "", 0 ); } diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index fdb5b79644..9b434f572a 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -6,7 +6,7 @@ #include "../fd_executor.h" #include "../fd_pubkey_utils.h" #include "../fd_system_ids.h" - +#include "../fd_bank_mgr.h" #include "fd_stake_program.h" #include "fd_vote_program.h" #include "../sysvar/fd_sysvar_epoch_schedule.h" @@ -3242,17 +3242,30 @@ fd_stake_activating_and_deactivating( fd_delegation_t const * self, /* Removes stake delegation from epoch stakes and updates vote account */ static void fd_stakes_remove_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * stake_account ) { + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( bank_mgr ); + fd_account_keys_pair_t_mapnode_t * account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); + fd_account_keys_pair_t_mapnode_t * account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); + fd_account_keys_pair_t_mapnode_t key; fd_memcpy( key.elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) ); - if( FD_UNLIKELY( slot_ctx->slot_bank.stake_account_keys.account_keys_pool==NULL ) ) { + if( FD_UNLIKELY( account_keys_pool==NULL ) ) { + /* TODO: Should this be a LOG_ERR/LOG_CRIT? */ FD_LOG_DEBUG(("Stake accounts pool does not exist")); return; } - fd_account_keys_pair_t_mapnode_t * entry = fd_account_keys_pair_t_map_find( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, slot_ctx->slot_bank.stake_account_keys.account_keys_root, &key ); + fd_account_keys_pair_t_mapnode_t * entry = fd_account_keys_pair_t_map_find( account_keys_pool, account_keys_root, &key ); if( FD_UNLIKELY( entry ) ) { - fd_account_keys_pair_t_map_remove( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, &slot_ctx->slot_bank.stake_account_keys.account_keys_root, entry ); + fd_account_keys_pair_t_map_remove( account_keys_pool, &account_keys_root, entry ); // TODO: do we need a release here? } + + fd_account_keys_account_keys_pool_update( stake_account_keys, account_keys_pool ); + fd_account_keys_account_keys_root_update( stake_account_keys, account_keys_root ); + fd_bank_mgr_stake_account_keys_save( bank_mgr ); } /* Updates stake delegation in epoch stakes */ @@ -3270,29 +3283,49 @@ fd_stakes_upsert_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account return; } + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( bank_mgr ); + + fd_account_keys_pair_t_mapnode_t * account_keys_pool = NULL; + fd_account_keys_pair_t_mapnode_t * account_keys_root = NULL; + if( stake_account_keys->account_keys_pool_offset==0 ) { + uchar * pool_mem = (uchar *)fd_ulong_align_up( (ulong)stake_account_keys + sizeof(fd_account_keys_global_t), fd_account_keys_pair_t_map_align() ); + account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); + account_keys_root = NULL; + } else { + account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); + account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); + } + fd_delegation_pair_t_mapnode_t * entry = fd_delegation_pair_t_map_find( stakes->stake_delegations_pool, stakes->stake_delegations_root, &key); if( FD_UNLIKELY( !entry ) ) { fd_account_keys_pair_t_mapnode_t key; fd_memcpy( key.elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) ); - if( slot_ctx->slot_bank.stake_account_keys.account_keys_pool==NULL) { + if( account_keys_pool==NULL) { FD_LOG_DEBUG(("Stake accounts pool does not exist")); return; } - fd_account_keys_pair_t_mapnode_t * stake_entry = fd_account_keys_pair_t_map_find( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, slot_ctx->slot_bank.stake_account_keys.account_keys_root, &key ); + fd_account_keys_pair_t_mapnode_t * stake_entry = fd_account_keys_pair_t_map_find( account_keys_pool, account_keys_root, &key ); if( stake_entry ) { stake_entry->elem.exists = 1; } else { - fd_account_keys_pair_t_mapnode_t * new_node = fd_account_keys_pair_t_map_acquire( slot_ctx->slot_bank.stake_account_keys.account_keys_pool ); - ulong size = fd_account_keys_pair_t_map_size( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, slot_ctx->slot_bank.stake_account_keys.account_keys_root ); - FD_LOG_DEBUG(("Curr stake account size %lu %p", size, (void *)slot_ctx->slot_bank.stake_account_keys.account_keys_pool)); + fd_account_keys_pair_t_mapnode_t * new_node = fd_account_keys_pair_t_map_acquire( account_keys_pool ); + ulong size = fd_account_keys_pair_t_map_size( account_keys_pool, account_keys_root ); + FD_LOG_DEBUG(("Curr stake account size %lu %p", size, (void *)account_keys_pool)); if( new_node==NULL ) { FD_LOG_ERR(("Stake accounts keys map full %lu", size)); } new_node->elem.exists = 1; fd_memcpy( new_node->elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) ); - fd_account_keys_pair_t_map_insert( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, &slot_ctx->slot_bank.stake_account_keys.account_keys_root, new_node ); + fd_account_keys_pair_t_map_insert( account_keys_pool, &account_keys_root, new_node ); } } + + fd_account_keys_account_keys_pool_update( stake_account_keys, account_keys_pool ); + fd_account_keys_account_keys_root_update( stake_account_keys, account_keys_root ); + + fd_bank_mgr_stake_account_keys_save( bank_mgr ); } void fd_store_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * stake_account ) { diff --git a/src/flamenco/runtime/program/fd_system_program_nonce.c b/src/flamenco/runtime/program/fd_system_program_nonce.c index 7794575e29..83de0f7e32 100644 --- a/src/flamenco/runtime/program/fd_system_program_nonce.c +++ b/src/flamenco/runtime/program/fd_system_program_nonce.c @@ -6,6 +6,7 @@ #include "../context/fd_exec_txn_ctx.h" #include "../sysvar/fd_sysvar_rent.h" #include "../fd_executor.h" +#include "../fd_bank_mgr.h" static int require_acct( fd_exec_instr_ctx_t * ctx, @@ -72,7 +73,7 @@ most_recent_block_hash( fd_exec_instr_ctx_t * ctx, /* The environment config blockhash comes from `bank.last_blockhash_and_lamports_per_signature()`, which takes the top element from the blockhash queue. https://github.com/anza-xyz/agave/blob/v2.1.6/programs/system/src/system_instruction.rs#L47 */ - fd_hash_t const * last_hash = ctx->txn_ctx->block_hash_queue.last_hash; + fd_hash_t const * last_hash = fd_block_hash_queue_last_hash_join( ctx->txn_ctx->block_hash_queue ); if( FD_UNLIKELY( last_hash==NULL ) ) { // Agave panics if this blockhash was never set at the start of the txn batch ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_NONCE_NO_RECENT_BLOCKHASHES; @@ -215,7 +216,7 @@ fd_system_program_advance_nonce_account( fd_exec_instr_ctx_t * ctx, .authority = data->authority, .durable_nonce = next_durable_nonce, .fee_calculator = { - .lamports_per_signature = ctx->txn_ctx->prev_lamports_per_signature + .lamports_per_signature = *(fd_bank_mgr_prev_lamports_per_signature_query( ctx->txn_ctx->bank_mgr )) } } } } } @@ -578,7 +579,7 @@ fd_system_program_initialize_nonce_account( fd_exec_instr_ctx_t * ctx, .authority = *authorized, .durable_nonce = durable_nonce, .fee_calculator = { - .lamports_per_signature = ctx->txn_ctx->prev_lamports_per_signature + .lamports_per_signature = *(fd_bank_mgr_prev_lamports_per_signature_query( ctx->txn_ctx->bank_mgr )) } } } } } @@ -875,8 +876,8 @@ fd_system_program_exec_upgrade_nonce_account( fd_exec_instr_ctx_t * ctx ) { Note: We check 151 and not 150 due to a known bug in agave. */ int fd_check_transaction_age( fd_exec_txn_ctx_t * txn_ctx ) { - fd_block_hash_queue_t hash_queue = txn_ctx->block_hash_queue; - fd_hash_t * last_blockhash = hash_queue.last_hash; + fd_block_hash_queue_global_t const * hash_queue = txn_ctx->block_hash_queue; + fd_hash_t * last_blockhash = fd_block_hash_queue_last_hash_join( hash_queue ); /* check_transaction_age */ fd_hash_t next_durable_nonce = {0}; @@ -888,7 +889,7 @@ fd_check_transaction_age( fd_exec_txn_ctx_t * txn_ctx ) { /* get_hash_info_if_valid. Check 151 hashes from the block hash queue and its age to see if it is valid. */ - if( fd_executor_is_blockhash_valid_for_age( &hash_queue, recent_blockhash, FD_RECENT_BLOCKHASHES_MAX_ENTRIES ) ) { + if( fd_executor_is_blockhash_valid_for_age( hash_queue, recent_blockhash, FD_RECENT_BLOCKHASHES_MAX_ENTRIES ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -999,7 +1000,7 @@ fd_check_transaction_age( fd_exec_txn_ctx_t * txn_ctx ) { .authority = state->inner.current.inner.initialized.authority, .durable_nonce = next_durable_nonce, .fee_calculator = { - .lamports_per_signature = txn_ctx->prev_lamports_per_signature + .lamports_per_signature = *(fd_bank_mgr_prev_lamports_per_signature_query( txn_ctx->bank_mgr )) } } } } } diff --git a/src/flamenco/runtime/program/fd_vote_program.c b/src/flamenco/runtime/program/fd_vote_program.c index 68a36c6b39..0c68492bc8 100644 --- a/src/flamenco/runtime/program/fd_vote_program.c +++ b/src/flamenco/runtime/program/fd_vote_program.c @@ -5,7 +5,7 @@ #include "../fd_pubkey_utils.h" #include "../sysvar/fd_sysvar_epoch_schedule.h" #include "../sysvar/fd_sysvar_rent.h" - +#include "../fd_bank_mgr.h" #include #include #include @@ -2163,9 +2163,14 @@ fd_vote_record_timestamp_vote_with_slot( fd_exec_slot_ctx_t * slot_ctx, long timestamp, ulong slot ) { + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( bank_mgr ); + fd_clock_timestamp_vote_t_mapnode_t * pool = fd_clock_timestamp_votes_votes_pool_join( clock_timestamp_votes ); + fd_clock_timestamp_vote_t_mapnode_t * root = fd_clock_timestamp_votes_votes_root_join( clock_timestamp_votes ); + fd_rwlock_write( slot_ctx->vote_stake_lock ); - fd_clock_timestamp_vote_t_mapnode_t * root = slot_ctx->slot_bank.timestamp_votes.votes_root; - fd_clock_timestamp_vote_t_mapnode_t * pool = slot_ctx->slot_bank.timestamp_votes.votes_pool; if( FD_UNLIKELY( !pool ) ) { FD_LOG_ERR(( "Timestamp vote account pool not allocated" )); } @@ -2185,8 +2190,12 @@ fd_vote_record_timestamp_vote_with_slot( fd_exec_slot_ctx_t * slot_ctx, FD_TEST( node != NULL ); node->elem = timestamp_vote; fd_clock_timestamp_vote_t_map_insert( pool, &root, node ); - slot_ctx->slot_bank.timestamp_votes.votes_root = root; } + + fd_clock_timestamp_votes_votes_pool_update( clock_timestamp_votes, pool ); + fd_clock_timestamp_votes_votes_root_update( clock_timestamp_votes, root ); + fd_bank_mgr_clock_timestamp_votes_save( bank_mgr ); + fd_rwlock_unwrite( slot_ctx->vote_stake_lock ); } @@ -2911,10 +2920,19 @@ fd_vote_convert_to_current( fd_vote_state_versioned_t * self, static void remove_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_account ) { + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( bank_mgr ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); + fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); fd_vote_accounts_t * epoch_vote_accounts = &epoch_bank->stakes.vote_accounts; if( FD_UNLIKELY( epoch_vote_accounts->vote_accounts_pool==NULL ) ) { FD_LOG_DEBUG(("Vote accounts pool does not exist")); + fd_bank_mgr_vote_account_keys_save( bank_mgr ); return; } @@ -2925,24 +2943,36 @@ remove_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_acco fd_vote_accounts_pair_t_map_remove( epoch_vote_accounts->vote_accounts_pool, &epoch_vote_accounts->vote_accounts_root, vote_account_entry); } - if( FD_UNLIKELY( slot_ctx->slot_bank.vote_account_keys.account_keys_pool==NULL ) ) { + if( FD_UNLIKELY( vote_account_keys_pool==NULL ) ) { FD_LOG_DEBUG(("Vote accounts pool does not exist")); + fd_bank_mgr_vote_account_keys_save( bank_mgr ); return; } fd_account_keys_pair_t_mapnode_t account_key; fd_memcpy( account_key.elem.key.uc, vote_account->pubkey->uc, sizeof(fd_pubkey_t) ); - fd_account_keys_pair_t_mapnode_t * account_key_entry = fd_account_keys_pair_t_map_find( slot_ctx->slot_bank.vote_account_keys.account_keys_pool, slot_ctx->slot_bank.vote_account_keys.account_keys_root, &account_key ); + fd_account_keys_pair_t_mapnode_t * account_key_entry = fd_account_keys_pair_t_map_find( vote_account_keys_pool, vote_account_keys_root, &account_key ); if( account_key_entry ) { - fd_account_keys_pair_t_map_remove( slot_ctx->slot_bank.vote_account_keys.account_keys_pool, &slot_ctx->slot_bank.vote_account_keys.account_keys_root, account_key_entry ); + fd_account_keys_pair_t_map_remove( vote_account_keys_pool, &vote_account_keys_root, account_key_entry ); } + + fd_bank_mgr_vote_account_keys_save( bank_mgr ); } static void upsert_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_account ) { - if( FD_UNLIKELY( slot_ctx->slot_bank.vote_account_keys.account_keys_pool==NULL ) ) { + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( bank_mgr ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); + + if( FD_UNLIKELY( vote_account_keys_pool==NULL ) ) { FD_LOG_DEBUG(( "Vote accounts pool does not exist" )); + fd_bank_mgr_vote_account_keys_save( bank_mgr ); return; } @@ -2955,19 +2985,22 @@ upsert_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_memcpy( &vote_acc.elem.key, vote_account->pubkey->uc, sizeof(fd_pubkey_t) ); // Skip duplicates - if( FD_LIKELY( fd_account_keys_pair_t_map_find( slot_ctx->slot_bank.vote_account_keys.account_keys_pool, slot_ctx->slot_bank.vote_account_keys.account_keys_root, &key ) || + if( FD_LIKELY( fd_account_keys_pair_t_map_find( vote_account_keys_pool, vote_account_keys_root, &key ) || fd_vote_accounts_pair_t_map_find( epoch_bank->stakes.vote_accounts.vote_accounts_pool, epoch_bank->stakes.vote_accounts.vote_accounts_root, &vote_acc ) ) ) { + fd_bank_mgr_vote_account_keys_save( bank_mgr ); return; } - fd_account_keys_pair_t_mapnode_t * new_node = fd_account_keys_pair_t_map_acquire( slot_ctx->slot_bank.vote_account_keys.account_keys_pool ); + fd_account_keys_pair_t_mapnode_t * new_node = fd_account_keys_pair_t_map_acquire( vote_account_keys_pool ); if( FD_UNLIKELY( !new_node ) ) { FD_LOG_ERR(("Map full")); } fd_memcpy( &new_node->elem.key, vote_account->pubkey, sizeof(fd_pubkey_t)); - fd_account_keys_pair_t_map_insert( slot_ctx->slot_bank.vote_account_keys.account_keys_pool, &slot_ctx->slot_bank.vote_account_keys.account_keys_root, new_node ); + fd_account_keys_pair_t_map_insert( vote_account_keys_pool, &vote_account_keys_root, new_node ); + fd_bank_mgr_vote_account_keys_save( bank_mgr ); } else { + fd_bank_mgr_vote_account_keys_save( bank_mgr ); remove_vote_account( slot_ctx, vote_account ); } } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar.c b/src/flamenco/runtime/sysvar/fd_sysvar.c index 85e41a1fd3..4b98086da3 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar.c @@ -1,4 +1,5 @@ #include "fd_sysvar.h" +#include "../fd_bank_mgr.h" #include "../context/fd_exec_epoch_ctx.h" #include "../context/fd_exec_slot_ctx.h" #include "fd_sysvar_rent.h" @@ -32,13 +33,19 @@ fd_sysvar_set( fd_exec_slot_ctx_t * slot_ctx, fd_acc_lamports_t lamports_after = fd_ulong_max( lamports_before, fd_rent_exempt_minimum_balance( &epoch_bank->rent, sz ) ); rec->vt->set_lamports( rec, lamports_after ); + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, funk, funk_txn ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank.rs#L1826 */ - if ( lamports_after > lamports_before ) { - slot_ctx->slot_bank.capitalization += ( lamports_after - lamports_before ); + if( lamports_after > lamports_before ) { + *capitalization += ( lamports_after - lamports_before ); } else if( lamports_after < lamports_before ) { - slot_ctx->slot_bank.capitalization -= ( lamports_before - lamports_after ); + *capitalization -= ( lamports_before - lamports_after ); } + fd_bank_mgr_capitalization_save( bank_mgr ); + rec->vt->set_data_len( rec, sz ); rec->vt->set_owner( rec, owner ); rec->vt->set_slot( rec, slot ); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_clock.c b/src/flamenco/runtime/sysvar/fd_sysvar_clock.c index 5f57eda3a0..e8ccf36e6d 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_clock.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_clock.c @@ -2,6 +2,7 @@ #include "fd_sysvar_epoch_schedule.h" #include "fd_sysvar_rent.h" #include "../fd_executor.h" +#include "../fd_bank_mgr.h" #include "../fd_acc_mgr.h" #include "../fd_system_ids.h" #include "../context/fd_exec_epoch_ctx.h" @@ -25,10 +26,19 @@ /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/runtime/src/bank.rs#L2200 */ static long timestamp_from_genesis( fd_exec_slot_ctx_t * slot_ctx ) { - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); /* TODO: maybe make types of timestamps the same throughout the runtime codebase. as Solana uses a signed representation */ - FD_LOG_INFO(("slot %lu", slot_ctx->slot_bank.slot)); - return (long)( epoch_bank->genesis_creation_time + ( ( slot_ctx->slot_bank.slot * epoch_bank->ns_per_slot ) / NS_IN_S ) ); + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + + uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( bank_mgr ); + uint128 ns_per_slot = !!ns_per_slot_bm ? *ns_per_slot_bm : 0; + + ulong * genesis_creation_time_bm = fd_bank_mgr_genesis_creation_time_query( bank_mgr ); + ulong genesis_creation_time = !!genesis_creation_time_bm ? *genesis_creation_time_bm : 0; + + return (long)(genesis_creation_time + ((slot_ctx->slot * ns_per_slot) / NS_IN_S)); } static void @@ -43,7 +53,7 @@ write_clock( fd_exec_slot_ctx_t * slot_ctx, if( fd_sol_sysvar_clock_encode( clock, &ctx ) ) FD_LOG_ERR(("fd_sol_sysvar_clock_encode failed")); - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, (fd_pubkey_t *) &fd_sysvar_clock_id, enc, sz, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, (fd_pubkey_t *) &fd_sysvar_clock_id, enc, sz, slot_ctx->slot ); } @@ -69,7 +79,7 @@ fd_sysvar_clock_init( fd_exec_slot_ctx_t * slot_ctx ) { long timestamp = timestamp_from_genesis( slot_ctx ); fd_sol_sysvar_clock_t clock = { - .slot = slot_ctx->slot_bank.slot, + .slot = slot_ctx->slot, .epoch = 0, .epoch_start_timestamp = timestamp, .leader_schedule_epoch = 1, @@ -86,10 +96,13 @@ bound_timestamp_estimate( fd_exec_slot_ctx_t * slot_ctx, long estimate, long epoch_start_timestamp ) { + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( bank_mgr ); + uint128 ns_per_slot = !!ns_per_slot_bm ? *ns_per_slot_bm : 0; /* Determine offsets from start of epoch */ /* TODO: handle epoch boundary case */ - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - uint128 poh_estimate_offset = epoch_bank->ns_per_slot * slot_ctx->slot_bank.slot; + uint128 poh_estimate_offset = ns_per_slot * slot_ctx->slot; uint128 estimate_offset = (uint128)( ( estimate - epoch_start_timestamp ) * NS_IN_S ); uint128 max_delta_fast = ( poh_estimate_offset * MAX_ALLOWABLE_DRIFT_FAST ) / 100; @@ -117,16 +130,19 @@ estimate_timestamp( fd_exec_slot_ctx_t * slot_ctx ) { /* TODO: bound the estimate to ensure it stays within a certain range of the expected PoH clock: https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/runtime/src/stake_weighted_timestamp.rs#L13 */ - fd_clock_timestamp_vote_t_mapnode_t * votes = slot_ctx->slot_bank.timestamp_votes.votes_root; - if ( NULL == votes ) { + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( bank_mgr ); + fd_clock_timestamp_vote_t_mapnode_t * votes = !!clock_timestamp_votes ? fd_clock_timestamp_votes_votes_root_join( clock_timestamp_votes ) : NULL; + if( NULL==votes ) { return timestamp_from_genesis( slot_ctx ); } + uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_query( bank_mgr ); /* TODO: actually take the stake-weighted median. For now, just use the root node. */ fd_clock_timestamp_vote_t * head = &votes->elem; - ulong slots = slot_ctx->slot_bank.slot - head->slot; - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - uint128 ns_correction = epoch_bank->ns_per_slot * slots; + ulong slots = slot_ctx->slot - head->slot; + uint128 ns_correction = *ns_per_slot * slots; return head->timestamp + (long) (ns_correction / NS_IN_S) ; } @@ -174,8 +190,12 @@ fd_calculate_stake_weighted_timestamp( fd_exec_slot_ctx_t * slot_ctx, uint fix_estimate_into_u64, fd_spad_t * runtime_spad ) { FD_SPAD_FRAME_BEGIN( runtime_spad ) { - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong slot_duration = (ulong)( epoch_bank->ns_per_slot ); + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( bank_mgr ); + ulong slot_duration = !!ns_per_slot_bm ? (ulong)*ns_per_slot_bm : 0UL; fd_sol_sysvar_clock_t const * clock = fd_sysvar_clock_read( slot_ctx->funk, slot_ctx->funk_txn, runtime_spad ); @@ -188,16 +208,27 @@ fd_calculate_stake_weighted_timestamp( fd_exec_slot_ctx_t * slot_ctx, stake_ts_treap_t * treap = stake_ts_treap_join( stake_ts_treap_new( _treap, 10240UL ) ); uchar * pool_mem = fd_spad_alloc( runtime_spad, stake_ts_pool_align(), stake_ts_pool_footprint( 10240UL ) ); stake_ts_ele_t * pool = stake_ts_pool_join( stake_ts_pool_new( pool_mem, 10240UL ) ); + + ulong * txn_cnt_bm = fd_bank_mgr_transaction_count_query( bank_mgr ); + uint txn_cnt = !!txn_cnt_bm ? (uint)*txn_cnt_bm : 0; + fd_rng_t _rng[1]; - fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, (uint)slot_ctx->slot_bank.transaction_count, 0UL ) ); + fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, txn_cnt, 0UL ) ); ulong total_stake = 0; - fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_root = slot_ctx->slot_bank.timestamp_votes.votes_root; - fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_pool = slot_ctx->slot_bank.timestamp_votes.votes_pool; + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( bank_mgr ); + if( FD_UNLIKELY( !clock_timestamp_votes ) ) { + *result_timestamp = 0; + return; + } + + fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_pool = fd_clock_timestamp_votes_votes_pool_join( clock_timestamp_votes ); + fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_root = fd_clock_timestamp_votes_votes_root_join( clock_timestamp_votes ); + fd_vote_accounts_pair_t_mapnode_t * vote_acc_root = slot_ctx->slot_bank.epoch_stakes.vote_accounts_root; fd_vote_accounts_pair_t_mapnode_t * vote_acc_pool = slot_ctx->slot_bank.epoch_stakes.vote_accounts_pool; - for( fd_vote_accounts_pair_t_mapnode_t* n = fd_vote_accounts_pair_t_map_minimum(vote_acc_pool, vote_acc_root); + for( fd_vote_accounts_pair_t_mapnode_t * n = fd_vote_accounts_pair_t_map_minimum(vote_acc_pool, vote_acc_root); n; n = fd_vote_accounts_pair_t_map_successor( vote_acc_pool, n ) ) { @@ -209,7 +240,9 @@ fd_calculate_stake_weighted_timestamp( fd_exec_slot_ctx_t * slot_ctx, } else { fd_clock_timestamp_vote_t_mapnode_t query_vote_acc_node; query_vote_acc_node.elem.pubkey = *vote_pubkey; - fd_clock_timestamp_vote_t_mapnode_t * vote_acc_node = fd_clock_timestamp_vote_t_map_find(timestamp_votes_pool, timestamp_votes_root, &query_vote_acc_node); + fd_clock_timestamp_vote_t_mapnode_t * vote_acc_node = fd_clock_timestamp_vote_t_map_find( timestamp_votes_pool, + timestamp_votes_root, + &query_vote_acc_node ); ulong vote_timestamp = 0; ulong vote_slot = 0; if( vote_acc_node == NULL ) { @@ -246,7 +279,7 @@ fd_calculate_stake_weighted_timestamp( fd_exec_slot_ctx_t * slot_ctx, vote_slot = vote_acc_node->elem.slot; } - ulong slot_delta = fd_ulong_sat_sub(slot_ctx->slot_bank.slot, vote_slot); + ulong slot_delta = fd_ulong_sat_sub(slot_ctx->slot, vote_slot); fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); if( slot_delta > epoch_bank->epoch_schedule.slots_per_epoch ) { continue; @@ -296,7 +329,7 @@ fd_calculate_stake_weighted_timestamp( fd_exec_slot_ctx_t * slot_ctx, fd_epoch_schedule_t schedule = slot_ctx->epoch_ctx->epoch_bank.epoch_schedule; ulong epoch_start_slot = fd_epoch_slot0( &schedule, clock->epoch ); FD_LOG_DEBUG(( "Epoch start slot %lu", epoch_start_slot )); - ulong poh_estimate_offset = fd_ulong_sat_mul( slot_duration, fd_ulong_sat_sub( slot_ctx->slot_bank.slot, epoch_start_slot ) ); + ulong poh_estimate_offset = fd_ulong_sat_mul( slot_duration, fd_ulong_sat_sub( slot_ctx->slot, epoch_start_slot ) ); ulong estimate_offset = fd_ulong_sat_mul( NS_IN_S, (fix_estimate_into_u64) ? fd_ulong_sat_sub( (ulong)*result_timestamp, (ulong)clock->epoch_start_timestamp ) : (ulong)(*result_timestamp - clock->epoch_start_timestamp)); ulong max_delta_fast = fd_ulong_sat_mul( poh_estimate_offset, MAX_ALLOWABLE_DRIFT_FAST ) / 100; ulong max_delta_slow = fd_ulong_sat_mul( poh_estimate_offset, MAX_ALLOWABLE_DRIFT_SLOW ) / 100; @@ -340,11 +373,11 @@ fd_sysvar_clock_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad long ancestor_timestamp = clock->unix_timestamp; - if( slot_ctx->slot_bank.slot != 0 ) { + if( slot_ctx->slot != 0 ) { long new_timestamp = 0L; fd_calculate_stake_weighted_timestamp( slot_ctx, &new_timestamp, - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, warp_timestamp_again ), + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, warp_timestamp_again ), runtime_spad ); /* If the timestamp was successfully calculated, use it. It not keep the old one. @@ -378,7 +411,7 @@ fd_sysvar_clock_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad clock->unix_timestamp = bounded_timestamp_estimate; } - clock->slot = slot_ctx->slot_bank.slot; + clock->slot = slot_ctx->slot; ulong epoch_old = clock->epoch; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); @@ -391,14 +424,14 @@ fd_sysvar_clock_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad long timestamp_estimate = 0L; fd_calculate_stake_weighted_timestamp( slot_ctx, ×tamp_estimate, - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, warp_timestamp_again ), + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, warp_timestamp_again ), runtime_spad ); clock->unix_timestamp = fd_long_max( timestamp_estimate, ancestor_timestamp ); clock->epoch_start_timestamp = clock->unix_timestamp; - clock->leader_schedule_epoch = fd_slot_to_leader_schedule_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.slot ); + clock->leader_schedule_epoch = fd_slot_to_leader_schedule_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot ); } - FD_LOG_DEBUG(( "Updated clock at slot %lu", slot_ctx->slot_bank.slot )); + FD_LOG_DEBUG(( "Updated clock at slot %lu", slot_ctx->slot )); FD_LOG_DEBUG(( "clock->slot: %lu", clock->slot )); FD_LOG_DEBUG(( "clock->epoch_start_timestamp: %ld", clock->epoch_start_timestamp )); FD_LOG_DEBUG(( "clock->epoch: %lu", clock->epoch )); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c index 2211b91b0f..5ef8ed2d1d 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_rewards.c @@ -19,7 +19,7 @@ write_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_epoch_rewards_t * FD_LOG_ERR(( "fd_sysvar_epoch_rewards_encode failed" )); } - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_epoch_rewards_id, enc, sz, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_epoch_rewards_id, enc, sz, slot_ctx->slot ); } fd_sysvar_epoch_rewards_t * @@ -79,7 +79,7 @@ fd_sysvar_epoch_rewards_set_inactive( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_ERR(( "failed to read sysvar epoch rewards" )); } - if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { + if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { if( FD_UNLIKELY( epoch_rewards->total_rewards < epoch_rewards->distributed_rewards ) ) { FD_LOG_ERR(( "distributed rewards overflow" )); } @@ -125,7 +125,7 @@ fd_sysvar_epoch_rewards_init( fd_exec_slot_ctx_t * slot_ctx, On other clusters, including those where enable_partitioned_epoch_reward is enabled, we should use total_rewards. https://github.com/anza-xyz/agave/blob/b9c9ecccbb05d9da774d600bdbef2cf210c57fa8/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L36-L43 */ - if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { + if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) { epoch_rewards.total_rewards = point_value.rewards; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c index 6e44ab865b..9d5d0d548a 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_epoch_schedule.c @@ -48,7 +48,7 @@ write_epoch_schedule( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_ERR(("fd_epoch_schedule_encode failed")); } - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_epoch_schedule_id, enc, sz, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_epoch_schedule_id, enc, sz, slot_ctx->slot ); } fd_epoch_schedule_t * diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_fees.c b/src/flamenco/runtime/sysvar/fd_sysvar_fees.c index 2a40c39f43..46a9df84ac 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_fees.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_fees.c @@ -2,6 +2,7 @@ #include "fd_sysvar.h" #include "../fd_system_ids.h" #include "../fd_runtime.h" +#include "../fd_bank_mgr.h" #include "../context/fd_exec_epoch_ctx.h" static void @@ -17,7 +18,7 @@ write_fees( fd_exec_slot_ctx_t* slot_ctx, fd_sysvar_fees_t* fees ) { FD_LOG_ERR(( "fd_sysvar_fees_encode failed" )); } - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_fees_id, enc, sz, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_fees_id, enc, sz, slot_ctx->slot ); } fd_sysvar_fees_t * @@ -42,18 +43,22 @@ fd_sysvar_fees_read( fd_funk_t * funk, */ void fd_sysvar_fees_new_derived( fd_exec_slot_ctx_t * slot_ctx, - fd_fee_rate_governor_t base_fee_rate_governor, ulong latest_singatures_per_slot ) { + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_fee_rate_governor_t * base_fee_rate_governor = fd_bank_mgr_fee_rate_governor_query( bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( bank_mgr ); + fd_fee_rate_governor_t me = { - .target_signatures_per_slot = base_fee_rate_governor.target_signatures_per_slot, - .target_lamports_per_signature = base_fee_rate_governor.target_lamports_per_signature, - .max_lamports_per_signature = base_fee_rate_governor.max_lamports_per_signature, - .min_lamports_per_signature = base_fee_rate_governor.min_lamports_per_signature, - .burn_percent = base_fee_rate_governor.burn_percent + .target_signatures_per_slot = base_fee_rate_governor->target_signatures_per_slot, + .target_lamports_per_signature = base_fee_rate_governor->target_lamports_per_signature, + .max_lamports_per_signature = base_fee_rate_governor->max_lamports_per_signature, + .min_lamports_per_signature = base_fee_rate_governor->min_lamports_per_signature, + .burn_percent = base_fee_rate_governor->burn_percent }; - ulong lamports_per_signature = 0; - if ( me.target_signatures_per_slot > 0 ) { + ulong new_lamports_per_signature = 0; + if( me.target_signatures_per_slot > 0 ) { me.min_lamports_per_signature = fd_ulong_max( 1UL, (ulong)(me.target_lamports_per_signature / 2) ); me.max_lamports_per_signature = me.target_lamports_per_signature * 10; ulong desired_lamports_per_signature = fd_ulong_min( @@ -65,40 +70,47 @@ fd_sysvar_fees_new_derived( fd_exec_slot_ctx_t * slot_ctx, / me.target_signatures_per_slot ) ); - long gap = (long)desired_lamports_per_signature - (long)slot_ctx->slot_bank.lamports_per_signature; + long gap = (long)desired_lamports_per_signature - (long)*lamports_per_signature; if ( gap == 0 ) { - lamports_per_signature = desired_lamports_per_signature; + new_lamports_per_signature = desired_lamports_per_signature; } else { long gap_adjust = (long)(fd_ulong_max( 1UL, (ulong)(me.target_lamports_per_signature / 20) )) * (gap != 0) * (gap > 0 ? 1 : -1); - lamports_per_signature = fd_ulong_min( + new_lamports_per_signature = fd_ulong_min( me.max_lamports_per_signature, fd_ulong_max( me.min_lamports_per_signature, - (ulong)((long) slot_ctx->slot_bank.lamports_per_signature + gap_adjust) + (ulong)((long)*lamports_per_signature + gap_adjust) ) ); } } else { - lamports_per_signature = base_fee_rate_governor.target_lamports_per_signature; + new_lamports_per_signature = base_fee_rate_governor->target_lamports_per_signature; me.min_lamports_per_signature = me.target_lamports_per_signature; me.max_lamports_per_signature = me.target_lamports_per_signature; } - if( FD_UNLIKELY( slot_ctx->slot_bank.lamports_per_signature==0UL ) ) { - slot_ctx->prev_lamports_per_signature = lamports_per_signature; + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( bank_mgr ); + if( FD_UNLIKELY( *lamports_per_signature==0UL ) ) { + *prev_lamports_per_signature = new_lamports_per_signature; } else { - slot_ctx->prev_lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; + *prev_lamports_per_signature = *lamports_per_signature; } + fd_bank_mgr_prev_lamports_per_signature_save( bank_mgr ); + + base_fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( bank_mgr ); + *base_fee_rate_governor = me; + fd_bank_mgr_fee_rate_governor_save( bank_mgr ); - slot_ctx->slot_bank.lamports_per_signature = lamports_per_signature; - slot_ctx->slot_bank.fee_rate_governor = me; + lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( bank_mgr ); + *lamports_per_signature = new_lamports_per_signature; + fd_bank_mgr_lamports_per_signature_save( bank_mgr ); } void fd_sysvar_fees_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar )) + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, disable_fees_sysvar )) return; fd_sysvar_fees_t * fees = fd_sysvar_fees_read( slot_ctx->funk, @@ -107,8 +119,11 @@ fd_sysvar_fees_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) if( FD_UNLIKELY( fees == NULL ) ) { FD_LOG_ERR(( "failed to read sysvar fees" )); } - /* todo: I need to the lamports_per_signature field */ - fees->fee_calculator.lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature; + + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( bank_mgr ); + fees->fee_calculator.lamports_per_signature = *lamports_per_signature; write_fees( slot_ctx, fees ); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_fees.h b/src/flamenco/runtime/sysvar/fd_sysvar_fees.h index b400ea64dd..17885b3ad6 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_fees.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_fees.h @@ -21,7 +21,6 @@ fd_sysvar_fees_read( fd_funk_t * funk, void fd_sysvar_fees_new_derived( fd_exec_slot_ctx_t * slot_ctx, - fd_fee_rate_governor_t base_fee_rate_governor, ulong latest_singatures_per_slot ); /* Updates fees for every slot. */ diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c b/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c index d14c7ccb18..9c8b369b6d 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c @@ -3,16 +3,22 @@ #include "fd_sysvar.h" #include "../fd_system_ids.h" #include "../fd_runtime.h" - +#include "../fd_bank_mgr.h" void fd_sysvar_last_restart_slot_init( fd_exec_slot_ctx_t * slot_ctx ) { - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, last_restart_slot_sysvar ) ) { + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, last_restart_slot_sysvar ) ) { FD_LOG_INFO(( "sysvar LastRestartSlot not supported by this ledger version!" )); return; } - fd_sol_sysvar_last_restart_slot_t const * sysvar = &slot_ctx->slot_bank.last_restart_slot; + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_sol_sysvar_last_restart_slot_t const * sysvar = fd_bank_mgr_last_restart_slot_query( bank_mgr ); + + fd_sol_sysvar_last_restart_slot_t sysvar_default = {0}; + sysvar = !!sysvar ? sysvar : &sysvar_default; ulong sz = fd_sol_sysvar_last_restart_slot_size( sysvar ); uchar enc[ sz ]; @@ -29,7 +35,7 @@ fd_sysvar_last_restart_slot_init( fd_exec_slot_ctx_t * slot_ctx ) { &fd_sysvar_owner_id, &fd_sysvar_last_restart_slot_id, enc, sz, - slot_ctx->slot_bank.slot ); + slot_ctx->slot ); } fd_sol_sysvar_last_restart_slot_t * @@ -55,7 +61,7 @@ void fd_sysvar_last_restart_slot_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2093-L2095 */ - if( !FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, last_restart_slot_sysvar ) ) return; + if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, last_restart_slot_sysvar ) ) return; int has_current_last_restart_slot = 0; ulong current_last_restart_slot = 0UL; @@ -70,7 +76,9 @@ fd_sysvar_last_restart_slot_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * r /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2108-L2120 */ /* FIXME: Query hard forks list */ - ulong last_restart_slot = slot_ctx->slot_bank.last_restart_slot.slot; + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + ulong last_restart_slot = fd_bank_mgr_last_restart_slot_query( bank_mgr )->slot; /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2122-L2130 */ if( !has_current_last_restart_slot || current_last_restart_slot != last_restart_slot ) { @@ -78,6 +86,6 @@ fd_sysvar_last_restart_slot_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * r slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_last_restart_slot_id, &last_restart_slot, sizeof(ulong), - slot_ctx->slot_bank.slot ); + slot_ctx->slot ); } } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c b/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c index dcf0c4c564..80918db29b 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c @@ -3,6 +3,7 @@ #include "../fd_hashes.h" #include "fd_sysvar.h" #include "../fd_runtime.h" +#include "../fd_bank_mgr.h" #include "../fd_system_ids.h" #include "../context/fd_exec_slot_ctx.h" @@ -21,23 +22,30 @@ /* Skips fd_types encoding preflight checks and directly serializes the blockhash queue into a buffer representing account data for the recent blockhashes sysvar. */ + static void encode_rbh_from_blockhash_queue( fd_exec_slot_ctx_t * slot_ctx, uchar * enc ) { - /* recent_blockhashes_account::update_account's `take` call takes at most 150 elements - https://github.com/anza-xyz/agave/blob/v2.1.6/runtime/src/bank/recent_blockhashes_account.rs#L15-L28 */ - fd_block_hash_queue_t const * queue = &slot_ctx->slot_bank.block_hash_queue; - ulong queue_sz = fd_hash_hash_age_pair_t_map_size( queue->ages_pool, queue->ages_root ); - ulong hashes_len = fd_ulong_min( queue_sz, FD_RECENT_BLOCKHASHES_MAX_ENTRIES ); + fd_bank_mgr_t bank_mgr_obj; + + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( bank_mgr ); + + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_block_hash_queue_ages_pool_join( bhq ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_block_hash_queue_ages_root_join( bhq ); + + ulong queue_sz = fd_hash_hash_age_pair_t_map_size( ages_pool, ages_root ); + ulong hashes_len = fd_ulong_min( queue_sz, FD_RECENT_BLOCKHASHES_MAX_ENTRIES ); fd_memcpy( enc, &hashes_len, sizeof(ulong) ); enc += sizeof(ulong); - /* Iterate over blockhash queue and encode the recent blockhashes. We can do direct memcpying - and avoid redundant checks from fd_types encoders since the enc buffer is already sized out to - the worst-case bound. */ + /* Iterate over blockhash queue and encode the recent blockhashes. + We can do direct memcpying and avoid redundant checks from fd_types + encoders since the enc buffer is already sized out to the + worst-case bound. */ fd_hash_hash_age_pair_t_mapnode_t const * nn; - for( fd_hash_hash_age_pair_t_mapnode_t const * n = fd_hash_hash_age_pair_t_map_minimum_const( queue->ages_pool, queue->ages_root ); n; n = nn ) { - nn = fd_hash_hash_age_pair_t_map_successor_const( queue->ages_pool, n ); - ulong enc_idx = queue->last_hash_index - n->elem.val.hash_index; + for( fd_hash_hash_age_pair_t_mapnode_t const * n = fd_hash_hash_age_pair_t_map_minimum_const( ages_pool, ages_root ); n; n = nn ) { + nn = fd_hash_hash_age_pair_t_map_successor_const( ages_pool, n ); + ulong enc_idx = bhq->last_hash_index - n->elem.val.hash_index; if( enc_idx>=hashes_len ) { continue; } @@ -47,6 +55,7 @@ encode_rbh_from_blockhash_queue( fd_exec_slot_ctx_t * slot_ctx, uchar * enc ) { fd_memcpy( enc + enc_idx * (FD_HASH_FOOTPRINT + sizeof(ulong)), &hash, FD_HASH_FOOTPRINT ); fd_memcpy( enc + enc_idx * (FD_HASH_FOOTPRINT + sizeof(ulong)) + sizeof(fd_hash_t), &lps, sizeof(ulong) ); } + } // https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/fee_calculator.rs#L110 @@ -56,7 +65,7 @@ fd_sysvar_recent_hashes_init( fd_exec_slot_ctx_t * slot_ctx, FD_SPAD_FRAME_BEGIN( runtime_spad ) { - if( slot_ctx->slot_bank.slot != 0 ) { + if( slot_ctx->slot != 0 ) { return; } @@ -64,41 +73,52 @@ fd_sysvar_recent_hashes_init( fd_exec_slot_ctx_t * slot_ctx, uchar * enc = fd_spad_alloc( runtime_spad, FD_SPAD_ALIGN, sz ); fd_memset( enc, 0, sz ); encode_rbh_from_blockhash_queue( slot_ctx, enc ); - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_recent_block_hashes_id, enc, sz, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_recent_block_hashes_id, enc, sz, slot_ctx->slot ); } FD_SPAD_FRAME_END; } -// https://github.com/anza-xyz/agave/blob/e8750ba574d9ac7b72e944bc1227dc7372e3a490/accounts-db/src/blockhash_queue.rs#L113 static void register_blockhash( fd_exec_slot_ctx_t * slot_ctx, fd_hash_t const * hash ) { - fd_block_hash_queue_t * queue = &slot_ctx->slot_bank.block_hash_queue; - // https://github.com/anza-xyz/agave/blob/e8750ba574d9ac7b72e944bc1227dc7372e3a490/accounts-db/src/blockhash_queue.rs#L114 - queue->last_hash_index++; - if ( fd_hash_hash_age_pair_t_map_size( queue->ages_pool, queue->ages_root ) >= queue->max_age ) { + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( bank_mgr ); + + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_modify( bank_mgr ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_block_hash_queue_ages_pool_join( bhq ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_block_hash_queue_ages_root_join( bhq ); + bhq->last_hash_index++; + if( fd_hash_hash_age_pair_t_map_size( ages_pool, ages_root ) >= bhq->max_age ) { fd_hash_hash_age_pair_t_mapnode_t * nn; - for ( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( queue->ages_pool, queue->ages_root ); n; n = nn ) { - nn = fd_hash_hash_age_pair_t_map_successor( queue->ages_pool, n ); + for( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( ages_pool, ages_root ); n; n = nn ) { + nn = fd_hash_hash_age_pair_t_map_successor( ages_pool, n ); /* NOTE: Yes, this check is incorrect. It should be >= which caps the blockhash queue at max_age entries, but instead max_age + 1 entries are allowed to exist in the queue at once. This mimics Agave to stay conformant with their implementation. https://github.com/anza-xyz/agave/blob/e8750ba574d9ac7b72e944bc1227dc7372e3a490/accounts-db/src/blockhash_queue.rs#L109 */ - if ( queue->last_hash_index - n->elem.val.hash_index > queue->max_age ) { - fd_hash_hash_age_pair_t_map_remove( queue->ages_pool, &queue->ages_root, n ); - fd_hash_hash_age_pair_t_map_release( queue->ages_pool, n ); + if( bhq->last_hash_index - n->elem.val.hash_index > bhq->max_age ) { + fd_hash_hash_age_pair_t_map_remove( ages_pool, &ages_root, n ); + fd_hash_hash_age_pair_t_map_release( ages_pool, n ); } } } - fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( queue->ages_pool ); + fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( ages_pool ); node->elem = (fd_hash_hash_age_pair_t){ .key = *hash, - .val = (fd_hash_age_t){ .hash_index = queue->last_hash_index, .fee_calculator = (fd_fee_calculator_t){.lamports_per_signature = slot_ctx->slot_bank.lamports_per_signature}, .timestamp = (ulong)fd_log_wallclock() } + .val = (fd_hash_age_t){ .hash_index = bhq->last_hash_index, .fee_calculator = (fd_fee_calculator_t){.lamports_per_signature = *lamports_per_signature}, .timestamp = (ulong)fd_log_wallclock() } }; // https://github.com/anza-xyz/agave/blob/e8750ba574d9ac7b72e944bc1227dc7372e3a490/accounts-db/src/blockhash_queue.rs#L121-L128 - fd_hash_hash_age_pair_t_map_insert( slot_ctx->slot_bank.block_hash_queue.ages_pool, &slot_ctx->slot_bank.block_hash_queue.ages_root, node ); + fd_hash_hash_age_pair_t_map_insert( ages_pool, &ages_root, node ); // https://github.com/anza-xyz/agave/blob/e8750ba574d9ac7b72e944bc1227dc7372e3a490/accounts-db/src/blockhash_queue.rs#L130 - *queue->last_hash = *hash; + fd_hash_t * last_hash = fd_block_hash_queue_last_hash_join( bhq ); + fd_memcpy( last_hash, hash, sizeof(fd_hash_t) ); + + bhq->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)bhq; + bhq->ages_root_offset = (ulong)ages_root - (ulong)bhq; + + fd_bank_mgr_block_hash_queue_save( bank_mgr ); } /* This implementation is more consistent with Agave's bank implementation for updating the block hashes sysvar: @@ -110,7 +130,10 @@ void fd_sysvar_recent_hashes_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { FD_SPAD_FRAME_BEGIN( runtime_spad ) { /* Update the blockhash queue */ - register_blockhash( slot_ctx, &slot_ctx->slot_bank.poh ); + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_hash_t * poh = fd_bank_mgr_poh_query( bank_mgr ); + register_blockhash( slot_ctx, poh ); /* Derive the new sysvar recent blockhashes from the blockhash queue */ ulong sz = FD_RECENT_BLOCKHASHES_ACCOUNT_MAX_SIZE; @@ -127,6 +150,6 @@ fd_sysvar_recent_hashes_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runti &fd_sysvar_recent_block_hashes_id, enc_start, sz, - slot_ctx->slot_bank.slot ); + slot_ctx->slot ); } FD_SPAD_FRAME_END; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_rent.c b/src/flamenco/runtime/sysvar/fd_sysvar_rent.c index b83c4ba9ba..3267e865db 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_rent.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_rent.c @@ -21,7 +21,7 @@ write_rent( fd_exec_slot_ctx_t * slot_ctx, if( fd_rent_encode( rent, &ctx ) ) FD_LOG_ERR(("fd_rent_encode failed")); - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_rent_id, enc, sz, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_rent_id, enc, sz, slot_ctx->slot ); } void diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c index b472e6d427..82836216f3 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c @@ -26,7 +26,7 @@ fd_sysvar_slot_hashes_write( fd_exec_slot_ctx_t * slot_ctx, if( fd_slot_hashes_encode_global( slot_hashes_global, &ctx ) ) { FD_LOG_ERR(("fd_slot_hashes_encode failed")); } - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_slot_hashes_id, enc, slot_hashes_account_size, slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_slot_hashes_id, enc, slot_hashes_account_size, slot_ctx->slot ); } ulong @@ -110,8 +110,8 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { !deq_fd_slot_hash_t_iter_done( hashes, iter ); iter = deq_fd_slot_hash_t_iter_next( hashes, iter ) ) { fd_slot_hash_t * ele = deq_fd_slot_hash_t_iter_ele( hashes, iter ); - if( ele->slot == slot_ctx->slot_bank.slot ) { - ele->hash = slot_ctx->slot_bank.banks_hash; + if( ele->slot == slot_ctx->slot ) { + memcpy( &ele->hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); found = 1; } } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_slot_history.c b/src/flamenco/runtime/sysvar/fd_sysvar_slot_history.c index 9f4d9f44c1..ed01aaa144 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_slot_history.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_slot_history.c @@ -49,7 +49,7 @@ fd_sysvar_slot_history_write_history( fd_exec_slot_ctx_t * slot_ctx, int err = fd_slot_history_encode_global( history, &ctx ); if (0 != err) return err; - return fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_slot_history_id, enc, sz, slot_ctx->slot_bank.slot ); + return fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_slot_history_id, enc, sz, slot_ctx->slot ); } /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_history.rs#L16 */ @@ -66,14 +66,14 @@ fd_sysvar_slot_history_init( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_ fd_slot_history_global_t * history = (fd_slot_history_global_t *)mem; ulong * blocks = (ulong *)fd_ulong_align_up( (ulong)((uchar*)history + sizeof(fd_slot_history_global_t)), alignof(ulong) ); - history->next_slot = slot_ctx->slot_bank.slot + 1UL; + history->next_slot = slot_ctx->slot + 1UL; history->bits_bitvec_offset = (ulong)((uchar*)blocks - (uchar*)history); history->bits_len = slot_history_max_entries; history->bits_bitvec_len = blocks_len; memset( blocks, 0, sizeof(ulong) * blocks_len ); /* TODO: handle slot != 0 init case */ - fd_sysvar_slot_history_set( history, slot_ctx->slot_bank.slot ); + fd_sysvar_slot_history_set( history, slot_ctx->slot ); fd_sysvar_slot_history_write_history( slot_ctx, history ); } FD_SPAD_FRAME_END; } @@ -110,8 +110,8 @@ fd_sysvar_slot_history_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtim fd_slot_history_global_t * history = fd_slot_history_decode_global( mem, &ctx ); /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_history.rs#L48 */ - fd_sysvar_slot_history_set( history, slot_ctx->slot_bank.slot ); - history->next_slot = slot_ctx->slot_bank.slot + 1; + fd_sysvar_slot_history_set( history, slot_ctx->slot ); + history->next_slot = slot_ctx->slot + 1; ulong sz = slot_history_min_account_size; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c index 6042dc9cfe..98a0e4e255 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_stake_history.c @@ -18,7 +18,7 @@ write_stake_history( fd_exec_slot_ctx_t * slot_ctx, if( FD_UNLIKELY( fd_stake_history_encode( stake_history, &encode )!=FD_BINCODE_SUCCESS ) ) FD_LOG_ERR(("fd_stake_history_encode failed")); - fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_stake_history_id, enc, sizeof(enc), slot_ctx->slot_bank.slot ); + fd_sysvar_set( slot_ctx, &fd_sysvar_owner_id, &fd_sysvar_stake_history_id, enc, sizeof(enc), slot_ctx->slot ); } static fd_stake_history_t * diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 34e4879954..c9f18c21c8 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -4,6 +4,7 @@ #include "harness/generated/vm.pb.h" #include "../fd_system_ids.h" #include "../fd_runtime.h" +#include "../fd_bank_mgr.h" #include "../program/fd_address_lookup_table_program.h" #include "../../../ballet/lthash/fd_lthash.h" #include "../../../ballet/nanopb/pb_encode.h" @@ -340,16 +341,19 @@ dump_sanitized_transaction( fd_funk_t * funk, /** BLOCKHASH QUEUE DUMPING **/ static void -dump_blockhash_queue( fd_block_hash_queue_t const * queue, - fd_spad_t * spad, - pb_bytes_array_t ** output_blockhash_queue, - pb_size_t * output_blockhash_queue_count ) { +dump_blockhash_queue( fd_block_hash_queue_global_t const * queue, + fd_spad_t * spad, + pb_bytes_array_t ** output_blockhash_queue, + pb_size_t * output_blockhash_queue_count ) { pb_size_t cnt = 0; fd_hash_hash_age_pair_t_mapnode_t * nn; + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_block_hash_queue_ages_pool_join( queue ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_block_hash_queue_ages_root_join( queue ); + // Iterate over all block hashes in the queue and save them in the output - for ( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( queue->ages_pool, queue->ages_root ); n; n = nn ) { - nn = fd_hash_hash_age_pair_t_map_successor( queue->ages_pool, n ); + for( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( ages_pool, ages_root ); n; n = nn ) { + nn = fd_hash_hash_age_pair_t_map_successor( ages_pool, n ); /* Get the index in the blockhash queue - Lower index = newer @@ -420,8 +424,15 @@ create_block_context_protobuf_from_block( fd_exec_test_block_context_t * block_c ulong num_sysvar_entries = (sizeof(fd_relevant_sysvar_ids) / sizeof(fd_pubkey_t)); ulong num_loaded_builtins = (sizeof(loaded_builtins) / sizeof(fd_pubkey_t)); - ulong new_stake_account_cnt = fd_account_keys_pair_t_map_size( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, - slot_ctx->slot_bank.stake_account_keys.account_keys_root ); + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_query( bank_mgr ); + fd_account_keys_pair_t_mapnode_t * stake_account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); + fd_account_keys_pair_t_mapnode_t * stake_account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); + + + ulong new_stake_account_cnt = fd_account_keys_pair_t_map_size( stake_account_keys_pool, stake_account_keys_root ); ulong stake_account_cnt = fd_delegation_pair_t_map_size( epoch_ctx->epoch_bank.stakes.stake_delegations_pool, epoch_ctx->epoch_bank.stakes.stake_delegations_root ); @@ -460,36 +471,41 @@ create_block_context_protobuf_from_block( fd_exec_test_block_context_t * block_c alignof(pb_bytes_array_t *), PB_BYTES_ARRAY_T_ALLOCSIZE((FD_BLOCKHASH_QUEUE_MAX_ENTRIES + 1) * sizeof(pb_bytes_array_t *)) ); block_context->blockhash_queue = output_blockhash_queue; - dump_blockhash_queue( &slot_ctx->slot_bank.block_hash_queue, spad, block_context->blockhash_queue, &block_context->blockhash_queue_count ); + + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( bank_mgr ); + dump_blockhash_queue( bhq, spad, block_context->blockhash_queue, &block_context->blockhash_queue_count ); /* BlockContext -> SlotContext */ block_context->has_slot_ctx = true; - block_context->slot_ctx.slot = slot_ctx->slot_bank.slot; + block_context->slot_ctx.slot = slot_ctx->slot; // HACK FOR NOW: block height gets incremented in process_new_epoch, so we should dump block height + 1 - block_context->slot_ctx.block_height = slot_ctx->slot_bank.block_height + 1UL; + block_context->slot_ctx.block_height = *(fd_bank_mgr_block_height_query( bank_mgr )) + 1UL; // fd_memcpy( block_context->slot_ctx.poh, &slot_ctx->slot_bank.poh, sizeof(fd_pubkey_t) ); // TODO: dump here when process epoch happens after poh verification fd_memcpy( block_context->slot_ctx.parent_bank_hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_pubkey_t) ); fd_memcpy( block_context->slot_ctx.parent_lt_hash, &slot_ctx->slot_bank.lthash.lthash, FD_LTHASH_LEN_BYTES ); block_context->slot_ctx.prev_slot = slot_ctx->slot_bank.prev_slot; - block_context->slot_ctx.prev_lps = slot_ctx->prev_lamports_per_signature; - block_context->slot_ctx.prev_epoch_capitalization = slot_ctx->slot_bank.capitalization; + block_context->slot_ctx.prev_lps = *(fd_bank_mgr_prev_lamports_per_signature_query( bank_mgr )); + block_context->slot_ctx.prev_epoch_capitalization = *(fd_bank_mgr_capitalization_query( bank_mgr )); /* BlockContext -> EpochContext */ block_context->has_epoch_ctx = true; block_context->epoch_ctx.has_features = true; dump_sorted_features( &epoch_ctx->features, &block_context->epoch_ctx.features, spad ); - block_context->epoch_ctx.hashes_per_tick = epoch_ctx->epoch_bank.hashes_per_tick; - block_context->epoch_ctx.ticks_per_slot = epoch_ctx->epoch_bank.ticks_per_slot; - block_context->epoch_ctx.slots_per_year = epoch_ctx->epoch_bank.slots_per_year; + block_context->epoch_ctx.hashes_per_tick = *(fd_bank_mgr_hashes_per_tick_query( bank_mgr )); + block_context->epoch_ctx.ticks_per_slot = *(fd_bank_mgr_ticks_per_slot_query( bank_mgr )); + block_context->epoch_ctx.slots_per_year = *(fd_bank_mgr_slots_per_year_query( bank_mgr )); block_context->epoch_ctx.has_inflation = true; + + fd_inflation_t * inflation = fd_bank_mgr_inflation_query( bank_mgr ); + block_context->epoch_ctx.inflation = (fd_exec_test_inflation_t) { - .initial = epoch_ctx->epoch_bank.inflation.initial, - .terminal = epoch_ctx->epoch_bank.inflation.terminal, - .taper = epoch_ctx->epoch_bank.inflation.taper, - .foundation = epoch_ctx->epoch_bank.inflation.foundation, - .foundation_term = epoch_ctx->epoch_bank.inflation.foundation_term, + .initial = inflation->initial, + .terminal = inflation->terminal, + .taper = inflation->taper, + .foundation = inflation->foundation, + .foundation_term = inflation->foundation_term, }; - block_context->epoch_ctx.genesis_creation_time = epoch_ctx->epoch_bank.genesis_creation_time; + block_context->epoch_ctx.genesis_creation_time = *(fd_bank_mgr_genesis_creation_time_query( bank_mgr )); /* Dumping stake accounts */ @@ -500,10 +516,10 @@ create_block_context_protobuf_from_block( fd_exec_test_block_context_t * block_c new_stake_account_cnt * sizeof(pb_bytes_array_t *) ); for( fd_account_keys_pair_t_mapnode_t const * curr = fd_account_keys_pair_t_map_minimum_const( - slot_ctx->slot_bank.stake_account_keys.account_keys_pool, - slot_ctx->slot_bank.stake_account_keys.account_keys_root ); + stake_account_keys_pool, + stake_account_keys_root ); curr; - curr = fd_account_keys_pair_t_map_successor_const( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, curr ) ) { + curr = fd_account_keys_pair_t_map_successor_const( stake_account_keys_pool, curr ) ) { // Verify the stake state before dumping FD_TXN_ACCOUNT_DECL( account ); @@ -554,18 +570,24 @@ create_block_context_protobuf_from_block( fd_exec_test_block_context_t * block_c /* Dumping vote accounts */ // BlockContext -> EpochContext -> new_vote_accounts (vote accounts for the current running epoch) - ulong new_vote_account_cnt = fd_account_keys_pair_t_map_size( slot_ctx->slot_bank.vote_account_keys.account_keys_pool, - slot_ctx->slot_bank.vote_account_keys.account_keys_root ); + + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_query( bank_mgr ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); + + /* FIXME: if the map doesn't exist this will crash */ + + ulong new_vote_account_cnt = fd_account_keys_pair_t_map_size( vote_account_keys_pool, vote_account_keys_root ); block_context->epoch_ctx.new_vote_accounts_count = 0UL; block_context->epoch_ctx.new_vote_accounts = fd_spad_alloc( spad, alignof(fd_exec_test_vote_account_t), new_vote_account_cnt * sizeof(fd_exec_test_vote_account_t) ); for( fd_account_keys_pair_t_mapnode_t const * curr = fd_account_keys_pair_t_map_minimum_const( - slot_ctx->slot_bank.vote_account_keys.account_keys_pool, - slot_ctx->slot_bank.vote_account_keys.account_keys_root ); + vote_account_keys_pool, + vote_account_keys_root ); curr; - curr = fd_account_keys_pair_t_map_successor_const( slot_ctx->slot_bank.vote_account_keys.account_keys_pool, curr ) ) { + curr = fd_account_keys_pair_t_map_successor_const( vote_account_keys_pool, curr ) ) { // Verify the vote account before dumping FD_TXN_ACCOUNT_DECL( account ); @@ -635,7 +657,10 @@ create_block_context_protobuf_from_block_tx_only( fd_exec_test_block_context_t * /* BlockContext -> slot_ctx -> poh This currently needs to be done because POH verification is done after epoch boundary processing. That should probably be changed */ - fd_memcpy( block_context->slot_ctx.poh, &slot_ctx->slot_bank.poh, sizeof(fd_pubkey_t) ); + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + fd_hash_t * poh = fd_bank_mgr_poh_query( bank_mgr ); + fd_memcpy( block_context->slot_ctx.poh, poh->hash, sizeof(fd_pubkey_t) ); /* When iterating over microblocks batches and microblocks, we flatten the batches for the output block context (essentially just one big batch with several microblocks) */ for( ulong i=0UL; imicroblock_batch_cnt; i++ ) { @@ -822,7 +847,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m alignof(pb_bytes_array_t *), PB_BYTES_ARRAY_T_ALLOCSIZE((FD_BLOCKHASH_QUEUE_MAX_ENTRIES + 1) * sizeof(pb_bytes_array_t *)) ); txn_context_msg->blockhash_queue = output_blockhash_queue; - dump_blockhash_queue( &txn_ctx->block_hash_queue, spad, output_blockhash_queue, &txn_context_msg->blockhash_queue_count ); + dump_blockhash_queue( txn_ctx->block_hash_queue, spad, output_blockhash_queue, &txn_context_msg->blockhash_queue_count ); /* Transaction Context -> epoch_ctx */ txn_context_msg->has_epoch_ctx = true; @@ -1071,7 +1096,7 @@ fd_dump_block_to_protobuf_tx_only( fd_runtime_block_info_t const * block_info, if( pb_encode( &stream, FD_EXEC_TEST_BLOCK_CONTEXT_FIELDS, block_context_msg ) ) { char output_filepath[256]; fd_memset( output_filepath, 0, sizeof(output_filepath) ); char * position = fd_cstr_init( output_filepath ); - position = fd_cstr_append_printf( position, "%s/block-%lu.bin", capture_ctx->dump_proto_output_dir, slot_ctx->slot_bank.slot ); + position = fd_cstr_append_printf( position, "%s/block-%lu.bin", capture_ctx->dump_proto_output_dir, slot_ctx->slot ); fd_cstr_fini( position ); FILE * file = fopen(output_filepath, "wb"); diff --git a/src/flamenco/runtime/tests/harness/fd_block_harness.c b/src/flamenco/runtime/tests/harness/fd_block_harness.c index 2818f28b1b..af61fefccd 100644 --- a/src/flamenco/runtime/tests/harness/fd_block_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_block_harness.c @@ -71,49 +71,63 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, } /* Set up slot context */ + ulong slot = test_ctx->slot_ctx.slot; + slot_ctx->funk_txn = funk_txn; slot_ctx->funk = funk; slot_ctx->enable_exec_recording = 0; slot_ctx->epoch_ctx = epoch_ctx; slot_ctx->runtime_wksp = fd_wksp_containing( slot_ctx ); - slot_ctx->prev_lamports_per_signature = test_ctx->slot_ctx.prev_lps; + slot_ctx->slot = slot; + fd_memcpy( &slot_ctx->slot_bank.banks_hash, test_ctx->slot_ctx.parent_bank_hash, sizeof( fd_hash_t ) ); /* Set up slot bank */ - ulong slot = test_ctx->slot_ctx.slot; fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; fd_memcpy( slot_bank->lthash.lthash, test_ctx->slot_ctx.parent_lt_hash, FD_LTHASH_LEN_BYTES ); - slot_bank->slot = slot; - slot_bank->block_height = test_ctx->slot_ctx.block_height; slot_bank->prev_slot = test_ctx->slot_ctx.prev_slot; - slot_bank->fee_rate_governor = (fd_fee_rate_governor_t) { - .target_lamports_per_signature = 10000UL, - .target_signatures_per_slot = 20000UL, - .min_lamports_per_signature = 5000UL, - .max_lamports_per_signature = 100000UL, - .burn_percent = 50, - }; - slot_bank->capitalization = test_ctx->slot_ctx.prev_epoch_capitalization; - slot_bank->lamports_per_signature = 5000UL; /* Set up epoch context and epoch bank */ /* TODO: Do we need any more of these? */ fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( epoch_ctx ); + /* All bank mgr stuff here. */ + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + // self.max_tick_height = (self.slot + 1) * self.ticks_per_slot; - epoch_bank->hashes_per_tick = test_ctx->epoch_ctx.hashes_per_tick; - epoch_bank->ticks_per_slot = test_ctx->epoch_ctx.ticks_per_slot; - epoch_bank->ns_per_slot = (uint128)64000000; // TODO: restore from input or smth - epoch_bank->genesis_creation_time = test_ctx->epoch_ctx.genesis_creation_time; - epoch_bank->slots_per_year = test_ctx->epoch_ctx.slots_per_year; - epoch_bank->inflation = (fd_inflation_t) { - .initial = test_ctx->epoch_ctx.inflation.initial, - .terminal = test_ctx->epoch_ctx.inflation.terminal, - .taper = test_ctx->epoch_ctx.inflation.taper, - .foundation = test_ctx->epoch_ctx.inflation.foundation, - .foundation_term = test_ctx->epoch_ctx.inflation.foundation_term - }; + ulong * max_tick_height = fd_bank_mgr_max_tick_height_modify( bank_mgr ); + *max_tick_height = test_ctx->epoch_ctx.hashes_per_tick; + fd_bank_mgr_max_tick_height_save( bank_mgr ); + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_modify( bank_mgr ); + *ticks_per_slot = test_ctx->epoch_ctx.ticks_per_slot; + fd_bank_mgr_ticks_per_slot_save( bank_mgr ); + + uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_modify( bank_mgr ); + *ns_per_slot = (uint128)64000000; // TODO: restore from input + fd_bank_mgr_ns_per_slot_save( bank_mgr ); + + ulong * genesis_creation_time = fd_bank_mgr_genesis_creation_time_modify( bank_mgr ); + *genesis_creation_time = test_ctx->epoch_ctx.genesis_creation_time; + fd_bank_mgr_genesis_creation_time_save( bank_mgr ); + + double * slots_per_year = fd_bank_mgr_slots_per_year_modify( bank_mgr ); + *slots_per_year = test_ctx->epoch_ctx.slots_per_year; + fd_bank_mgr_slots_per_year_save( bank_mgr ); + + fd_inflation_t * inflation = fd_bank_mgr_inflation_modify( bank_mgr ); + inflation->initial = test_ctx->epoch_ctx.inflation.initial; + inflation->terminal = test_ctx->epoch_ctx.inflation.terminal; + inflation->taper = test_ctx->epoch_ctx.inflation.taper; + inflation->foundation = test_ctx->epoch_ctx.inflation.foundation; + inflation->foundation_term = test_ctx->epoch_ctx.inflation.foundation_term; + fd_bank_mgr_inflation_save( bank_mgr ); + + ulong * block_height = fd_bank_mgr_block_height_modify( bank_mgr ); + *block_height = test_ctx->slot_ctx.block_height; + fd_bank_mgr_block_height_save( bank_mgr ); /* Load in all accounts with > 0 lamports provided in the context */ for( ushort i=0; iacct_states_count; i++ ) { @@ -185,11 +199,6 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, runner->spad ); /* Initialize the current running epoch stake and vote accounts */ - pool_mem = fd_spad_alloc( runner->spad, - fd_account_keys_pair_t_map_align(), - fd_account_keys_pair_t_map_footprint( vote_acct_max ) ); - slot_bank->stake_account_keys.account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, vote_acct_max ) ); - slot_bank->stake_account_keys.account_keys_root = NULL; for( uint i=0U; iepoch_ctx.new_stake_accounts_count; i++ ) { FD_TXN_ACCOUNT_DECL( acc ); @@ -204,11 +213,6 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, fd_store_stake_delegation( slot_ctx, acc ); } - pool_mem = fd_spad_alloc( runner->spad, - fd_account_keys_pair_t_map_align(), - fd_account_keys_pair_t_map_footprint( vote_acct_max ) ); - slot_bank->vote_account_keys.account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, vote_acct_max ) ); - slot_bank->vote_account_keys.account_keys_root = NULL; for( uint i=0U; iepoch_ctx.new_vote_accounts_count; i++ ) { FD_TXN_ACCOUNT_DECL( acc ); @@ -224,34 +228,71 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, } /* Update leader schedule */ - fd_runtime_update_leaders( slot_ctx, slot_ctx->slot_bank.slot, runner->spad ); + fd_runtime_update_leaders( slot_ctx, slot_ctx->slot, runner->spad ); + + ulong * slot_bm = fd_bank_mgr_slot_modify( bank_mgr ); + *slot_bm = slot_ctx->slot; + fd_bank_mgr_slot_save( bank_mgr ); + + fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( bank_mgr ); + *fee_rate_governor = (fd_fee_rate_governor_t) { .target_lamports_per_signature = 10000UL, + .target_signatures_per_slot = 20000UL, + .min_lamports_per_signature = 5000UL, + .max_lamports_per_signature = 100000UL, + .burn_percent = 50, + }; + fd_bank_mgr_fee_rate_governor_save( bank_mgr ); + + ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + *capitalization = test_ctx->slot_ctx.prev_epoch_capitalization; + fd_bank_mgr_capitalization_save( bank_mgr ); + + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( bank_mgr ); + *lamports_per_signature = 5000UL; + fd_bank_mgr_lamports_per_signature_save( bank_mgr ); + + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( bank_mgr ); + *prev_lamports_per_signature = test_ctx->slot_ctx.prev_lps; + fd_bank_mgr_prev_lamports_per_signature_save( bank_mgr ); /* Initialize the blockhash queue and recent blockhashes sysvar from the input blockhash queue */ - slot_bank->block_hash_queue.max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; // Max age is fixed at 300 - slot_bank->block_hash_queue.ages_root = NULL; - pool_mem = fd_spad_alloc( runner->spad, fd_hash_hash_age_pair_t_map_align(), fd_hash_hash_age_pair_t_map_footprint( FD_BLOCKHASH_QUEUE_MAX_ENTRIES+1UL ) ); - slot_bank->block_hash_queue.ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( pool_mem, FD_BLOCKHASH_QUEUE_MAX_ENTRIES+1UL ) ); - slot_bank->block_hash_queue.last_hash = fd_valloc_malloc( fd_spad_virtual( runner->spad ), FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); + fd_block_hash_queue_global_t * block_hash_queue = fd_bank_mgr_block_hash_queue_modify( bank_mgr ); + uchar * last_hash_mem = (uchar *)fd_ulong_align_up( (ulong)block_hash_queue + sizeof(fd_block_hash_queue_global_t), alignof(fd_hash_t) ); + uchar * ages_pool_mem = (uchar *)fd_ulong_align_up( (ulong)last_hash_mem + sizeof(fd_hash_t), fd_hash_hash_age_pair_t_map_align() ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( ages_pool_mem, FD_BLOCKHASH_QUEUE_MAX_ENTRIES ) ); - /* TODO: Restore this from input */ - pool_mem = fd_spad_alloc( runner->spad, fd_clock_timestamp_vote_t_map_align(), fd_clock_timestamp_vote_t_map_footprint( 10000UL ) ); - slot_bank->timestamp_votes.votes_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new( pool_mem, 10000UL ) ); - slot_bank->timestamp_votes.votes_root = NULL; + block_hash_queue->max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; // Max age is fixed at 300 + block_hash_queue->ages_root_offset = 0UL; + block_hash_queue->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)block_hash_queue; + block_hash_queue->last_hash_index = 0UL; + block_hash_queue->last_hash_offset = (ulong)last_hash_mem - (ulong)block_hash_queue; - /* TODO: We might need to load this in from the input. We also need to size this out for worst case, but this also blows up the memory requirement. */ + fd_memset( last_hash_mem, 0, sizeof(fd_hash_t) ); + fd_bank_mgr_block_hash_queue_save( bank_mgr ); + + /* TODO: Restore this from input */ + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( bank_mgr ); + pool_mem = (uchar *)fd_ulong_align_up( (ulong)clock_timestamp_votes + sizeof(fd_clock_timestamp_votes_global_t), fd_clock_timestamp_vote_t_map_align() ); + fd_clock_timestamp_vote_t_mapnode_t * clock_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new( pool_mem, 15000UL ) ); + clock_timestamp_votes->votes_pool_offset = (ulong)fd_clock_timestamp_vote_t_map_leave( clock_pool) - (ulong)clock_timestamp_votes; + clock_timestamp_votes->votes_root_offset = 0UL; + fd_bank_mgr_clock_timestamp_votes_save( bank_mgr ); + + /* TODO: We might need to load this in from the input. We also need to + size this out for worst case, but this also blows up the memory + requirement. */ /* Allocate all the memory for the rent fresh accounts list */ - fd_rent_fresh_accounts_new( &slot_bank->rent_fresh_accounts ); - slot_bank->rent_fresh_accounts.total_count = 0UL; - slot_bank->rent_fresh_accounts.fresh_accounts_len = FD_RENT_FRESH_ACCOUNTS_MAX; - slot_bank->rent_fresh_accounts.fresh_accounts = fd_spad_alloc( - runner->spad, - alignof(fd_rent_fresh_account_t), - sizeof(fd_rent_fresh_account_t) * FD_RENT_FRESH_ACCOUNTS_MAX ); - fd_memset( slot_bank->rent_fresh_accounts.fresh_accounts, 0, sizeof(fd_rent_fresh_account_t) * FD_RENT_FRESH_ACCOUNTS_MAX ); + + fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( bank_mgr ); + fd_rent_fresh_account_t * fresh_accounts = (fd_rent_fresh_account_t *)fd_ulong_align_up( (ulong)rent_fresh_accounts + sizeof(fd_rent_fresh_accounts_global_t), alignof(fd_rent_fresh_account_t) ); + rent_fresh_accounts->total_count = 0UL; + rent_fresh_accounts->fresh_accounts_len = FD_RENT_FRESH_ACCOUNTS_MAX; + fd_memset( fresh_accounts, 0, sizeof(fd_rent_fresh_account_t) * FD_RENT_FRESH_ACCOUNTS_MAX ); + fd_rent_fresh_accounts_fresh_accounts_update( rent_fresh_accounts, fresh_accounts ); + fd_bank_mgr_rent_fresh_accounts_save( bank_mgr ); // Set genesis hash to {0} fd_memset( &epoch_bank->genesis_hash, 0, sizeof(fd_hash_t) ); - fd_memset( slot_bank->block_hash_queue.last_hash, 0, sizeof(fd_hash_t) ); // Use the latest lamports per signature fd_recent_block_hashes_global_t const * rbh_global = fd_sysvar_cache_recent_block_hashes( slot_ctx->sysvar_cache, runner->wksp ); @@ -263,8 +304,12 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, if( rbh_global && !deq_fd_block_block_hash_entry_t_empty( rbh->hashes ) ) { fd_block_block_hash_entry_t const * last = deq_fd_block_block_hash_entry_t_peek_head_const( rbh->hashes ); if( last && last->fee_calculator.lamports_per_signature!=0UL ) { - slot_bank->lamports_per_signature = last->fee_calculator.lamports_per_signature; - slot_ctx->prev_lamports_per_signature = last->fee_calculator.lamports_per_signature; + lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( bank_mgr ); + *lamports_per_signature = 5000UL; + fd_bank_mgr_lamports_per_signature_save( bank_mgr ); + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( bank_mgr ); + *prev_lamports_per_signature = last->fee_calculator.lamports_per_signature; + fd_bank_mgr_prev_lamports_per_signature_save( bank_mgr ); } } @@ -272,12 +317,16 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, for( ushort i=0; iblockhash_queue_count; ++i ) { fd_block_block_hash_entry_t blockhash_entry; memcpy( &blockhash_entry.blockhash, test_ctx->blockhash_queue[i]->bytes, sizeof(fd_hash_t) ); - slot_bank->poh = blockhash_entry.blockhash; + fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + fd_memcpy( poh->hash, &blockhash_entry.blockhash, sizeof(fd_hash_t) ); + fd_bank_mgr_poh_save( bank_mgr ); fd_sysvar_recent_hashes_update( slot_ctx, runner->spad ); } // Set the current poh from the input (we skip POH verification in this fuzzing target) - fd_memcpy( slot_ctx->slot_bank.poh.uc, test_ctx->slot_ctx.poh, FD_HASH_FOOTPRINT ); + fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + fd_memcpy( poh->hash, test_ctx->slot_ctx.poh, sizeof(fd_hash_t) ); + fd_bank_mgr_poh_save( bank_mgr ); /* Make a new funk transaction since we're done loading in accounts for context */ fd_funk_txn_xid_t fork_xid[1] = {0}; @@ -452,7 +501,9 @@ fd_runtime_fuzz_block_run( fd_runtime_fuzz_runner_t * runner, effects->has_error = !!( res ); /* Capture capitalization */ - effects->slot_capitalization = slot_ctx->slot_bank.capitalization; + fd_bank_mgr_t bank_mgr_obj; + fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + effects->slot_capitalization = *(fd_bank_mgr_capitalization_query( bank_mgr )); /* Capture hashes */ uchar out_lt_hash[32]; diff --git a/src/flamenco/runtime/tests/harness/fd_harness_common.h b/src/flamenco/runtime/tests/harness/fd_harness_common.h index 92424d6e5e..37187344cb 100644 --- a/src/flamenco/runtime/tests/harness/fd_harness_common.h +++ b/src/flamenco/runtime/tests/harness/fd_harness_common.h @@ -4,6 +4,7 @@ #include #include "../../fd_runtime.h" +#include "../../fd_bank_mgr.h" #include "generated/context.pb.h" /* fd_runtime_fuzz_runner_t provides a funk instance and spad, generic diff --git a/src/flamenco/runtime/tests/harness/fd_instr_harness.c b/src/flamenco/runtime/tests/harness/fd_instr_harness.c index 91ac2efe0c..ad1452b891 100644 --- a/src/flamenco/runtime/tests/harness/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_instr_harness.c @@ -64,11 +64,26 @@ fd_runtime_fuzz_instr_ctx_create( fd_runtime_fuzz_runner_t * runner, fd_slot_bank_new( &slot_ctx->slot_bank ); + /* Bank manager */ + + slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( slot_ctx->bank_mgr_mem ), slot_ctx->funk, funk_txn ); + /* Blockhash queue init */ - fd_block_hash_queue_t * blockhash_queue = &slot_ctx->slot_bank.block_hash_queue; - blockhash_queue->max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; - blockhash_queue->last_hash = fd_spad_alloc( runner->spad, FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); - fd_memset( blockhash_queue->last_hash, 0, FD_HASH_FOOTPRINT ); + + fd_block_hash_queue_global_t * block_hash_queue = fd_bank_mgr_block_hash_queue_modify( slot_ctx->bank_mgr ); + + uchar * last_hash_mem = (uchar *)fd_ulong_align_up( (ulong)block_hash_queue + sizeof(fd_block_hash_queue_global_t), alignof(fd_hash_t) ); + uchar * ages_pool_mem = (uchar *)fd_ulong_align_up( (ulong)last_hash_mem + sizeof(fd_hash_t), fd_hash_hash_age_pair_t_map_align() ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( ages_pool_mem, 400 ) ); + + block_hash_queue->max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; + block_hash_queue->ages_root_offset = 0UL; + block_hash_queue->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)block_hash_queue; + block_hash_queue->last_hash_index = 0UL; + block_hash_queue->last_hash_offset = (ulong)last_hash_mem - (ulong)block_hash_queue; + + memset( last_hash_mem, 0, sizeof(fd_hash_t) ); + fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); /* Set up txn context */ @@ -275,7 +290,11 @@ fd_runtime_fuzz_instr_ctx_create( fd_runtime_fuzz_runner_t * runner, } /* Set slot bank variables */ - slot_ctx->slot_bank.slot = fd_sysvar_cache_clock( slot_ctx->sysvar_cache, runner->wksp )->slot; + slot_ctx->slot = fd_sysvar_cache_clock( slot_ctx->sysvar_cache, runner->wksp )->slot; + + ulong * slot = fd_bank_mgr_slot_modify( slot_ctx->bank_mgr ); + *slot = slot_ctx->slot; + fd_bank_mgr_slot_save( slot_ctx->bank_mgr ); /* Handle undefined behavior if sysvars are malicious (!!!) */ @@ -295,9 +314,16 @@ fd_runtime_fuzz_instr_ctx_create( fd_runtime_fuzz_runner_t * runner, if( rbh_global && !deq_fd_block_block_hash_entry_t_empty( rbh->hashes ) ) { fd_block_block_hash_entry_t const * last = deq_fd_block_block_hash_entry_t_peek_tail_const( rbh->hashes ); if( last ) { - *blockhash_queue->last_hash = last->blockhash; - slot_ctx->slot_bank.lamports_per_signature = last->fee_calculator.lamports_per_signature; - slot_ctx->prev_lamports_per_signature = last->fee_calculator.lamports_per_signature; + block_hash_queue = fd_bank_mgr_block_hash_queue_modify( slot_ctx->bank_mgr ); + fd_hash_t * last_hash = fd_block_hash_queue_last_hash_join( block_hash_queue ); + fd_memcpy( last_hash, &last->blockhash, sizeof(fd_hash_t) ); + fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *lamports_per_signature = last->fee_calculator.lamports_per_signature; + fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *prev_lamports_per_signature = last->fee_calculator.lamports_per_signature; + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); } } diff --git a/src/flamenco/runtime/tests/harness/fd_txn_harness.c b/src/flamenco/runtime/tests/harness/fd_txn_harness.c index e26b84e50c..d3f6def193 100644 --- a/src/flamenco/runtime/tests/harness/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_txn_harness.c @@ -34,7 +34,9 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, /* Allocate contexts */ uchar * epoch_ctx_mem = fd_spad_alloc( runner->spad, fd_exec_epoch_ctx_align(), fd_exec_epoch_ctx_footprint( vote_acct_max ) ); - fd_exec_epoch_ctx_t * epoch_ctx = fd_exec_epoch_ctx_join( fd_exec_epoch_ctx_new( epoch_ctx_mem, vote_acct_max ) ); + fd_exec_epoch_ctx_t * epoch_ctx + + = fd_exec_epoch_ctx_join( fd_exec_epoch_ctx_new( epoch_ctx_mem, vote_acct_max ) ); assert( epoch_ctx ); assert( slot_ctx ); @@ -82,15 +84,36 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, ulong slot = test_ctx->slot_ctx.slot ? test_ctx->slot_ctx.slot : 10; // Arbitrary default > 0 /* Set slot bank variables (defaults obtained from GenesisConfig::default() in Agave) */ - slot_ctx->slot_bank.slot = slot; - slot_ctx->slot_bank.prev_slot = slot_ctx->slot_bank.slot - 1; // Can underflow, but its fine since it will correctly be ULONG_MAX - slot_ctx->slot_bank.fee_rate_governor.burn_percent = 50; - slot_ctx->slot_bank.fee_rate_governor.min_lamports_per_signature = 0; - slot_ctx->slot_bank.fee_rate_governor.max_lamports_per_signature = 0; - slot_ctx->slot_bank.fee_rate_governor.target_lamports_per_signature = 10000; - slot_ctx->slot_bank.fee_rate_governor.target_signatures_per_slot = 20000; - slot_ctx->slot_bank.lamports_per_signature = 5000; - slot_ctx->prev_lamports_per_signature = 5000; + slot_ctx->slot = slot; + slot_ctx->slot_bank.prev_slot = slot_ctx->slot - 1; // Can underflow, but its fine since it will correctly be ULONG_MAX + + /* Setup Bank manager */ + + slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( slot_ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); + + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *lamports_per_signature = 5000; + fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); + + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *prev_lamports_per_signature = 5000; + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); + + ulong * slot_bm = fd_bank_mgr_slot_modify( slot_ctx->bank_mgr ); + *slot_bm = slot_ctx->slot; + fd_bank_mgr_slot_save( slot_ctx->bank_mgr ); + + fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( slot_ctx->bank_mgr ); + fee_rate_governor->burn_percent = 50; + fee_rate_governor->min_lamports_per_signature = 0; + fee_rate_governor->max_lamports_per_signature = 0; + fee_rate_governor->target_lamports_per_signature = 10000; + fee_rate_governor->target_signatures_per_slot = 20000; + fd_bank_mgr_fee_rate_governor_save( slot_ctx->bank_mgr ); + + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_modify( slot_ctx->bank_mgr ); + *ticks_per_slot = 64; + fd_bank_mgr_ticks_per_slot_save( slot_ctx->bank_mgr ); /* Set epoch bank variables if not present (defaults obtained from GenesisConfig::default() in Agave) */ fd_epoch_schedule_t default_epoch_schedule = { @@ -108,8 +131,10 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, epoch_bank->epoch_schedule = default_epoch_schedule; epoch_bank->rent_epoch_schedule = default_epoch_schedule; epoch_bank->rent = default_rent; - epoch_bank->ticks_per_slot = 64; - epoch_bank->slots_per_year = SECONDS_PER_YEAR * (1000000000.0 / (double)6250000) / (double)epoch_bank->ticks_per_slot; + + double * slots_per_year = fd_bank_mgr_slots_per_year_modify( slot_ctx->bank_mgr ); + *slots_per_year = SECONDS_PER_YEAR * (1000000000.0 / (double)6250000) / (double)(*fd_bank_mgr_ticks_per_slot_query( slot_ctx->bank_mgr )); + fd_bank_mgr_slots_per_year_save( slot_ctx->bank_mgr ); // Override default values if provided if( slot_ctx->sysvar_cache->has_epoch_schedule ) { @@ -172,8 +197,8 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, THIS MAY CHANGE IN THE FUTURE. If there are other parts of transaction execution that use the epoch rewards sysvar, we may need to update this. */ - if( (FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || - FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature )) + if( (FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, enable_partitioned_epoch_reward ) || + FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature )) && !slot_ctx->sysvar_cache->has_epoch_rewards ) { fd_point_value_t point_value = {0}; fd_hash_t const * last_hash = test_ctx->blockhash_queue_count > 0 ? (fd_hash_t const *)test_ctx->blockhash_queue[0]->bytes : (fd_hash_t const *)empty_bytes; @@ -200,11 +225,19 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, ulong num_blockhashes = test_ctx->blockhash_queue_count; /* Blockhash queue init */ - slot_ctx->slot_bank.block_hash_queue.max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; - slot_ctx->slot_bank.block_hash_queue.ages_root = NULL; - uchar * pool_mem = fd_spad_alloc( runner->spad, fd_hash_hash_age_pair_t_map_align(), fd_hash_hash_age_pair_t_map_footprint( 400 ) ); - slot_ctx->slot_bank.block_hash_queue.ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( pool_mem, 400 ) ); - slot_ctx->slot_bank.block_hash_queue.last_hash = fd_spad_alloc( runner->spad, FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); + fd_block_hash_queue_global_t * block_hash_queue = fd_bank_mgr_block_hash_queue_modify( slot_ctx->bank_mgr ); + uchar * last_hash_mem = (uchar *)fd_ulong_align_up( (ulong)block_hash_queue + sizeof(fd_block_hash_queue_global_t), alignof(fd_hash_t) ); + uchar * ages_pool_mem = (uchar *)fd_ulong_align_up( (ulong)last_hash_mem + sizeof(fd_hash_t), fd_hash_hash_age_pair_t_map_align() ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join( fd_hash_hash_age_pair_t_map_new( ages_pool_mem, 400 ) ); + + block_hash_queue->max_age = FD_BLOCKHASH_QUEUE_MAX_ENTRIES; + block_hash_queue->ages_root_offset = 0UL; + block_hash_queue->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)block_hash_queue; + block_hash_queue->last_hash_index = 0UL; + block_hash_queue->last_hash_offset = (ulong)last_hash_mem - (ulong)block_hash_queue; + + fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); + // Save lamports per signature for most recent blockhash, if sysvar cache contains recent block hashes fd_recent_block_hashes_global_t const * rbh_global = fd_sysvar_cache_recent_block_hashes( slot_ctx->sysvar_cache, runner->wksp ); @@ -216,8 +249,13 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, if( rbh_global && !deq_fd_block_block_hash_entry_t_empty( rbh->hashes ) ) { fd_block_block_hash_entry_t const * last = deq_fd_block_block_hash_entry_t_peek_head_const( rbh->hashes ); if( last && last->fee_calculator.lamports_per_signature!=0UL ) { - slot_ctx->slot_bank.lamports_per_signature = last->fee_calculator.lamports_per_signature; - slot_ctx->prev_lamports_per_signature = last->fee_calculator.lamports_per_signature; + lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *lamports_per_signature = last->fee_calculator.lamports_per_signature; + fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); + + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); + *prev_lamports_per_signature = last->fee_calculator.lamports_per_signature; + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); } } @@ -230,7 +268,9 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, // Recent block hashes cap is 150 (actually 151), while blockhash queue capacity is 300 (actually 301) fd_block_block_hash_entry_t blockhash_entry; memcpy( &blockhash_entry.blockhash, test_ctx->blockhash_queue[i]->bytes, sizeof(fd_hash_t) ); - slot_ctx->slot_bank.poh = blockhash_entry.blockhash; + fd_hash_t * poh = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); + fd_memcpy( poh->hash, &blockhash_entry.blockhash, sizeof(fd_hash_t) ); + fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); fd_sysvar_recent_hashes_update( slot_ctx, runner->spad ); } } else { @@ -239,7 +279,9 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, memcpy( &epoch_bank->genesis_hash, empty_bytes, sizeof(fd_hash_t) ); fd_block_block_hash_entry_t blockhash_entry; memcpy( &blockhash_entry.blockhash, empty_bytes, sizeof(fd_hash_t) ); - slot_ctx->slot_bank.poh = blockhash_entry.blockhash; + fd_hash_t * poh = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); + fd_memcpy( poh->hash, &blockhash_entry.blockhash, sizeof(fd_hash_t) ); + fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); fd_sysvar_recent_hashes_update( slot_ctx, runner->spad ); } fd_sysvar_cache_restore_recent_block_hashes( slot_ctx->sysvar_cache, funk, funk_txn, runner->spad, fd_wksp_containing( slot_ctx ) ); @@ -297,9 +339,14 @@ fd_runtime_fuzz_txn_ctx_exec( fd_runtime_fuzz_runner_t * runner, task_info->exec_res = fd_execute_txn( task_info ); } - slot_ctx->slot_bank.collected_execution_fees += task_info->txn_ctx->execution_fee; - slot_ctx->slot_bank.collected_priority_fees += task_info->txn_ctx->priority_fee; - slot_ctx->slot_bank.collected_rent += task_info->txn_ctx->collected_rent; + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); + *execution_fees += task_info->txn_ctx->execution_fee; + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); + + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( slot_ctx->bank_mgr ); + *priority_fees += task_info->txn_ctx->priority_fee; + fd_bank_mgr_priority_fees_save( slot_ctx->bank_mgr ); + return task_info; } diff --git a/src/flamenco/snapshot/fd_snapshot.c b/src/flamenco/snapshot/fd_snapshot.c index 38fa0be739..01c545aec6 100644 --- a/src/flamenco/snapshot/fd_snapshot.c +++ b/src/flamenco/snapshot/fd_snapshot.c @@ -5,10 +5,11 @@ #include "../runtime/fd_hashes.h" #include "../runtime/fd_runtime_init.h" #include "../runtime/fd_system_ids.h" +#include "../runtime/fd_bank_mgr.h" +#include "../runtime/fd_runtime.h" #include "../runtime/context/fd_exec_epoch_ctx.h" #include "../runtime/context/fd_exec_slot_ctx.h" #include "../rewards/fd_rewards.h" -#include "../runtime/fd_runtime.h" #include #include @@ -40,7 +41,7 @@ struct fd_snapshot_load_ctx { typedef struct fd_snapshot_load_ctx fd_snapshot_load_ctx_t; static void -fd_hashes_load( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { +fd_hashes_load( fd_exec_slot_ctx_t * slot_ctx ) { FD_TXN_ACCOUNT_DECL( block_hashes_rec ); int err = fd_txn_account_init_from_funk_readonly( block_hashes_rec, &fd_sysvar_recent_block_hashes_id, slot_ctx->funk, slot_ctx->funk_txn ); @@ -48,20 +49,9 @@ fd_hashes_load( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { FD_LOG_ERR(( "missing recent block hashes account" )); } - /* FIXME: Do not hardcode the number of vote accounts */ - - slot_ctx->slot_bank.stake_account_keys.account_keys_root = NULL; - uchar * pool_mem = fd_spad_alloc( runtime_spad, fd_account_keys_pair_t_map_align(), fd_account_keys_pair_t_map_footprint( 100000UL ) ); - - slot_ctx->slot_bank.stake_account_keys.account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); - - slot_ctx->slot_bank.vote_account_keys.account_keys_root = NULL; - pool_mem = fd_spad_alloc( runtime_spad, fd_account_keys_pair_t_map_align(), fd_account_keys_pair_t_map_footprint( 100000UL ) ); - slot_ctx->slot_bank.vote_account_keys.account_keys_pool = fd_account_keys_pair_t_map_join( fd_account_keys_pair_t_map_new( pool_mem, 100000UL ) ); - - slot_ctx->slot_bank.collected_execution_fees = 0UL; - slot_ctx->slot_bank.collected_priority_fees = 0UL; - slot_ctx->slot_bank.collected_rent = 0UL; + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); + FD_STORE( ulong, execution_fees, 0UL ); + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); fd_runtime_save_slot_bank( slot_ctx ); fd_runtime_save_epoch_bank( slot_ctx ); @@ -152,8 +142,8 @@ fd_snapshot_load_init( fd_snapshot_load_ctx_t * ctx ) { // the hash in the incremental snapshot of an lt_hash contains all the accounts. This means we don't need a sub-txn for the incremental if( ctx->verify_hash && - (FD_FEATURE_ACTIVE( ctx->slot_ctx->slot_bank.slot, ctx->slot_ctx->epoch_ctx->features, incremental_snapshot_only_incremental_hash_calculation ) - && !FD_FEATURE_ACTIVE( ctx->slot_ctx->slot_bank.slot, ctx->slot_ctx->epoch_ctx->features, snapshots_lt_hash ) )) { + (FD_FEATURE_ACTIVE( ctx->slot_ctx->slot, ctx->slot_ctx->epoch_ctx->features, incremental_snapshot_only_incremental_hash_calculation ) + && !FD_FEATURE_ACTIVE( ctx->slot_ctx->slot, ctx->slot_ctx->epoch_ctx->features, snapshots_lt_hash ) )) { fd_funk_txn_xid_t xid; memset( &xid, 0xc3, sizeof(xid) ); fd_funk_txn_start_write( ctx->slot_ctx->funk ); @@ -207,7 +197,7 @@ fd_snapshot_load_manifest_and_status_cache( fd_snapshot_load_ctx_t * ctx, if( FD_UNLIKELY( !fd_snapshot_loader_init( ctx->loader, ctx->restore, src, - base_slot_override ? *base_slot_override : ctx->slot_ctx->slot_bank.slot, + base_slot_override ? *base_slot_override : ctx->slot_ctx->slot, 1 ) ) ) { FD_LOG_ERR(( "Failed to init snapshot loader" )); } @@ -259,9 +249,9 @@ fd_snapshot_load_fini( fd_snapshot_load_ctx_t * ctx ) { fd_features_restore( ctx->slot_ctx, ctx->runtime_spad ); fd_calculate_epoch_accounts_hash_values( ctx->slot_ctx ); - int snapshots_lt_hash = FD_FEATURE_ACTIVE( ctx->slot_ctx->slot_bank.slot, ctx->slot_ctx->epoch_ctx->features, snapshots_lt_hash ); - int accounts_lt_hash = FD_FEATURE_ACTIVE( ctx->slot_ctx->slot_bank.slot, ctx->slot_ctx->epoch_ctx->features, accounts_lt_hash ); - int incremental_snapshot_only_incremental_hash_calculation = FD_FEATURE_ACTIVE( ctx->slot_ctx->slot_bank.slot, ctx->slot_ctx->epoch_ctx->features, + int snapshots_lt_hash = FD_FEATURE_ACTIVE( ctx->slot_ctx->slot, ctx->slot_ctx->epoch_ctx->features, snapshots_lt_hash ); + int accounts_lt_hash = FD_FEATURE_ACTIVE( ctx->slot_ctx->slot, ctx->slot_ctx->epoch_ctx->features, accounts_lt_hash ); + int incremental_snapshot_only_incremental_hash_calculation = FD_FEATURE_ACTIVE( ctx->slot_ctx->slot, ctx->slot_ctx->epoch_ctx->features, incremental_snapshot_only_incremental_hash_calculation ); #ifdef FD_LTHASH_SNAPSHOT_HACK @@ -352,8 +342,8 @@ fd_snapshot_load_fini( fd_snapshot_load_ctx_t * ctx ) { } else { FD_LOG_ERR(( "invalid snapshot type %d", ctx->snapshot_type )); } - } + } if( ctx->child_txn != ctx->par_txn ) { fd_funk_txn_start_write( ctx->slot_ctx->funk ); fd_funk_txn_publish( ctx->slot_ctx->funk, ctx->child_txn, 0 ); @@ -361,7 +351,7 @@ fd_snapshot_load_fini( fd_snapshot_load_ctx_t * ctx ) { ctx->slot_ctx->funk_txn = ctx->par_txn; } - fd_hashes_load( ctx->slot_ctx, ctx->runtime_spad ); + fd_hashes_load( ctx->slot_ctx ); /* We don't need to free any of the loader memory since it is allocated from a spad. */ @@ -458,16 +448,20 @@ fd_snapshot_load_prefetch_manifest( fd_snapshot_load_ctx_t * ctx ) { static int fd_should_snapshot_include_epoch_accounts_hash(fd_exec_slot_ctx_t * slot_ctx) { - if( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, snapshots_lt_hash) ) + if( FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, snapshots_lt_hash ) ) { return 0; + } - fd_epoch_bank_t const * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_query( slot_ctx->bank_mgr ); + ulong * eah_end_slot = fd_bank_mgr_eah_stop_slot_query( slot_ctx->bank_mgr ); // We need to find the correct logic - if (epoch_bank->eah_start_slot != ULONG_MAX) + if( *eah_start_slot != ULONG_MAX ) { return 0; - if (epoch_bank->eah_stop_slot == ULONG_MAX) + } + if( *eah_end_slot == ULONG_MAX ) { return 0; + } return 1; } @@ -485,12 +479,14 @@ fd_snapshot_hash( fd_exec_slot_ctx_t * slot_ctx, fd_lthash_value_t * lt_hash ) { (void)check_hash; + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_query( slot_ctx->bank_mgr ); + if( fd_should_snapshot_include_epoch_accounts_hash( slot_ctx ) ) { FD_LOG_NOTICE(( "snapshot is including epoch account hash" )); fd_sha256_t h; fd_hash_t hash; fd_accounts_hash( slot_ctx->funk, - &slot_ctx->slot_bank, + slot_ctx->slot, &hash, runtime_spad, &slot_ctx->epoch_ctx->features, @@ -499,13 +495,13 @@ fd_snapshot_hash( fd_exec_slot_ctx_t * slot_ctx, fd_sha256_init( &h ); fd_sha256_append( &h, (uchar const *) hash.hash, sizeof( fd_hash_t ) ); - fd_sha256_append( &h, (uchar const *) slot_ctx->slot_bank.epoch_account_hash.hash, sizeof( fd_hash_t ) ); + fd_sha256_append( &h, (uchar const *) epoch_account_hash, sizeof( fd_hash_t ) ); fd_sha256_fini( &h, accounts_hash ); return 0; } return fd_accounts_hash( slot_ctx->funk, - &slot_ctx->slot_bank, + slot_ctx->slot, accounts_hash, runtime_spad, &slot_ctx->epoch_ctx->features, @@ -530,7 +526,7 @@ fd_snapshot_inc_hash( fd_exec_slot_ctx_t * slot_ctx, fd_sha256_init( &h ); fd_sha256_append( &h, (uchar const *) hash.hash, sizeof( fd_hash_t ) ); - fd_sha256_append( &h, (uchar const *) slot_ctx->slot_bank.epoch_account_hash.hash, sizeof( fd_hash_t ) ); + //fd_sha256_append( &h, (uchar const *) slot_ctx->slot_bank.epoch_account_hash.hash, sizeof( fd_hash_t ) ); fd_sha256_fini( &h, accounts_hash ); return 0; diff --git a/src/flamenco/snapshot/fd_snapshot_create.c b/src/flamenco/snapshot/fd_snapshot_create.c index e62a231d9c..0515f008cd 100644 --- a/src/flamenco/snapshot/fd_snapshot_create.c +++ b/src/flamenco/snapshot/fd_snapshot_create.c @@ -608,23 +608,22 @@ fd_snapshot_create_populate_bank( fd_snapshot_ctx_t * snapshot_ctx, As a note, the size is 300 but in fact is of size 301 due to a knwon bug in the agave client that is emulated by the firedancer client. */ - bank->blockhash_queue.last_hash_index = slot_bank->block_hash_queue.last_hash_index; - bank->blockhash_queue.last_hash = fd_spad_alloc( snapshot_ctx->spad, FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); - *bank->blockhash_queue.last_hash = *slot_bank->block_hash_queue.last_hash; - - bank->blockhash_queue.ages_len = fd_hash_hash_age_pair_t_map_size( slot_bank->block_hash_queue.ages_pool, slot_bank->block_hash_queue.ages_root); - bank->blockhash_queue.ages = fd_spad_alloc( snapshot_ctx->spad, FD_HASH_HASH_AGE_PAIR_ALIGN, bank->blockhash_queue.ages_len * sizeof(fd_hash_hash_age_pair_t) ); - bank->blockhash_queue.max_age = FD_BLOCKHASH_QUEUE_SIZE; - - fd_block_hash_queue_t * queue = &slot_bank->block_hash_queue; - fd_hash_hash_age_pair_t_mapnode_t * nn = NULL; - ulong blockhash_queue_idx = 0UL; - for( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( queue->ages_pool, queue->ages_root ); n; n = nn ) { - nn = fd_hash_hash_age_pair_t_map_successor( queue->ages_pool, n ); - bank->blockhash_queue.ages[ blockhash_queue_idx++ ] = n->elem; - } - - + /* TODO: This needs to be converted to a global blockhash queue. */ + // bank->blockhash_queue.last_hash_index = slot_bank->block_hash_queue.last_hash_index; + // bank->blockhash_queue.last_hash = fd_spad_alloc( snapshot_ctx->spad, FD_HASH_ALIGN, FD_HASH_FOOTPRINT ); + // fd_memcpy( bank->blockhash_queue.last_hash, slot_bank->block_hash_queue.last_hash, sizeof(fd_hash_t) ); + + // bank->blockhash_queue.ages_len = fd_hash_hash_age_pair_t_map_size( slot_bank->block_hash_queue.ages_pool, slot_bank->block_hash_queue.ages_root); + // bank->blockhash_queue.ages = fd_spad_alloc( snapshot_ctx->spad, FD_HASH_HASH_AGE_PAIR_ALIGN, bank->blockhash_queue.ages_len * sizeof(fd_hash_hash_age_pair_t) ); + // bank->blockhash_queue.max_age = FD_BLOCKHASH_QUEUE_SIZE; + + // fd_block_hash_queue_t * queue = &slot_bank->block_hash_queue; + // fd_hash_hash_age_pair_t_mapnode_t * nn = NULL; + // ulong blockhash_queue_idx = 0UL; + // for( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( queue->ages_pool, queue->ages_root ); n; n = nn ) { + // nn = fd_hash_hash_age_pair_t_map_successor( queue->ages_pool, n ); + // fd_memcpy( &bank->blockhash_queue.ages[ blockhash_queue_idx++ ], &n->elem, sizeof(fd_hash_hash_age_pair_t) ); + // } /* Ancestor can be omitted to boot off of for both clients */ @@ -634,22 +633,22 @@ fd_snapshot_create_populate_bank( fd_snapshot_ctx_t * snapshot_ctx, bank->hash = slot_bank->banks_hash; bank->parent_hash = slot_bank->prev_banks_hash; bank->parent_slot = slot_bank->prev_slot; - bank->hard_forks = slot_bank->hard_forks; - bank->transaction_count = slot_bank->transaction_count; - bank->signature_count = slot_bank->parent_signature_cnt; - bank->capitalization = slot_bank->capitalization; - bank->tick_height = slot_bank->tick_height; - bank->max_tick_height = slot_bank->max_tick_height; + // bank->hard_forks = slot_bank->hard_forks; + // bank->transaction_count = slot_bank->transaction_count; + // bank->signature_count = slot_bank->parent_signature_cnt; + // bank->capitalization = slot_bank->capitalization; + // bank->tick_height = slot_bank->tick_height; + // bank->max_tick_height = slot_bank->max_tick_height; /* The hashes_per_tick needs to be copied over from the epoch bank because the pointer could go out of bounds during an epoch boundary. */ - bank->hashes_per_tick = fd_spad_alloc( snapshot_ctx->spad, alignof(ulong), sizeof(ulong) ); - *bank->hashes_per_tick = epoch_bank->hashes_per_tick; + // bank->hashes_per_tick = fd_spad_alloc( snapshot_ctx->spad, alignof(ulong), sizeof(ulong) ); + // *bank->hashes_per_tick = epoch_bank->hashes_per_tick; bank->ticks_per_slot = FD_TICKS_PER_SLOT; - bank->ns_per_slot = epoch_bank->ns_per_slot; - bank->genesis_creation_time = epoch_bank->genesis_creation_time; - bank->slots_per_year = epoch_bank->slots_per_year; + // bank->ns_per_slot = epoch_bank->ns_per_slot; + // bank->genesis_creation_time = epoch_bank->genesis_creation_time; + // bank->slots_per_year = epoch_bank->slots_per_year; /* This value can be set to 0 because the Agave client recomputes this value and the firedancer client doesn't use it. */ @@ -658,24 +657,24 @@ fd_snapshot_create_populate_bank( fd_snapshot_ctx_t * snapshot_ctx, bank->slot = snapshot_ctx->slot; bank->epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, bank->slot, NULL ); - bank->block_height = slot_bank->block_height; + // bank->block_height = slot_bank->block_height; /* Collector id can be left as null for both clients */ fd_memset( &bank->collector_id, 0, sizeof(fd_pubkey_t) ); - bank->collector_fees = slot_bank->collected_execution_fees + slot_bank->collected_priority_fees; - bank->fee_calculator.lamports_per_signature = slot_bank->lamports_per_signature; - bank->fee_rate_governor = slot_bank->fee_rate_governor; - bank->collected_rent = slot_bank->collected_rent; + // bank->collector_fees = slot_bank->collected_execution_fees + slot_bank->collected_priority_fees; + // bank->fee_calculator.lamports_per_signature = slot_bank->lamports_per_signature; + // bank->fee_rate_governor = slot_bank->fee_rate_governor; + bank->collected_rent = 0UL; bank->rent_collector.epoch = bank->epoch; bank->rent_collector.epoch_schedule = epoch_bank->rent_epoch_schedule; - bank->rent_collector.slots_per_year = epoch_bank->slots_per_year; + // bank->rent_collector.slots_per_year = epoch_bank->slots_per_year; bank->rent_collector.rent = epoch_bank->rent; bank->epoch_schedule = epoch_bank->epoch_schedule; - bank->inflation = epoch_bank->inflation; + // bank->inflation = epoch_bank->inflation; /* Unused accounts can be left as NULL for both clients. */ @@ -786,10 +785,10 @@ fd_snapshot_create_setup_and_validate_ctx( fd_snapshot_ctx_t * snapshot_ctx ) { FD_LOG_ERR(( "Snapshot directory is not set" )); } - if( FD_UNLIKELY( snapshot_ctx->slot>snapshot_ctx->slot_bank.slot ) ) { - FD_LOG_ERR(( "Snapshot slot=%lu is greater than the current slot=%lu", - snapshot_ctx->slot, snapshot_ctx->slot_bank.slot )); - } + // if( FD_UNLIKELY( snapshot_ctx->slot>snapshot_ctx->slot_bank.slot ) ) { + // FD_LOG_ERR(( "Snapshot slot=%lu is greater than the current slot=%lu", + // snapshot_ctx->slot, snapshot_ctx->slot_bank.slot )); + // } /* Truncate the two files used for snapshot creation and seek to its start. */ @@ -897,6 +896,7 @@ fd_snapshot_create_write_manifest_and_acc_vecs( fd_snapshot_ctx_t * snapshot_ctx fd_hash_t * out_hash, ulong * out_capitalization ) { + (void)out_capitalization; fd_solana_manifest_t manifest = {0}; @@ -906,8 +906,8 @@ fd_snapshot_create_write_manifest_and_acc_vecs( fd_snapshot_ctx_t * snapshot_ctx /* Populate the rest of the manifest, except for the append vec index. */ - manifest.lamports_per_signature = snapshot_ctx->slot_bank.lamports_per_signature; - manifest.epoch_account_hash = &snapshot_ctx->slot_bank.epoch_account_hash; + // manifest.lamports_per_signature = snapshot_ctx->slot_bank.lamports_per_signature; + // manifest.epoch_account_hash = &snapshot_ctx->slot_bank.epoch_account_hash; /* FIXME: The versioned epoch stakes needs to be implemented. Right now if we try to create a snapshot on or near an epoch boundary, we will produce @@ -933,7 +933,7 @@ fd_snapshot_create_write_manifest_and_acc_vecs( fd_snapshot_ctx_t * snapshot_ctx manifest.bank_incremental_snapshot_persistence->incremental_capitalization = incr_capitalization; } else { *out_hash = manifest.accounts_db.bank_hash_info.accounts_hash; - *out_capitalization = snapshot_ctx->slot_bank.capitalization; + //*out_capitalization = snapshot_ctx->slot_bank.capitalization; } /* At this point, all of the account files are written out and the append diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index 64209d64f1..dc3277b400 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -1,5 +1,6 @@ #include "fd_stakes.h" #include "../runtime/fd_system_ids.h" +#include "../runtime/fd_bank_mgr.h" #include "../runtime/context/fd_exec_epoch_ctx.h" #include "../runtime/context/fd_exec_slot_ctx.h" #include "../runtime/program/fd_stake_program.h" @@ -294,13 +295,18 @@ fd_refresh_vote_accounts( fd_exec_slot_ctx_t * slot_ctx, ulong exec_spad_cnt, fd_spad_t * runtime_spad ) { - fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); fd_stakes_t * stakes = &epoch_bank->stakes; + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_query( slot_ctx->bank_mgr ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); + fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); + + ulong vote_account_keys_map_sz = !!vote_account_keys_pool ? fd_account_keys_pair_t_map_size( vote_account_keys_pool, vote_account_keys_root ) : 0UL; + ulong vote_accounts_stakes_map_sz = fd_vote_accounts_pair_t_map_size( stakes->vote_accounts.vote_accounts_pool, stakes->vote_accounts.vote_accounts_root ); + // Initialize a temporary vote states cache - ulong vote_states_pool_sz = fd_vote_accounts_pair_t_map_size( stakes->vote_accounts.vote_accounts_pool, stakes->vote_accounts.vote_accounts_root ) - + fd_account_keys_pair_t_map_size( slot_bank->vote_account_keys.account_keys_pool, slot_bank->vote_account_keys.account_keys_root ); + ulong vote_states_pool_sz = vote_accounts_stakes_map_sz + vote_account_keys_map_sz; temp_info->vote_states_root = NULL; uchar * pool_mem = fd_spad_alloc( runtime_spad, fd_vote_info_pair_t_map_align(), fd_vote_info_pair_t_map_footprint( vote_states_pool_sz ) ); temp_info->vote_states_pool = fd_vote_info_pair_t_map_join( fd_vote_info_pair_t_map_new( pool_mem, vote_states_pool_sz ) ); @@ -321,9 +327,9 @@ fd_refresh_vote_accounts( fd_exec_slot_ctx_t * slot_ctx, fd_stake_weight_t_map_insert( pool, &root, entry ); } - for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( slot_bank->vote_account_keys.account_keys_pool, slot_bank->vote_account_keys.account_keys_root ); + for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( vote_account_keys_pool, vote_account_keys_root ); n; - n = fd_account_keys_pair_t_map_successor( slot_bank->vote_account_keys.account_keys_pool, n ) ) { + n = fd_account_keys_pair_t_map_successor( vote_account_keys_pool, n ) ) { fd_stake_weight_t_mapnode_t temp; temp.elem.key = n->elem.key; fd_stake_weight_t_mapnode_t * entry = fd_stake_weight_t_map_find( pool, root, &temp ); @@ -381,9 +387,9 @@ fd_refresh_vote_accounts( fd_exec_slot_ctx_t * slot_ctx, } // Update the epoch stakes cache with new vote accounts from the epoch - for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( slot_bank->vote_account_keys.account_keys_pool, slot_bank->vote_account_keys.account_keys_root ); + for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( vote_account_keys_pool, vote_account_keys_root ); n; - n = fd_account_keys_pair_t_map_successor( slot_bank->vote_account_keys.account_keys_pool, n ) ) { + n = fd_account_keys_pair_t_map_successor( vote_account_keys_pool, n ) ) { fd_pubkey_t const * vote_account_pubkey = &n->elem.key; fd_vote_accounts_pair_t_mapnode_t key; @@ -419,10 +425,19 @@ fd_refresh_vote_accounts( fd_exec_slot_ctx_t * slot_ctx, fd_vote_info_pair_t_map_insert( temp_info->vote_states_pool, &temp_info->vote_states_root, new_vote_state_node ); } - slot_ctx->epoch_ctx->total_epoch_stake = total_epoch_stake; - - fd_account_keys_pair_t_map_release_tree( slot_bank->vote_account_keys.account_keys_pool, slot_bank->vote_account_keys.account_keys_root ); - slot_bank->vote_account_keys.account_keys_root = NULL; + ulong * total_epoch_stake_bm = NULL; + FD_BANK_MGR_MODIFY_BEGIN( slot_ctx->bank_mgr, total_epoch_stake, total_epoch_stake_bm ) { + FD_STORE( ulong, total_epoch_stake_bm, total_epoch_stake ); + } FD_BANK_MGR_MODIFY_END; + + FD_BANK_MGR_MODIFY_BEGIN( slot_ctx->bank_mgr, vote_account_keys, vote_account_keys ) { + vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); + vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); + fd_account_keys_pair_t_map_release_tree( vote_account_keys_pool, vote_account_keys_root ); + vote_account_keys_root = NULL; + fd_account_keys_account_keys_pool_update( vote_account_keys, vote_account_keys_pool ); + fd_account_keys_account_keys_root_update( vote_account_keys, vote_account_keys_root ); + } FD_BANK_MGR_MODIFY_END; } static void @@ -582,11 +597,14 @@ fd_accumulate_stake_infos( fd_exec_slot_ctx_t const * slot_ctx, } temp_info->stake_infos_new_keys_start_idx = temp_info->stake_infos_len; + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_query( slot_ctx->bank_mgr ); + fd_account_keys_pair_t_mapnode_t * account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); + fd_account_keys_pair_t_mapnode_t * account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); /* The number of account keys aggregated across the epoch is usually small, so there aren't much performance gains from tpooling here. */ - for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, slot_ctx->slot_bank.stake_account_keys.account_keys_root ); + for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( account_keys_pool, account_keys_root ); n; - n = fd_account_keys_pair_t_map_successor( slot_ctx->slot_bank.stake_account_keys.account_keys_pool, n ) ) { + n = fd_account_keys_pair_t_map_successor( account_keys_pool, n ) ) { FD_TXN_ACCOUNT_DECL( acc ); int rc = fd_txn_account_init_from_funk_readonly(acc, &n->elem.key, slot_ctx->funk, slot_ctx->funk_txn ); if( FD_UNLIKELY( rc!=FD_ACC_MGR_SUCCESS || acc->vt->get_lamports( acc )==0UL ) ) { @@ -631,6 +649,16 @@ fd_stakes_activate_epoch( fd_exec_slot_ctx_t * slot_ctx, fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); fd_stakes_t * stakes = &epoch_bank->stakes; + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_query( slot_ctx->bank_mgr ); + + fd_account_keys_pair_t_mapnode_t * account_keys_pool = NULL; + fd_account_keys_pair_t_mapnode_t * account_keys_root = NULL; + + if( stake_account_keys ) { + account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); + account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); + } + /* Current stake delegations: list of all current delegations in stake_delegations https://github.com/solana-labs/solana/blob/88aeaa82a856fc807234e7da0b31b89f2dc0e091/runtime/src/stakes.rs#L180 */ /* Add a new entry to the Stake History sysvar for the previous epoch @@ -647,8 +675,10 @@ fd_stakes_activate_epoch( fd_exec_slot_ctx_t * slot_ctx, ulong stake_delegations_size = fd_delegation_pair_t_map_size( stakes->stake_delegations_pool, stakes->stake_delegations_root ); - stake_delegations_size += fd_account_keys_pair_t_map_size( - slot_ctx->slot_bank.stake_account_keys.account_keys_pool, slot_ctx->slot_bank.stake_account_keys.account_keys_root ); + + stake_delegations_size += !!account_keys_pool ? fd_account_keys_pair_t_map_size( + account_keys_pool, account_keys_root ) : 0UL; + temp_info->stake_infos_len = 0UL; temp_info->stake_infos = (fd_epoch_info_pair_t *)fd_spad_alloc( runtime_spad, FD_EPOCH_INFO_PAIR_ALIGN, sizeof(fd_epoch_info_pair_t)*stake_delegations_size ); fd_memset( temp_info->stake_infos, 0, sizeof(fd_epoch_info_pair_t)*stake_delegations_size ); diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index e42c965361..56f488be55 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -1564,8 +1564,6 @@ void *fd_firedancer_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) self->slot = fd_rng_ulong( rng ); self->prev_slot = fd_rng_ulong( rng ); fd_hash_generate( &self->poh, alloc_mem, rng ); - fd_hash_generate( &self->banks_hash, alloc_mem, rng ); - fd_fee_rate_governor_generate( &self->fee_rate_governor, alloc_mem, rng ); self->capitalization = fd_rng_ulong( rng ); self->block_height = fd_rng_ulong( rng ); self->lamports_per_signature = fd_rng_ulong( rng ); @@ -1622,26 +1620,24 @@ void *fd_rent_fresh_accounts_generate( void *mem, void **alloc_mem, fd_rng_t * r return mem; } +void *fd_cluster_version_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { + fd_cluster_version_t *self = (fd_cluster_version_t *) mem; + *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_cluster_version_t); + fd_cluster_version_new(mem); + self->major = fd_rng_uint( rng ); + self->minor = fd_rng_uint( rng ); + self->patch = fd_rng_uint( rng ); + return mem; +} + void *fd_epoch_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_epoch_bank_t *self = (fd_epoch_bank_t *) mem; *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_epoch_bank_t); fd_epoch_bank_new(mem); fd_stakes_generate( &self->stakes, alloc_mem, rng ); - self->hashes_per_tick = fd_rng_ulong( rng ); - self->ticks_per_slot = fd_rng_ulong( rng ); - self->ns_per_slot = fd_rng_uint128( rng ); - self->genesis_creation_time = fd_rng_ulong( rng ); - self->slots_per_year = fd_rng_double_o( rng ); - self->max_tick_height = fd_rng_ulong( rng ); - fd_inflation_generate( &self->inflation, alloc_mem, rng ); fd_epoch_schedule_generate( &self->epoch_schedule, alloc_mem, rng ); fd_rent_generate( &self->rent, alloc_mem, rng ); - self->eah_start_slot = fd_rng_ulong( rng ); - self->eah_stop_slot = fd_rng_ulong( rng ); - self->eah_interval = fd_rng_ulong( rng ); fd_hash_generate( &self->genesis_hash, alloc_mem, rng ); - self->cluster_type = fd_rng_uint( rng ); - LLVMFuzzerMutate( (uchar *)self->cluster_version, sizeof(uint)*3, sizeof(uint)*3 ); fd_vote_accounts_generate( &self->next_epoch_stakes, alloc_mem, rng ); fd_epoch_schedule_generate( &self->rent_epoch_schedule, alloc_mem, rng ); return mem; @@ -1829,38 +1825,11 @@ void *fd_slot_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_slot_bank_t *self = (fd_slot_bank_t *) mem; *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_slot_bank_t); fd_slot_bank_new(mem); - fd_clock_timestamp_votes_generate( &self->timestamp_votes, alloc_mem, rng ); - self->slot = fd_rng_ulong( rng ); self->prev_slot = fd_rng_ulong( rng ); - fd_hash_generate( &self->poh, alloc_mem, rng ); fd_hash_generate( &self->banks_hash, alloc_mem, rng ); - fd_hash_generate( &self->epoch_account_hash, alloc_mem, rng ); - fd_fee_rate_governor_generate( &self->fee_rate_governor, alloc_mem, rng ); - self->capitalization = fd_rng_ulong( rng ); - self->block_height = fd_rng_ulong( rng ); - self->max_tick_height = fd_rng_ulong( rng ); - self->collected_execution_fees = fd_rng_ulong( rng ); - self->collected_priority_fees = fd_rng_ulong( rng ); - self->collected_rent = fd_rng_ulong( rng ); fd_vote_accounts_generate( &self->epoch_stakes, alloc_mem, rng ); - fd_sol_sysvar_last_restart_slot_generate( &self->last_restart_slot, alloc_mem, rng ); - fd_account_keys_generate( &self->stake_account_keys, alloc_mem, rng ); - fd_account_keys_generate( &self->vote_account_keys, alloc_mem, rng ); - self->lamports_per_signature = fd_rng_ulong( rng ); - self->transaction_count = fd_rng_ulong( rng ); fd_slot_lthash_generate( &self->lthash, alloc_mem, rng ); - fd_block_hash_queue_generate( &self->block_hash_queue, alloc_mem, rng ); fd_hash_generate( &self->prev_banks_hash, alloc_mem, rng ); - self->parent_signature_cnt = fd_rng_ulong( rng ); - self->tick_height = fd_rng_ulong( rng ); - { - self->has_use_preceeding_epoch_stakes = fd_rng_uchar( rng ) % 2; - if( self->has_use_preceeding_epoch_stakes ) { - LLVMFuzzerMutate( (uchar *)&(self->use_preceeding_epoch_stakes), sizeof(ulong), sizeof(ulong) ); - } - } - fd_hard_forks_generate( &self->hard_forks, alloc_mem, rng ); - fd_rent_fresh_accounts_generate( &self->rent_fresh_accounts, alloc_mem, rng ); fd_epoch_reward_status_generate( &self->epoch_reward_status, alloc_mem, rng ); return mem; } diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index 36b573dff0..3e228fd97a 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -461,6 +461,39 @@ int fd_block_hash_queue_encode( fd_block_hash_queue_t const * self, fd_bincode_e if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; } +int fd_block_hash_queue_encode_global( fd_block_hash_queue_global_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->last_hash_index, ctx ); + if( FD_UNLIKELY( err ) ) return err; + if( self->last_hash_offset ) { + err = fd_bincode_bool_encode( 1, ctx ); + if( FD_UNLIKELY( err ) ) return err; + fd_hash_t * last_hash = (void *)((uchar*)self + self->last_hash_offset); + err = fd_hash_encode( last_hash, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } else { + err = fd_bincode_bool_encode( 0, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_hash_hash_age_pair_t_map_join( (uchar *)self + self->ages_root_offset ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join( (uchar *)self + self->ages_pool_offset ); + if( ages_root ) { + ulong ages_len = fd_hash_hash_age_pair_t_map_size( ages_pool, ages_root ); + err = fd_bincode_uint64_encode( ages_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( fd_hash_hash_age_pair_t_mapnode_t * n = fd_hash_hash_age_pair_t_map_minimum( ages_pool, ages_root ); n; n = fd_hash_hash_age_pair_t_map_successor( ages_pool, n ) ) { + err = fd_hash_hash_age_pair_encode( &n->elem, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } else { + ulong ages_len = 0; + err = fd_bincode_uint64_encode( ages_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + err = fd_bincode_uint64_encode( self->max_age, ctx ); + if( FD_UNLIKELY( err ) ) return err; + return FD_BINCODE_SUCCESS; +} static int fd_block_hash_queue_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; @@ -533,6 +566,45 @@ void * fd_block_hash_queue_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { fd_block_hash_queue_decode_inner( mem, alloc_mem, ctx ); return self; } +static void fd_block_hash_queue_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { + fd_block_hash_queue_global_t * self = (fd_block_hash_queue_global_t *)struct_mem; + fd_bincode_uint64_decode_unsafe( &self->last_hash_index, ctx ); + { + uchar o; + fd_bincode_bool_decode_unsafe( &o, ctx ); + if( o ) { + *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, FD_HASH_ALIGN ); + self->last_hash_offset = (ulong)*alloc_mem - (ulong)struct_mem; + fd_hash_new( *alloc_mem ); + *alloc_mem = (uchar *)*alloc_mem + sizeof(fd_hash_t); + fd_hash_decode_inner( (uchar*)self + self->last_hash_offset, alloc_mem, ctx ); + } else { + self->last_hash_offset = 0UL; + } + } + ulong ages_len; + fd_bincode_uint64_decode_unsafe( &ages_len, ctx ); + *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_hash_hash_age_pair_t_map_align() ); + fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_hash_hash_age_pair_t_map_join_new( alloc_mem, fd_ulong_max( ages_len, 400 ) ); + fd_hash_hash_age_pair_t_mapnode_t * ages_root = NULL; + for( ulong i=0; i < ages_len; i++ ) { + fd_hash_hash_age_pair_t_mapnode_t * node = fd_hash_hash_age_pair_t_map_acquire( ages_pool ); + fd_hash_hash_age_pair_new( (fd_hash_hash_age_pair_t *)fd_type_pun(&node->elem) ); + fd_hash_hash_age_pair_decode_inner( &node->elem, alloc_mem, ctx ); + fd_hash_hash_age_pair_t_map_insert( ages_pool, &ages_root, node ); + } + self->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)struct_mem; + self->ages_root_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_root ) - (ulong)struct_mem; + fd_bincode_uint64_decode_unsafe( &self->max_age, ctx ); +} +void * fd_block_hash_queue_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { + fd_block_hash_queue_global_t * self = (fd_block_hash_queue_global_t *)mem; + fd_block_hash_queue_new( (fd_block_hash_queue_t *)self ); + void * alloc_region = (uchar *)mem + sizeof(fd_block_hash_queue_global_t); + void * * alloc_mem = &alloc_region; + fd_block_hash_queue_decode_inner_global( mem, alloc_mem, ctx ); + return self; +} void fd_block_hash_queue_new(fd_block_hash_queue_t * self) { fd_memset( self, 0, sizeof(fd_block_hash_queue_t) ); } @@ -1562,6 +1634,25 @@ int fd_account_keys_encode( fd_account_keys_t const * self, fd_bincode_encode_ct } return FD_BINCODE_SUCCESS; } +int fd_account_keys_encode_global( fd_account_keys_global_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + fd_account_keys_pair_t_mapnode_t * account_keys_root = fd_account_keys_pair_t_map_join( (uchar *)self + self->account_keys_root_offset ); + fd_account_keys_pair_t_mapnode_t * account_keys_pool = fd_account_keys_pair_t_map_join( (uchar *)self + self->account_keys_pool_offset ); + if( account_keys_root ) { + ulong account_keys_len = fd_account_keys_pair_t_map_size( account_keys_pool, account_keys_root ); + err = fd_bincode_uint64_encode( account_keys_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( fd_account_keys_pair_t_mapnode_t * n = fd_account_keys_pair_t_map_minimum( account_keys_pool, account_keys_root ); n; n = fd_account_keys_pair_t_map_successor( account_keys_pool, n ) ) { + err = fd_account_keys_pair_encode( &n->elem, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } else { + ulong account_keys_len = 0; + err = fd_bincode_uint64_encode( account_keys_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + return FD_BINCODE_SUCCESS; +} static int fd_account_keys_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; @@ -1605,6 +1696,30 @@ void * fd_account_keys_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { fd_account_keys_decode_inner( mem, alloc_mem, ctx ); return self; } +static void fd_account_keys_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { + fd_account_keys_global_t * self = (fd_account_keys_global_t *)struct_mem; + ulong account_keys_len; + fd_bincode_uint64_decode_unsafe( &account_keys_len, ctx ); + *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_account_keys_pair_t_map_align() ); + fd_account_keys_pair_t_mapnode_t * account_keys_pool = fd_account_keys_pair_t_map_join_new( alloc_mem, fd_ulong_max( account_keys_len, 100000 ) ); + fd_account_keys_pair_t_mapnode_t * account_keys_root = NULL; + for( ulong i=0; i < account_keys_len; i++ ) { + fd_account_keys_pair_t_mapnode_t * node = fd_account_keys_pair_t_map_acquire( account_keys_pool ); + fd_account_keys_pair_new( (fd_account_keys_pair_t *)fd_type_pun(&node->elem) ); + fd_account_keys_pair_decode_inner( &node->elem, alloc_mem, ctx ); + fd_account_keys_pair_t_map_insert( account_keys_pool, &account_keys_root, node ); + } + self->account_keys_pool_offset = (ulong)fd_account_keys_pair_t_map_leave( account_keys_pool ) - (ulong)struct_mem; + self->account_keys_root_offset = (ulong)fd_account_keys_pair_t_map_leave( account_keys_root ) - (ulong)struct_mem; +} +void * fd_account_keys_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { + fd_account_keys_global_t * self = (fd_account_keys_global_t *)mem; + fd_account_keys_new( (fd_account_keys_t *)self ); + void * alloc_region = (uchar *)mem + sizeof(fd_account_keys_global_t); + void * * alloc_mem = &alloc_region; + fd_account_keys_decode_inner_global( mem, alloc_mem, ctx ); + return self; +} void fd_account_keys_new(fd_account_keys_t * self) { fd_memset( self, 0, sizeof(fd_account_keys_t) ); } @@ -7805,6 +7920,25 @@ int fd_clock_timestamp_votes_encode( fd_clock_timestamp_votes_t const * self, fd } return FD_BINCODE_SUCCESS; } +int fd_clock_timestamp_votes_encode_global( fd_clock_timestamp_votes_global_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + fd_clock_timestamp_vote_t_mapnode_t * votes_root = fd_clock_timestamp_vote_t_map_join( (uchar *)self + self->votes_root_offset ); + fd_clock_timestamp_vote_t_mapnode_t * votes_pool = fd_clock_timestamp_vote_t_map_join( (uchar *)self + self->votes_pool_offset ); + if( votes_root ) { + ulong votes_len = fd_clock_timestamp_vote_t_map_size( votes_pool, votes_root ); + err = fd_bincode_uint64_encode( votes_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + for( fd_clock_timestamp_vote_t_mapnode_t * n = fd_clock_timestamp_vote_t_map_minimum( votes_pool, votes_root ); n; n = fd_clock_timestamp_vote_t_map_successor( votes_pool, n ) ) { + err = fd_clock_timestamp_vote_encode( &n->elem, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } else { + ulong votes_len = 0; + err = fd_bincode_uint64_encode( votes_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + return FD_BINCODE_SUCCESS; +} static int fd_clock_timestamp_votes_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; @@ -7848,6 +7982,30 @@ void * fd_clock_timestamp_votes_decode( void * mem, fd_bincode_decode_ctx_t * ct fd_clock_timestamp_votes_decode_inner( mem, alloc_mem, ctx ); return self; } +static void fd_clock_timestamp_votes_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { + fd_clock_timestamp_votes_global_t * self = (fd_clock_timestamp_votes_global_t *)struct_mem; + ulong votes_len; + fd_bincode_uint64_decode_unsafe( &votes_len, ctx ); + *alloc_mem = (void*)fd_ulong_align_up( (ulong)*alloc_mem, fd_clock_timestamp_vote_t_map_align() ); + fd_clock_timestamp_vote_t_mapnode_t * votes_pool = fd_clock_timestamp_vote_t_map_join_new( alloc_mem, fd_ulong_max( votes_len, 15000 ) ); + fd_clock_timestamp_vote_t_mapnode_t * votes_root = NULL; + for( ulong i=0; i < votes_len; i++ ) { + fd_clock_timestamp_vote_t_mapnode_t * node = fd_clock_timestamp_vote_t_map_acquire( votes_pool ); + fd_clock_timestamp_vote_new( (fd_clock_timestamp_vote_t *)fd_type_pun(&node->elem) ); + fd_clock_timestamp_vote_decode_inner( &node->elem, alloc_mem, ctx ); + fd_clock_timestamp_vote_t_map_insert( votes_pool, &votes_root, node ); + } + self->votes_pool_offset = (ulong)fd_clock_timestamp_vote_t_map_leave( votes_pool ) - (ulong)struct_mem; + self->votes_root_offset = (ulong)fd_clock_timestamp_vote_t_map_leave( votes_root ) - (ulong)struct_mem; +} +void * fd_clock_timestamp_votes_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { + fd_clock_timestamp_votes_global_t * self = (fd_clock_timestamp_votes_global_t *)mem; + fd_clock_timestamp_votes_new( (fd_clock_timestamp_votes_t *)self ); + void * alloc_region = (uchar *)mem + sizeof(fd_clock_timestamp_votes_global_t); + void * * alloc_mem = &alloc_region; + fd_clock_timestamp_votes_decode_inner_global( mem, alloc_mem, ctx ); + return self; +} void fd_clock_timestamp_votes_new(fd_clock_timestamp_votes_t * self) { fd_memset( self, 0, sizeof(fd_clock_timestamp_votes_t) ); } @@ -8249,10 +8407,6 @@ int fd_firedancer_bank_encode( fd_firedancer_bank_t const * self, fd_bincode_enc if( FD_UNLIKELY( err ) ) return err; err = fd_hash_encode( &self->poh, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_encode( &self->banks_hash, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_fee_rate_governor_encode( &self->fee_rate_governor, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_encode( self->capitalization, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_encode( self->block_height, ctx ); @@ -8302,10 +8456,6 @@ static int fd_firedancer_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_hash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_fee_rate_governor_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_decode_footprint( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_bincode_uint64_decode_footprint( ctx ); @@ -8356,8 +8506,6 @@ static void fd_firedancer_bank_decode_inner( void * struct_mem, void * * alloc_m fd_bincode_uint64_decode_unsafe( &self->slot, ctx ); fd_bincode_uint64_decode_unsafe( &self->prev_slot, ctx ); fd_hash_decode_inner( &self->poh, alloc_mem, ctx ); - fd_hash_decode_inner( &self->banks_hash, alloc_mem, ctx ); - fd_fee_rate_governor_decode_inner( &self->fee_rate_governor, alloc_mem, ctx ); fd_bincode_uint64_decode_unsafe( &self->capitalization, ctx ); fd_bincode_uint64_decode_unsafe( &self->block_height, ctx ); fd_bincode_uint64_decode_unsafe( &self->lamports_per_signature, ctx ); @@ -8389,8 +8537,6 @@ void fd_firedancer_bank_new(fd_firedancer_bank_t * self) { fd_recent_block_hashes_new( &self->recent_block_hashes ); fd_clock_timestamp_votes_new( &self->timestamp_votes ); fd_hash_new( &self->poh ); - fd_hash_new( &self->banks_hash ); - fd_fee_rate_governor_new( &self->fee_rate_governor ); fd_inflation_new( &self->inflation ); fd_epoch_schedule_new( &self->epoch_schedule ); fd_rent_new( &self->rent ); @@ -8405,8 +8551,6 @@ void fd_firedancer_bank_walk( void * w, fd_firedancer_bank_t const * self, fd_ty fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fun( w, &self->prev_slot, "prev_slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fd_hash_walk( w, &self->poh, fun, "poh", level ); - fd_hash_walk( w, &self->banks_hash, fun, "banks_hash", level ); - fd_fee_rate_governor_walk( w, &self->fee_rate_governor, fun, "fee_rate_governor", level ); fun( w, &self->capitalization, "capitalization", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fun( w, &self->block_height, "block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fun( w, &self->lamports_per_signature, "lamports_per_signature", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); @@ -8433,8 +8577,6 @@ ulong fd_firedancer_bank_size( fd_firedancer_bank_t const * self ) { size += sizeof(ulong); size += sizeof(ulong); size += fd_hash_size( &self->poh ); - size += fd_hash_size( &self->banks_hash ); - size += fd_fee_rate_governor_size( &self->fee_rate_governor ); size += sizeof(ulong); size += sizeof(ulong); size += sizeof(ulong); @@ -8606,6 +8748,22 @@ int fd_rent_fresh_accounts_encode( fd_rent_fresh_accounts_t const * self, fd_bin } return FD_BINCODE_SUCCESS; } +int fd_rent_fresh_accounts_encode_global( fd_rent_fresh_accounts_global_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_bincode_uint64_encode( self->total_count, ctx ); + if( FD_UNLIKELY( err ) ) return err; + err = fd_bincode_uint64_encode( self->fresh_accounts_len, ctx ); + if( FD_UNLIKELY( err ) ) return err; + if( self->fresh_accounts_len ) { + uchar * fresh_accounts_laddr = (uchar*)self + self->fresh_accounts_offset; + fd_rent_fresh_account_t * fresh_accounts = (fd_rent_fresh_account_t *)fresh_accounts_laddr; + for( ulong i=0; i < self->fresh_accounts_len; i++ ) { + err = fd_rent_fresh_account_encode( &fresh_accounts[i], ctx ); + if( FD_UNLIKELY( err ) ) return err; + } + } + return FD_BINCODE_SUCCESS; +} static int fd_rent_fresh_accounts_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; @@ -8654,6 +8812,31 @@ void * fd_rent_fresh_accounts_decode( void * mem, fd_bincode_decode_ctx_t * ctx fd_rent_fresh_accounts_decode_inner( mem, alloc_mem, ctx ); return self; } +static void fd_rent_fresh_accounts_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { + fd_rent_fresh_accounts_global_t * self = (fd_rent_fresh_accounts_global_t *)struct_mem; + fd_bincode_uint64_decode_unsafe( &self->total_count, ctx ); + fd_bincode_uint64_decode_unsafe( &self->fresh_accounts_len, ctx ); + if( self->fresh_accounts_len ) { + *alloc_mem = (void*)fd_ulong_align_up( (ulong)(*alloc_mem), FD_RENT_FRESH_ACCOUNT_ALIGN ); + self->fresh_accounts_offset = (ulong)*alloc_mem - (ulong)struct_mem; + uchar * cur_mem = (uchar *)(*alloc_mem); + *alloc_mem = (uchar *)(*alloc_mem) + sizeof(fd_rent_fresh_account_t)*self->fresh_accounts_len; + for( ulong i=0; i < self->fresh_accounts_len; i++ ) { + fd_rent_fresh_account_new( (fd_rent_fresh_account_t *)fd_type_pun(cur_mem + sizeof(fd_rent_fresh_account_t) * i) ); + fd_rent_fresh_account_decode_inner( cur_mem + sizeof(fd_rent_fresh_account_t) * i, alloc_mem, ctx ); + } + } else { + self->fresh_accounts_offset = 0UL; + } +} +void * fd_rent_fresh_accounts_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) { + fd_rent_fresh_accounts_global_t * self = (fd_rent_fresh_accounts_global_t *)mem; + fd_rent_fresh_accounts_new( (fd_rent_fresh_accounts_t *)self ); + void * alloc_region = (uchar *)mem + sizeof(fd_rent_fresh_accounts_global_t); + void * * alloc_mem = &alloc_region; + fd_rent_fresh_accounts_decode_inner_global( mem, alloc_mem, ctx ); + return self; +} void fd_rent_fresh_accounts_new(fd_rent_fresh_accounts_t * self) { fd_memset( self, 0, sizeof(fd_rent_fresh_accounts_t) ); } @@ -8679,42 +8862,60 @@ ulong fd_rent_fresh_accounts_size( fd_rent_fresh_accounts_t const * self ) { return size; } -int fd_epoch_bank_encode( fd_epoch_bank_t const * self, fd_bincode_encode_ctx_t * ctx ) { +int fd_cluster_version_encode( fd_cluster_version_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_stakes_encode( &self->stakes, ctx ); + err = fd_bincode_uint32_encode( self->major, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->hashes_per_tick, ctx ); + err = fd_bincode_uint32_encode( self->minor, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->ticks_per_slot, ctx ); + err = fd_bincode_uint32_encode( self->patch, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint128_encode( self->ns_per_slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->genesis_creation_time, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_double_encode( self->slots_per_year, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->max_tick_height, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_inflation_encode( &self->inflation, ctx ); + return FD_BINCODE_SUCCESS; +} +static inline int fd_cluster_version_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { + if( (ulong)ctx->data + 12UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; + ctx->data = (void *)( (ulong)ctx->data + 12UL ); + return 0; +} +static void fd_cluster_version_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { + fd_cluster_version_t * self = (fd_cluster_version_t *)struct_mem; + fd_bincode_uint32_decode_unsafe( &self->major, ctx ); + fd_bincode_uint32_decode_unsafe( &self->minor, ctx ); + fd_bincode_uint32_decode_unsafe( &self->patch, ctx ); +} +void * fd_cluster_version_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { + fd_cluster_version_t * self = (fd_cluster_version_t *)mem; + fd_cluster_version_new( self ); + void * alloc_region = (uchar *)mem + sizeof(fd_cluster_version_t); + void * * alloc_mem = &alloc_region; + fd_cluster_version_decode_inner( mem, alloc_mem, ctx ); + return self; +} +void fd_cluster_version_walk( void * w, fd_cluster_version_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { + fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_cluster_version", level++ ); + fun( w, &self->major, "major", FD_FLAMENCO_TYPE_UINT, "uint", level ); + fun( w, &self->minor, "minor", FD_FLAMENCO_TYPE_UINT, "uint", level ); + fun( w, &self->patch, "patch", FD_FLAMENCO_TYPE_UINT, "uint", level ); + fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_cluster_version", level-- ); +} +ulong fd_cluster_version_size( fd_cluster_version_t const * self ) { + ulong size = 0; + size += sizeof(uint); + size += sizeof(uint); + size += sizeof(uint); + return size; +} + +int fd_epoch_bank_encode( fd_epoch_bank_t const * self, fd_bincode_encode_ctx_t * ctx ) { + int err; + err = fd_stakes_encode( &self->stakes, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_schedule_encode( &self->epoch_schedule, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_rent_encode( &self->rent, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->eah_start_slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->eah_stop_slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->eah_interval, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_hash_encode( &self->genesis_hash, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint32_encode( self->cluster_type, ctx ); - if( FD_UNLIKELY( err ) ) return err; - for( ulong i=0; i<3; i++ ) { - err = fd_bincode_uint32_encode( self->cluster_version[i], ctx ); - if( FD_UNLIKELY( err ) ) return err; - } err = fd_vote_accounts_encode( &self->next_epoch_stakes, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_schedule_encode( &self->rent_epoch_schedule, ctx ); @@ -8726,38 +8927,12 @@ static int fd_epoch_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, int err = 0; err = fd_stakes_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint128_decode_footprint( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_double_decode_footprint( ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_inflation_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_schedule_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; err = fd_rent_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_hash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint32_decode_footprint( ctx ); - if( FD_UNLIKELY( err ) ) return err; - for( ulong i=0; i<3; i++ ) { - err = fd_bincode_uint32_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } err = fd_vote_accounts_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_schedule_decode_footprint_inner( ctx, total_sz ); @@ -8775,23 +8950,9 @@ int fd_epoch_bank_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total static void fd_epoch_bank_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { fd_epoch_bank_t * self = (fd_epoch_bank_t *)struct_mem; fd_stakes_decode_inner( &self->stakes, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->hashes_per_tick, ctx ); - fd_bincode_uint64_decode_unsafe( &self->ticks_per_slot, ctx ); - fd_bincode_uint128_decode_unsafe( &self->ns_per_slot, ctx ); - fd_bincode_uint64_decode_unsafe( &self->genesis_creation_time, ctx ); - fd_bincode_double_decode_unsafe( &self->slots_per_year, ctx ); - fd_bincode_uint64_decode_unsafe( &self->max_tick_height, ctx ); - fd_inflation_decode_inner( &self->inflation, alloc_mem, ctx ); fd_epoch_schedule_decode_inner( &self->epoch_schedule, alloc_mem, ctx ); fd_rent_decode_inner( &self->rent, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->eah_start_slot, ctx ); - fd_bincode_uint64_decode_unsafe( &self->eah_stop_slot, ctx ); - fd_bincode_uint64_decode_unsafe( &self->eah_interval, ctx ); fd_hash_decode_inner( &self->genesis_hash, alloc_mem, ctx ); - fd_bincode_uint32_decode_unsafe( &self->cluster_type, ctx ); - for( ulong i=0; i<3; i++ ) { - fd_bincode_uint32_decode_unsafe( self->cluster_version + i, ctx ); - } fd_vote_accounts_decode_inner( &self->next_epoch_stakes, alloc_mem, ctx ); fd_epoch_schedule_decode_inner( &self->rent_epoch_schedule, alloc_mem, ctx ); } @@ -8806,7 +8967,6 @@ void * fd_epoch_bank_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { void fd_epoch_bank_new(fd_epoch_bank_t * self) { fd_memset( self, 0, sizeof(fd_epoch_bank_t) ); fd_stakes_new( &self->stakes ); - fd_inflation_new( &self->inflation ); fd_epoch_schedule_new( &self->epoch_schedule ); fd_rent_new( &self->rent ); fd_hash_new( &self->genesis_hash ); @@ -8816,24 +8976,9 @@ void fd_epoch_bank_new(fd_epoch_bank_t * self) { void fd_epoch_bank_walk( void * w, fd_epoch_bank_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_epoch_bank", level++ ); fd_stakes_walk( w, &self->stakes, fun, "stakes", level ); - fun( w, &self->hashes_per_tick, "hashes_per_tick", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->ticks_per_slot, "ticks_per_slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->ns_per_slot, "ns_per_slot", FD_FLAMENCO_TYPE_UINT128, "uint128", level ); - fun( w, &self->genesis_creation_time, "genesis_creation_time", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->slots_per_year, "slots_per_year", FD_FLAMENCO_TYPE_DOUBLE, "double", level ); - fun( w, &self->max_tick_height, "max_tick_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fd_inflation_walk( w, &self->inflation, fun, "inflation", level ); fd_epoch_schedule_walk( w, &self->epoch_schedule, fun, "epoch_schedule", level ); fd_rent_walk( w, &self->rent, fun, "rent", level ); - fun( w, &self->eah_start_slot, "eah_start_slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->eah_stop_slot, "eah_stop_slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->eah_interval, "eah_interval", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fd_hash_walk( w, &self->genesis_hash, fun, "genesis_hash", level ); - fun( w, &self->cluster_type, "cluster_type", FD_FLAMENCO_TYPE_UINT, "uint", level ); - fun( w, NULL, "cluster_version", FD_FLAMENCO_TYPE_ARR, "uint[]", level++ ); - for( ulong i=0; i<3; i++ ) - fun( w, self->cluster_version + i, "cluster_version", FD_FLAMENCO_TYPE_UINT, "uint", level ); - fun( w, NULL, "cluster_version", FD_FLAMENCO_TYPE_ARR_END, "uint[]", level-- ); fd_vote_accounts_walk( w, &self->next_epoch_stakes, fun, "next_epoch_stakes", level ); fd_epoch_schedule_walk( w, &self->rent_epoch_schedule, fun, "rent_epoch_schedule", level ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_epoch_bank", level-- ); @@ -8841,21 +8986,9 @@ void fd_epoch_bank_walk( void * w, fd_epoch_bank_t const * self, fd_types_walk_f ulong fd_epoch_bank_size( fd_epoch_bank_t const * self ) { ulong size = 0; size += fd_stakes_size( &self->stakes ); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(uint128); - size += sizeof(ulong); - size += sizeof(double); - size += sizeof(ulong); - size += fd_inflation_size( &self->inflation ); size += fd_epoch_schedule_size( &self->epoch_schedule ); size += fd_rent_size( &self->rent ); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(ulong); size += fd_hash_size( &self->genesis_hash ); - size += sizeof(uint); - size += 3 * sizeof(uint); size += fd_vote_accounts_size( &self->next_epoch_stakes ); size += fd_epoch_schedule_size( &self->rent_epoch_schedule ); return size; @@ -9857,64 +9990,16 @@ int fd_epoch_reward_status_encode( fd_epoch_reward_status_t const * self, fd_bin int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_clock_timestamp_votes_encode( &self->timestamp_votes, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_encode( self->prev_slot, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_encode( &self->poh, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_hash_encode( &self->banks_hash, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_encode( &self->epoch_account_hash, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_fee_rate_governor_encode( &self->fee_rate_governor, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->capitalization, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->block_height, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->max_tick_height, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->collected_execution_fees, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->collected_priority_fees, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->collected_rent, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_encode( &self->epoch_stakes, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_sol_sysvar_last_restart_slot_encode( &self->last_restart_slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_account_keys_encode( &self->stake_account_keys, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_account_keys_encode( &self->vote_account_keys, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->lamports_per_signature, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->transaction_count, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_slot_lthash_encode( &self->lthash, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_block_hash_queue_encode( &self->block_hash_queue, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_hash_encode( &self->prev_banks_hash, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->parent_signature_cnt, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_encode( self->tick_height, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_bool_encode( self->has_use_preceeding_epoch_stakes, ctx ); - if( FD_UNLIKELY( err ) ) return err; - if( self->has_use_preceeding_epoch_stakes ) { - err = fd_bincode_uint64_encode( self->use_preceeding_epoch_stakes, ctx ); - if( FD_UNLIKELY( err ) ) return err; - } - err = fd_hard_forks_encode( &self->hard_forks, ctx ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_rent_fresh_accounts_encode( &self->rent_fresh_accounts, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_reward_status_encode( &self->epoch_reward_status, ctx ); if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; @@ -9922,67 +10007,16 @@ int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * static int fd_slot_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; - err = fd_clock_timestamp_votes_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_bincode_uint64_decode_footprint( ctx ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_hash_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_hash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_fee_rate_governor_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_vote_accounts_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_sol_sysvar_last_restart_slot_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_account_keys_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_account_keys_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_slot_lthash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_block_hash_queue_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_hash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - { - uchar o; - err = fd_bincode_bool_decode( &o, ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - if( o ) { - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; - } - } - err = fd_hard_forks_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; - err = fd_rent_fresh_accounts_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_reward_status_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; return 0; @@ -9997,40 +10031,11 @@ int fd_slot_bank_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_ } static void fd_slot_bank_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { fd_slot_bank_t * self = (fd_slot_bank_t *)struct_mem; - fd_clock_timestamp_votes_decode_inner( &self->timestamp_votes, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->slot, ctx ); fd_bincode_uint64_decode_unsafe( &self->prev_slot, ctx ); - fd_hash_decode_inner( &self->poh, alloc_mem, ctx ); fd_hash_decode_inner( &self->banks_hash, alloc_mem, ctx ); - fd_hash_decode_inner( &self->epoch_account_hash, alloc_mem, ctx ); - fd_fee_rate_governor_decode_inner( &self->fee_rate_governor, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->capitalization, ctx ); - fd_bincode_uint64_decode_unsafe( &self->block_height, ctx ); - fd_bincode_uint64_decode_unsafe( &self->max_tick_height, ctx ); - fd_bincode_uint64_decode_unsafe( &self->collected_execution_fees, ctx ); - fd_bincode_uint64_decode_unsafe( &self->collected_priority_fees, ctx ); - fd_bincode_uint64_decode_unsafe( &self->collected_rent, ctx ); fd_vote_accounts_decode_inner( &self->epoch_stakes, alloc_mem, ctx ); - fd_sol_sysvar_last_restart_slot_decode_inner( &self->last_restart_slot, alloc_mem, ctx ); - fd_account_keys_decode_inner( &self->stake_account_keys, alloc_mem, ctx ); - fd_account_keys_decode_inner( &self->vote_account_keys, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->lamports_per_signature, ctx ); - fd_bincode_uint64_decode_unsafe( &self->transaction_count, ctx ); fd_slot_lthash_decode_inner( &self->lthash, alloc_mem, ctx ); - fd_block_hash_queue_decode_inner( &self->block_hash_queue, alloc_mem, ctx ); fd_hash_decode_inner( &self->prev_banks_hash, alloc_mem, ctx ); - fd_bincode_uint64_decode_unsafe( &self->parent_signature_cnt, ctx ); - fd_bincode_uint64_decode_unsafe( &self->tick_height, ctx ); - { - uchar o; - fd_bincode_bool_decode_unsafe( &o, ctx ); - self->has_use_preceeding_epoch_stakes = !!o; - if( o ) { - fd_bincode_uint64_decode_unsafe( &self->use_preceeding_epoch_stakes, ctx ); - } - } - fd_hard_forks_decode_inner( &self->hard_forks, alloc_mem, ctx ); - fd_rent_fresh_accounts_decode_inner( &self->rent_fresh_accounts, alloc_mem, ctx ); fd_epoch_reward_status_decode_inner( &self->epoch_reward_status, alloc_mem, ctx ); } void * fd_slot_bank_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { @@ -10043,90 +10048,29 @@ void * fd_slot_bank_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { } void fd_slot_bank_new(fd_slot_bank_t * self) { fd_memset( self, 0, sizeof(fd_slot_bank_t) ); - fd_clock_timestamp_votes_new( &self->timestamp_votes ); - fd_hash_new( &self->poh ); fd_hash_new( &self->banks_hash ); - fd_hash_new( &self->epoch_account_hash ); - fd_fee_rate_governor_new( &self->fee_rate_governor ); fd_vote_accounts_new( &self->epoch_stakes ); - fd_sol_sysvar_last_restart_slot_new( &self->last_restart_slot ); - fd_account_keys_new( &self->stake_account_keys ); - fd_account_keys_new( &self->vote_account_keys ); fd_slot_lthash_new( &self->lthash ); - fd_block_hash_queue_new( &self->block_hash_queue ); fd_hash_new( &self->prev_banks_hash ); - fd_hard_forks_new( &self->hard_forks ); - fd_rent_fresh_accounts_new( &self->rent_fresh_accounts ); fd_epoch_reward_status_new( &self->epoch_reward_status ); } void fd_slot_bank_walk( void * w, fd_slot_bank_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_slot_bank", level++ ); - fd_clock_timestamp_votes_walk( w, &self->timestamp_votes, fun, "timestamp_votes", level ); - fun( w, &self->slot, "slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fun( w, &self->prev_slot, "prev_slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fd_hash_walk( w, &self->poh, fun, "poh", level ); fd_hash_walk( w, &self->banks_hash, fun, "banks_hash", level ); - fd_hash_walk( w, &self->epoch_account_hash, fun, "epoch_account_hash", level ); - fd_fee_rate_governor_walk( w, &self->fee_rate_governor, fun, "fee_rate_governor", level ); - fun( w, &self->capitalization, "capitalization", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->block_height, "block_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->max_tick_height, "max_tick_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->collected_execution_fees, "collected_execution_fees", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->collected_priority_fees, "collected_priority_fees", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->collected_rent, "collected_rent", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fd_vote_accounts_walk( w, &self->epoch_stakes, fun, "epoch_stakes", level ); - fd_sol_sysvar_last_restart_slot_walk( w, &self->last_restart_slot, fun, "last_restart_slot", level ); - fd_account_keys_walk( w, &self->stake_account_keys, fun, "stake_account_keys", level ); - fd_account_keys_walk( w, &self->vote_account_keys, fun, "vote_account_keys", level ); - fun( w, &self->lamports_per_signature, "lamports_per_signature", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->transaction_count, "transaction_count", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fd_slot_lthash_walk( w, &self->lthash, fun, "lthash", level ); - fd_block_hash_queue_walk( w, &self->block_hash_queue, fun, "block_hash_queue", level ); fd_hash_walk( w, &self->prev_banks_hash, fun, "prev_banks_hash", level ); - fun( w, &self->parent_signature_cnt, "parent_signature_cnt", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - fun( w, &self->tick_height, "tick_height", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - if( !self->has_use_preceeding_epoch_stakes ) { - fun( w, NULL, "use_preceeding_epoch_stakes", FD_FLAMENCO_TYPE_NULL, "ulong", level ); - } else { - fun( w, &self->use_preceeding_epoch_stakes, "use_preceeding_epoch_stakes", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); - } - fd_hard_forks_walk( w, &self->hard_forks, fun, "hard_forks", level ); - fd_rent_fresh_accounts_walk( w, &self->rent_fresh_accounts, fun, "rent_fresh_accounts", level ); fd_epoch_reward_status_walk( w, &self->epoch_reward_status, fun, "epoch_reward_status", level ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_slot_bank", level-- ); } ulong fd_slot_bank_size( fd_slot_bank_t const * self ) { ulong size = 0; - size += fd_clock_timestamp_votes_size( &self->timestamp_votes ); - size += sizeof(ulong); size += sizeof(ulong); - size += fd_hash_size( &self->poh ); size += fd_hash_size( &self->banks_hash ); - size += fd_hash_size( &self->epoch_account_hash ); - size += fd_fee_rate_governor_size( &self->fee_rate_governor ); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(ulong); size += fd_vote_accounts_size( &self->epoch_stakes ); - size += fd_sol_sysvar_last_restart_slot_size( &self->last_restart_slot ); - size += fd_account_keys_size( &self->stake_account_keys ); - size += fd_account_keys_size( &self->vote_account_keys ); - size += sizeof(ulong); - size += sizeof(ulong); size += fd_slot_lthash_size( &self->lthash ); - size += fd_block_hash_queue_size( &self->block_hash_queue ); size += fd_hash_size( &self->prev_banks_hash ); - size += sizeof(ulong); - size += sizeof(ulong); - size += sizeof(char); - if( self->has_use_preceeding_epoch_stakes ) { - size += sizeof(ulong); - } - size += fd_hard_forks_size( &self->hard_forks ); - size += fd_rent_fresh_accounts_size( &self->rent_fresh_accounts ); size += fd_epoch_reward_status_size( &self->epoch_reward_status ); return size; } diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index 9eabbee0cb..ae4b432ccd 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -83,6 +83,33 @@ struct fd_block_hash_queue { typedef struct fd_block_hash_queue fd_block_hash_queue_t; #define FD_BLOCK_HASH_QUEUE_ALIGN alignof(fd_block_hash_queue_t) +struct fd_block_hash_queue_global { + ulong last_hash_index; + ulong last_hash_offset; + ulong ages_pool_offset; + ulong ages_root_offset; + ulong max_age; +}; +typedef struct fd_block_hash_queue_global fd_block_hash_queue_global_t; +#define FD_BLOCK_HASH_QUEUE_GLOBAL_ALIGN alignof(fd_block_hash_queue_global_t) + +FD_FN_UNUSED static fd_hash_t * fd_block_hash_queue_last_hash_join( fd_block_hash_queue_global_t const * struct_mem ) { + return (fd_hash_t *)fd_type_pun( (uchar *)struct_mem + struct_mem->last_hash_offset ); +} +static FD_FN_UNUSED fd_hash_hash_age_pair_t_mapnode_t * fd_block_hash_queue_ages_pool_join( fd_block_hash_queue_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->ages_pool_offset ? (fd_hash_hash_age_pair_t_mapnode_t *)fd_hash_hash_age_pair_t_map_join( fd_type_pun( (uchar *)type + type->ages_pool_offset ) ) : NULL; +} +static FD_FN_UNUSED fd_hash_hash_age_pair_t_mapnode_t * fd_block_hash_queue_ages_root_join( fd_block_hash_queue_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->ages_root_offset ? (fd_hash_hash_age_pair_t_mapnode_t *)fd_type_pun( (uchar *)type + type->ages_root_offset ) : NULL; +} +static FD_FN_UNUSED void fd_block_hash_queue_ages_pool_update( fd_block_hash_queue_global_t * type, fd_hash_hash_age_pair_t_mapnode_t * pool ) { + type->ages_pool_offset = !!pool ? (ulong)fd_hash_hash_age_pair_t_map_leave( pool ) - (ulong)type : 0UL; +} +static FD_FN_UNUSED void fd_block_hash_queue_ages_root_update( fd_block_hash_queue_global_t * type, fd_hash_hash_age_pair_t_mapnode_t * root ) { + type->ages_root_offset = !!root ? (ulong)root - (ulong)type : 0UL; +} /* Encoded Size: Fixed (33 bytes) */ struct fd_fee_rate_governor { ulong target_lamports_per_signature; @@ -206,8 +233,11 @@ struct fd_solana_account_global { typedef struct fd_solana_account_global fd_solana_account_global_t; #define FD_SOLANA_ACCOUNT_GLOBAL_ALIGN alignof(fd_solana_account_global_t) -FD_FN_UNUSED static uchar * fd_solana_account_data_join( fd_solana_account_global_t * struct_mem ) { // vector - return (uchar *)fd_type_pun( (uchar *)struct_mem + struct_mem->data_offset ); +FD_FN_UNUSED static uchar * fd_solana_account_data_join( fd_solana_account_global_t const * struct_mem ) { // vector + return struct_mem->data_offset ? (uchar *)fd_type_pun( (uchar *)struct_mem + struct_mem->data_offset ) : NULL; +} +FD_FN_UNUSED static void fd_solana_account_data_update( fd_solana_account_global_t * struct_mem, uchar * vec ) { + struct_mem->data_offset = !!vec ? (ulong)vec - (ulong)struct_mem : 0UL; } /* Encoded Size: Fixed (48 bytes) */ struct __attribute__((packed)) fd_solana_account_stored_meta { @@ -323,11 +353,19 @@ struct fd_vote_accounts_global { typedef struct fd_vote_accounts_global fd_vote_accounts_global_t; #define FD_VOTE_ACCOUNTS_GLOBAL_ALIGN alignof(fd_vote_accounts_global_t) -static FD_FN_UNUSED fd_vote_accounts_pair_global_t_mapnode_t * fd_vote_accounts_vote_accounts_pool_join( void * struct_mem, ulong offset ) { // deque - return (fd_vote_accounts_pair_global_t_mapnode_t *)fd_vote_accounts_pair_global_t_map_join( fd_type_pun( (uchar *)struct_mem + offset ) ); +static FD_FN_UNUSED fd_vote_accounts_pair_global_t_mapnode_t * fd_vote_accounts_vote_accounts_pool_join( fd_vote_accounts_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->vote_accounts_pool_offset ? (fd_vote_accounts_pair_global_t_mapnode_t *)fd_vote_accounts_pair_global_t_map_join( fd_type_pun( (uchar *)type + type->vote_accounts_pool_offset ) ) : NULL; +} +static FD_FN_UNUSED fd_vote_accounts_pair_global_t_mapnode_t * fd_vote_accounts_vote_accounts_root_join( fd_vote_accounts_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->vote_accounts_root_offset ? (fd_vote_accounts_pair_global_t_mapnode_t *)fd_type_pun( (uchar *)type + type->vote_accounts_root_offset ) : NULL; +} +static FD_FN_UNUSED void fd_vote_accounts_vote_accounts_pool_update( fd_vote_accounts_global_t * type, fd_vote_accounts_pair_global_t_mapnode_t * pool ) { + type->vote_accounts_pool_offset = !!pool ? (ulong)fd_vote_accounts_pair_global_t_map_leave( pool ) - (ulong)type : 0UL; } -static FD_FN_UNUSED fd_vote_accounts_pair_global_t_mapnode_t * fd_vote_accounts_vote_accounts_root_join( void * struct_mem, ulong offset ) { // deque - return (fd_vote_accounts_pair_global_t_mapnode_t *)fd_type_pun( (uchar *)struct_mem + offset ); +static FD_FN_UNUSED void fd_vote_accounts_vote_accounts_root_update( fd_vote_accounts_global_t * type, fd_vote_accounts_pair_global_t_mapnode_t * root ) { + type->vote_accounts_root_offset = !!root ? (ulong)root - (ulong)type : 0UL; } /* Encoded Size: Fixed (33 bytes) */ struct fd_account_keys_pair { @@ -365,6 +403,27 @@ struct fd_account_keys { typedef struct fd_account_keys fd_account_keys_t; #define FD_ACCOUNT_KEYS_ALIGN alignof(fd_account_keys_t) +struct fd_account_keys_global { + ulong account_keys_pool_offset; + ulong account_keys_root_offset; +}; +typedef struct fd_account_keys_global fd_account_keys_global_t; +#define FD_ACCOUNT_KEYS_GLOBAL_ALIGN alignof(fd_account_keys_global_t) + +static FD_FN_UNUSED fd_account_keys_pair_t_mapnode_t * fd_account_keys_account_keys_pool_join( fd_account_keys_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->account_keys_pool_offset ? (fd_account_keys_pair_t_mapnode_t *)fd_account_keys_pair_t_map_join( fd_type_pun( (uchar *)type + type->account_keys_pool_offset ) ) : NULL; +} +static FD_FN_UNUSED fd_account_keys_pair_t_mapnode_t * fd_account_keys_account_keys_root_join( fd_account_keys_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->account_keys_root_offset ? (fd_account_keys_pair_t_mapnode_t *)fd_type_pun( (uchar *)type + type->account_keys_root_offset ) : NULL; +} +static FD_FN_UNUSED void fd_account_keys_account_keys_pool_update( fd_account_keys_global_t * type, fd_account_keys_pair_t_mapnode_t * pool ) { + type->account_keys_pool_offset = !!pool ? (ulong)fd_account_keys_pair_t_map_leave( pool ) - (ulong)type : 0UL; +} +static FD_FN_UNUSED void fd_account_keys_account_keys_root_update( fd_account_keys_global_t * type, fd_account_keys_pair_t_mapnode_t * root ) { + type->account_keys_root_offset = !!root ? (ulong)root - (ulong)type : 0UL; +} /* fd_stake_weight_t assigns an Ed25519 public key (node identity) a stake weight number measured in lamports */ /* Encoded Size: Fixed (40 bytes) */ struct fd_stake_weight { @@ -483,11 +542,19 @@ struct fd_stakes_global { typedef struct fd_stakes_global fd_stakes_global_t; #define FD_STAKES_GLOBAL_ALIGN alignof(fd_stakes_global_t) -static FD_FN_UNUSED fd_delegation_pair_t_mapnode_t * fd_stakes_stake_delegations_pool_join( void * struct_mem, ulong offset ) { // deque - return (fd_delegation_pair_t_mapnode_t *)fd_delegation_pair_t_map_join( fd_type_pun( (uchar *)struct_mem + offset ) ); +static FD_FN_UNUSED fd_delegation_pair_t_mapnode_t * fd_stakes_stake_delegations_pool_join( fd_stakes_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->stake_delegations_pool_offset ? (fd_delegation_pair_t_mapnode_t *)fd_delegation_pair_t_map_join( fd_type_pun( (uchar *)type + type->stake_delegations_pool_offset ) ) : NULL; +} +static FD_FN_UNUSED fd_delegation_pair_t_mapnode_t * fd_stakes_stake_delegations_root_join( fd_stakes_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->stake_delegations_root_offset ? (fd_delegation_pair_t_mapnode_t *)fd_type_pun( (uchar *)type + type->stake_delegations_root_offset ) : NULL; +} +static FD_FN_UNUSED void fd_stakes_stake_delegations_pool_update( fd_stakes_global_t * type, fd_delegation_pair_t_mapnode_t * pool ) { + type->stake_delegations_pool_offset = !!pool ? (ulong)fd_delegation_pair_t_map_leave( pool ) - (ulong)type : 0UL; } -static FD_FN_UNUSED fd_delegation_pair_t_mapnode_t * fd_stakes_stake_delegations_root_join( void * struct_mem, ulong offset ) { // deque - return (fd_delegation_pair_t_mapnode_t *)fd_type_pun( (uchar *)struct_mem + offset ); +static FD_FN_UNUSED void fd_stakes_stake_delegations_root_update( fd_stakes_global_t * type, fd_delegation_pair_t_mapnode_t * root ) { + type->stake_delegations_root_offset = !!root ? (ulong)root - (ulong)type : 0UL; } typedef struct fd_stake_pair_t_mapnode fd_stake_pair_t_mapnode_t; #define REDBLK_T fd_stake_pair_t_mapnode_t @@ -1235,8 +1302,8 @@ struct fd_slot_hashes_global { typedef struct fd_slot_hashes_global fd_slot_hashes_global_t; #define FD_SLOT_HASHES_GLOBAL_ALIGN alignof(fd_slot_hashes_global_t) -static FD_FN_UNUSED fd_slot_hash_t * fd_slot_hashes_hashes_join( void * struct_mem, ulong offset ) { // deque - return (fd_slot_hash_t *)deq_fd_slot_hash_t_join( fd_type_pun( (uchar *)struct_mem + offset ) ); +static FD_FN_UNUSED fd_slot_hash_t * fd_slot_hashes_hashes_join( fd_slot_hashes_global_t * type ) { // deque + return (fd_slot_hash_t *)deq_fd_slot_hash_t_join( fd_type_pun( (uchar *)type + type->hashes_offset ) ); } /* Encoded Size: Fixed (40 bytes) */ struct fd_block_block_hash_entry { @@ -1274,8 +1341,8 @@ struct fd_recent_block_hashes_global { typedef struct fd_recent_block_hashes_global fd_recent_block_hashes_global_t; #define FD_RECENT_BLOCK_HASHES_GLOBAL_ALIGN alignof(fd_recent_block_hashes_global_t) -static FD_FN_UNUSED fd_block_block_hash_entry_t * fd_recent_block_hashes_hashes_join( void * struct_mem, ulong offset ) { // deque - return (fd_block_block_hash_entry_t *)deq_fd_block_block_hash_entry_t_join( fd_type_pun( (uchar *)struct_mem + offset ) ); +static FD_FN_UNUSED fd_block_block_hash_entry_t * fd_recent_block_hashes_hashes_join( fd_recent_block_hashes_global_t * type ) { // deque + return (fd_block_block_hash_entry_t *)deq_fd_block_block_hash_entry_t_join( fd_type_pun( (uchar *)type + type->hashes_offset ) ); } /* Encoded Size: Dynamic */ struct fd_slot_meta { @@ -1333,6 +1400,27 @@ struct fd_clock_timestamp_votes { typedef struct fd_clock_timestamp_votes fd_clock_timestamp_votes_t; #define FD_CLOCK_TIMESTAMP_VOTES_ALIGN alignof(fd_clock_timestamp_votes_t) +struct fd_clock_timestamp_votes_global { + ulong votes_pool_offset; + ulong votes_root_offset; +}; +typedef struct fd_clock_timestamp_votes_global fd_clock_timestamp_votes_global_t; +#define FD_CLOCK_TIMESTAMP_VOTES_GLOBAL_ALIGN alignof(fd_clock_timestamp_votes_global_t) + +static FD_FN_UNUSED fd_clock_timestamp_vote_t_mapnode_t * fd_clock_timestamp_votes_votes_pool_join( fd_clock_timestamp_votes_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->votes_pool_offset ? (fd_clock_timestamp_vote_t_mapnode_t *)fd_clock_timestamp_vote_t_map_join( fd_type_pun( (uchar *)type + type->votes_pool_offset ) ) : NULL; +} +static FD_FN_UNUSED fd_clock_timestamp_vote_t_mapnode_t * fd_clock_timestamp_votes_votes_root_join( fd_clock_timestamp_votes_global_t const * type ) { + if( FD_UNLIKELY( !type ) ) return NULL; + return !!type->votes_root_offset ? (fd_clock_timestamp_vote_t_mapnode_t *)fd_type_pun( (uchar *)type + type->votes_root_offset ) : NULL; +} +static FD_FN_UNUSED void fd_clock_timestamp_votes_votes_pool_update( fd_clock_timestamp_votes_global_t * type, fd_clock_timestamp_vote_t_mapnode_t * pool ) { + type->votes_pool_offset = !!pool ? (ulong)fd_clock_timestamp_vote_t_map_leave( pool ) - (ulong)type : 0UL; +} +static FD_FN_UNUSED void fd_clock_timestamp_votes_votes_root_update( fd_clock_timestamp_votes_global_t * type, fd_clock_timestamp_vote_t_mapnode_t * root ) { + type->votes_root_offset = !!root ? (ulong)root - (ulong)type : 0UL; +} /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/sysvar/fees.rs#L21 */ /* Encoded Size: Fixed (8 bytes) */ struct fd_sysvar_fees { @@ -1392,8 +1480,6 @@ struct fd_firedancer_bank { ulong slot; ulong prev_slot; fd_hash_t poh; - fd_hash_t banks_hash; - fd_fee_rate_governor_t fee_rate_governor; ulong capitalization; ulong block_height; ulong lamports_per_signature; @@ -1438,24 +1524,35 @@ struct fd_rent_fresh_accounts { typedef struct fd_rent_fresh_accounts fd_rent_fresh_accounts_t; #define FD_RENT_FRESH_ACCOUNTS_ALIGN alignof(fd_rent_fresh_accounts_t) +struct fd_rent_fresh_accounts_global { + ulong total_count; + ulong fresh_accounts_len; + ulong fresh_accounts_offset; +}; +typedef struct fd_rent_fresh_accounts_global fd_rent_fresh_accounts_global_t; +#define FD_RENT_FRESH_ACCOUNTS_GLOBAL_ALIGN alignof(fd_rent_fresh_accounts_global_t) + +FD_FN_UNUSED static fd_rent_fresh_account_t * fd_rent_fresh_accounts_fresh_accounts_join( fd_rent_fresh_accounts_global_t const * struct_mem ) { // vector + return struct_mem->fresh_accounts_offset ? (fd_rent_fresh_account_t *)fd_type_pun( (uchar *)struct_mem + struct_mem->fresh_accounts_offset ) : NULL; +} +FD_FN_UNUSED static void fd_rent_fresh_accounts_fresh_accounts_update( fd_rent_fresh_accounts_global_t * struct_mem, fd_rent_fresh_account_t * vec ) { + struct_mem->fresh_accounts_offset = !!vec ? (ulong)vec - (ulong)struct_mem : 0UL; +} +/* Encoded Size: Fixed (12 bytes) */ +struct fd_cluster_version { + uint major; + uint minor; + uint patch; +}; +typedef struct fd_cluster_version fd_cluster_version_t; +#define FD_CLUSTER_VERSION_ALIGN alignof(fd_cluster_version_t) + /* Encoded Size: Dynamic */ struct fd_epoch_bank { fd_stakes_t stakes; - ulong hashes_per_tick; - ulong ticks_per_slot; - uint128 ns_per_slot; - ulong genesis_creation_time; - double slots_per_year; - ulong max_tick_height; - fd_inflation_t inflation; fd_epoch_schedule_t epoch_schedule; fd_rent_t rent; - ulong eah_start_slot; - ulong eah_stop_slot; - ulong eah_interval; fd_hash_t genesis_hash; - uint cluster_type; - uint cluster_version[3]; fd_vote_accounts_t next_epoch_stakes; fd_epoch_schedule_t rent_epoch_schedule; }; @@ -1668,34 +1765,11 @@ typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; /* Encoded Size: Dynamic */ struct fd_slot_bank { - fd_clock_timestamp_votes_t timestamp_votes; - ulong slot; ulong prev_slot; - fd_hash_t poh; fd_hash_t banks_hash; - fd_hash_t epoch_account_hash; - fd_fee_rate_governor_t fee_rate_governor; - ulong capitalization; - ulong block_height; - ulong max_tick_height; - ulong collected_execution_fees; - ulong collected_priority_fees; - ulong collected_rent; fd_vote_accounts_t epoch_stakes; - fd_sol_sysvar_last_restart_slot_t last_restart_slot; - fd_account_keys_t stake_account_keys; - fd_account_keys_t vote_account_keys; - ulong lamports_per_signature; - ulong transaction_count; fd_slot_lthash_t lthash; - fd_block_hash_queue_t block_hash_queue; fd_hash_t prev_banks_hash; - ulong parent_signature_cnt; - ulong tick_height; - ulong use_preceeding_epoch_stakes; - uchar has_use_preceeding_epoch_stakes; - fd_hard_forks_t hard_forks; - fd_rent_fresh_accounts_t rent_fresh_accounts; fd_epoch_reward_status_t epoch_reward_status; }; typedef struct fd_slot_bank fd_slot_bank_t; @@ -3309,6 +3383,8 @@ ulong fd_block_hash_queue_size( fd_block_hash_queue_t const * self ); static inline ulong fd_block_hash_queue_align( void ) { return FD_BLOCK_HASH_QUEUE_ALIGN; } int fd_block_hash_queue_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); void * fd_block_hash_queue_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); +void * fd_block_hash_queue_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); +int fd_block_hash_queue_encode_global( fd_block_hash_queue_global_t const * self, fd_bincode_encode_ctx_t * ctx ); static inline void fd_fee_rate_governor_new( fd_fee_rate_governor_t * self ) { fd_memset( self, 0, sizeof(fd_fee_rate_governor_t) ); } int fd_fee_rate_governor_encode( fd_fee_rate_governor_t const * self, fd_bincode_encode_ctx_t * ctx ); @@ -3463,6 +3539,8 @@ ulong fd_account_keys_size( fd_account_keys_t const * self ); static inline ulong fd_account_keys_align( void ) { return FD_ACCOUNT_KEYS_ALIGN; } int fd_account_keys_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); void * fd_account_keys_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); +void * fd_account_keys_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); +int fd_account_keys_encode_global( fd_account_keys_global_t const * self, fd_bincode_encode_ctx_t * ctx ); static inline void fd_stake_weight_new( fd_stake_weight_t * self ) { fd_memset( self, 0, sizeof(fd_stake_weight_t) ); } int fd_stake_weight_encode( fd_stake_weight_t const * self, fd_bincode_encode_ctx_t * ctx ); @@ -4132,6 +4210,8 @@ ulong fd_clock_timestamp_votes_size( fd_clock_timestamp_votes_t const * self ); static inline ulong fd_clock_timestamp_votes_align( void ) { return FD_CLOCK_TIMESTAMP_VOTES_ALIGN; } int fd_clock_timestamp_votes_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); void * fd_clock_timestamp_votes_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); +void * fd_clock_timestamp_votes_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); +int fd_clock_timestamp_votes_encode_global( fd_clock_timestamp_votes_global_t const * self, fd_bincode_encode_ctx_t * ctx ); static inline void fd_sysvar_fees_new( fd_sysvar_fees_t * self ) { fd_memset( self, 0, sizeof(fd_sysvar_fees_t) ); } int fd_sysvar_fees_encode( fd_sysvar_fees_t const * self, fd_bincode_encode_ctx_t * ctx ); @@ -4223,6 +4303,20 @@ ulong fd_rent_fresh_accounts_size( fd_rent_fresh_accounts_t const * self ); static inline ulong fd_rent_fresh_accounts_align( void ) { return FD_RENT_FRESH_ACCOUNTS_ALIGN; } int fd_rent_fresh_accounts_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ); void * fd_rent_fresh_accounts_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); +void * fd_rent_fresh_accounts_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ); +int fd_rent_fresh_accounts_encode_global( fd_rent_fresh_accounts_global_t const * self, fd_bincode_encode_ctx_t * ctx ); + +static inline void fd_cluster_version_new( fd_cluster_version_t * self ) { fd_memset( self, 0, sizeof(fd_cluster_version_t) ); } +int fd_cluster_version_encode( fd_cluster_version_t const * self, fd_bincode_encode_ctx_t * ctx ); +void fd_cluster_version_walk( void * w, fd_cluster_version_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ); +ulong fd_cluster_version_size( fd_cluster_version_t const * self ); +static inline ulong fd_cluster_version_align( void ) { return FD_CLUSTER_VERSION_ALIGN; } +static inline int fd_cluster_version_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { + *total_sz += sizeof(fd_cluster_version_t); + if( (ulong)ctx->data + 12UL > (ulong)ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; + return 0; +} +void * fd_cluster_version_decode( void * mem, fd_bincode_decode_ctx_t * ctx ); void fd_epoch_bank_new( fd_epoch_bank_t * self ); int fd_epoch_bank_encode( fd_epoch_bank_t const * self, fd_bincode_encode_ctx_t * ctx ); diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 6ca14f75be..01687262a3 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -81,6 +81,7 @@ { "name": "block_hash_queue", "type": "struct", + "global": true, "fields": [ { "name": "last_hash_index", "type": "ulong" }, { "name": "last_hash", "type": "option", "element": "hash" }, @@ -254,6 +255,7 @@ { "name": "vote_accounts", "type": "struct", + "global": true, "fields": [ { "name": "vote_accounts", "type": "map", "element": "vote_accounts_pair", "key": "key", "minalloc":15000 } ] @@ -269,6 +271,7 @@ { "name": "account_keys", "type": "struct", + "global": true, "fields": [ { "name": "account_keys", "type": "map", "element": "account_keys_pair", "key": "key", "minalloc":100000 } ] @@ -962,6 +965,7 @@ { "name": "clock_timestamp_votes", "type": "struct", + "global": true, "fields": [ { "name": "votes", "type": "map", "element": "clock_timestamp_vote", "key": "pubkey", "minalloc":15000 } ], @@ -1027,8 +1031,6 @@ { "name": "slot", "type": "ulong" }, { "name": "prev_slot", "type": "ulong" }, { "name": "poh", "type": "hash" }, - { "name": "banks_hash", "type": "hash" }, - { "name": "fee_rate_governor", "type": "fee_rate_governor" }, { "name": "capitalization", "type": "ulong" }, { "name": "block_height", "type": "ulong" }, { "name": "lamports_per_signature","type": "ulong" }, @@ -1069,32 +1071,31 @@ { "name": "rent_fresh_accounts", "type": "struct", + "global": true, "fields": [ { "name": "total_count", "type": "ulong" }, { "name": "fresh_accounts", "type": "vector", "element": "rent_fresh_account" } ] }, + { + "name": "cluster_version", + "type": "struct", + "global": true, + "fields": [ + { "name": "major", "type": "uint" }, + { "name": "minor", "type": "uint" }, + { "name": "patch", "type": "uint" } + ] + }, { "name": "epoch_bank", "type": "struct", "archival": "true", "fields": [ { "name": "stakes", "type": "stakes" }, - { "name": "hashes_per_tick", "type": "ulong" }, - { "name": "ticks_per_slot", "type": "ulong" }, - { "name": "ns_per_slot", "type": "uint128" }, - { "name": "genesis_creation_time", "type": "ulong" }, - { "name": "slots_per_year", "type": "double" }, - { "name": "max_tick_height", "type": "ulong" }, - { "name": "inflation", "type": "inflation" }, { "name": "epoch_schedule", "type": "epoch_schedule" }, { "name": "rent", "type": "rent" }, - { "name": "eah_start_slot", "type": "ulong" }, - { "name": "eah_stop_slot", "type": "ulong" }, - { "name": "eah_interval", "type": "ulong" }, { "name": "genesis_hash", "type": "hash" }, - { "name": "cluster_type", "type": "uint" }, - { "name": "cluster_version", "type": "array", "element": "uint", "length": 3 }, { "name": "next_epoch_stakes", "type": "vote_accounts"}, { "name": "rent_epoch_schedule", "type": "epoch_schedule" } ] @@ -1231,33 +1232,11 @@ "name": "slot_bank", "type": "struct", "fields": [ - { "name": "timestamp_votes", "type": "clock_timestamp_votes" }, - { "name": "slot", "type": "ulong" }, { "name": "prev_slot", "type": "ulong" }, - { "name": "poh", "type": "hash" }, { "name": "banks_hash", "type": "hash" }, - { "name": "epoch_account_hash", "type": "hash" }, - { "name": "fee_rate_governor", "type": "fee_rate_governor" }, - { "name": "capitalization", "type": "ulong" }, - { "name": "block_height", "type": "ulong" }, - { "name": "max_tick_height", "type": "ulong" }, - { "name": "collected_execution_fees", "type": "ulong" }, - { "name": "collected_priority_fees", "type": "ulong" }, - { "name": "collected_rent", "type": "ulong" }, { "name": "epoch_stakes", "type": "vote_accounts" }, - { "name": "last_restart_slot", "type": "sol_sysvar_last_restart_slot" }, - { "name": "stake_account_keys", "type": "account_keys"}, - { "name": "vote_account_keys", "type": "account_keys" }, - { "name": "lamports_per_signature", "type": "ulong" }, - { "name": "transaction_count", "type": "ulong" }, { "name": "lthash", "type": "slot_lthash" }, - { "name": "block_hash_queue", "type": "block_hash_queue" }, { "name": "prev_banks_hash", "type": "hash" }, - { "name": "parent_signature_cnt", "type": "ulong" }, - { "name": "tick_height", "type": "ulong" }, - { "name": "use_preceeding_epoch_stakes", "type": "option", "element": "ulong", "flat": true, "comment": "The epoch for which to use the immediately preceeding epoch's stakes for leader schedule calculation. This is necessary due to how Agave's stake caches interact when loading from snapshots." }, - { "name": "hard_forks", "type": "hard_forks" }, - { "name": "rent_fresh_accounts", "type": "rent_fresh_accounts", "comment": "TODO: remove this after disable_partitioned_rent_collection is activated everywhere." }, { "name": "epoch_reward_status", "type": "epoch_reward_status" } ] }, diff --git a/src/flamenco/types/fd_types_reflect_generated.c b/src/flamenco/types/fd_types_reflect_generated.c index 03cf503904..c13660e429 100644 --- a/src/flamenco/types/fd_types_reflect_generated.c +++ b/src/flamenco/types/fd_types_reflect_generated.c @@ -3,7 +3,7 @@ #include "fd_types_custom.h" #include "fd_types_reflect_private.h" #pragma GCC diagnostic ignored "-Wpedantic" -ulong fd_types_vt_list_cnt = 249; +ulong fd_types_vt_list_cnt = 250; fd_types_vt_t const fd_types_vt_list[] = { { .name="fd_hash", .name_len=7, .align=FD_HASH_ALIGN, .new_=(void *)fd_hash_new, .decode=(void *)fd_hash_decode, .size=(void *)fd_hash_size, .walk=(void *)fd_hash_walk, .decode_footprint=(void *)fd_hash_decode_footprint, .encode=(void *)fd_hash_encode }, { .name="fd_pubkey", .name_len=9, .align=FD_PUBKEY_ALIGN, .new_=(void *)fd_pubkey_new, .decode=(void *)fd_pubkey_decode, .size=(void *)fd_pubkey_size, .walk=(void *)fd_pubkey_walk, .decode_footprint=(void *)fd_pubkey_decode_footprint, .encode=(void *)fd_pubkey_encode }, @@ -106,6 +106,7 @@ fd_types_vt_t const fd_types_vt_list[] = { { .name="fd_cluster_type", .name_len=15, .align=FD_CLUSTER_TYPE_ALIGN, .new_=(void *)fd_cluster_type_new, .decode=(void *)fd_cluster_type_decode, .size=(void *)fd_cluster_type_size, .walk=(void *)fd_cluster_type_walk, .decode_footprint=(void *)fd_cluster_type_decode_footprint, .encode=(void *)fd_cluster_type_encode }, { .name="fd_rent_fresh_account", .name_len=21, .align=FD_RENT_FRESH_ACCOUNT_ALIGN, .new_=(void *)fd_rent_fresh_account_new, .decode=(void *)fd_rent_fresh_account_decode, .size=(void *)fd_rent_fresh_account_size, .walk=(void *)fd_rent_fresh_account_walk, .decode_footprint=(void *)fd_rent_fresh_account_decode_footprint, .encode=(void *)fd_rent_fresh_account_encode }, { .name="fd_rent_fresh_accounts", .name_len=22, .align=FD_RENT_FRESH_ACCOUNTS_ALIGN, .new_=(void *)fd_rent_fresh_accounts_new, .decode=(void *)fd_rent_fresh_accounts_decode, .size=(void *)fd_rent_fresh_accounts_size, .walk=(void *)fd_rent_fresh_accounts_walk, .decode_footprint=(void *)fd_rent_fresh_accounts_decode_footprint, .encode=(void *)fd_rent_fresh_accounts_encode }, + { .name="fd_cluster_version", .name_len=18, .align=FD_CLUSTER_VERSION_ALIGN, .new_=(void *)fd_cluster_version_new, .decode=(void *)fd_cluster_version_decode, .size=(void *)fd_cluster_version_size, .walk=(void *)fd_cluster_version_walk, .decode_footprint=(void *)fd_cluster_version_decode_footprint, .encode=(void *)fd_cluster_version_encode }, { .name="fd_epoch_bank", .name_len=13, .align=FD_EPOCH_BANK_ALIGN, .new_=(void *)fd_epoch_bank_new, .decode=(void *)fd_epoch_bank_decode, .size=(void *)fd_epoch_bank_size, .walk=(void *)fd_epoch_bank_walk, .decode_footprint=(void *)fd_epoch_bank_decode_footprint, .encode=(void *)fd_epoch_bank_encode }, { .name="fd_stake_reward", .name_len=15, .align=FD_STAKE_REWARD_ALIGN, .new_=(void *)fd_stake_reward_new, .decode=(void *)fd_stake_reward_decode, .size=(void *)fd_stake_reward_size, .walk=(void *)fd_stake_reward_walk, .decode_footprint=(void *)fd_stake_reward_decode_footprint, .encode=(void *)fd_stake_reward_encode }, { .name="fd_vote_reward", .name_len=14, .align=FD_VOTE_REWARD_ALIGN, .new_=(void *)fd_vote_reward_new, .decode=(void *)fd_vote_reward_decode, .size=(void *)fd_vote_reward_size, .walk=(void *)fd_vote_reward_walk, .decode_footprint=(void *)fd_vote_reward_decode_footprint, .encode=(void *)fd_vote_reward_encode }, diff --git a/src/flamenco/types/gen_stubs.py b/src/flamenco/types/gen_stubs.py index 0b47c474a1..f78992498f 100644 --- a/src/flamenco/types/gen_stubs.py +++ b/src/flamenco/types/gen_stubs.py @@ -504,10 +504,14 @@ def emitOffsetJoin(self, type_name): else: ret_type = f'{namespace}_{self.element}_global_t' - print(f'FD_FN_UNUSED static {ret_type} * {type_name}_{self.name}_join( {type_name}_global_t * struct_mem ) {{ // vector', file=header) - print(f' return ({ret_type} *)fd_type_pun( (uchar *)struct_mem + struct_mem->{self.name}_offset );', file=header) + print(f'FD_FN_UNUSED static {ret_type} * {type_name}_{self.name}_join( {type_name}_global_t const * struct_mem ) {{ // vector', file=header) + print(f' return struct_mem->{self.name}_offset ? ({ret_type} *)fd_type_pun( (uchar *)struct_mem + struct_mem->{self.name}_offset ) : NULL;', file=header) + print(f'}}', file=header) + print(f'FD_FN_UNUSED static void {type_name}_{self.name}_update( {type_name}_global_t * struct_mem, {ret_type} * vec ) {{', file=header) + print(f' struct_mem->{self.name}_offset = !!vec ? (ulong)vec - (ulong)struct_mem : 0UL;', file=header) print(f'}}', file=header) + def emitNew(self, indent=''): pass @@ -1173,8 +1177,8 @@ def emitOffsetJoin(self, type_name): prefix = self.prefix() if self.element in flattypes else self.prefix_global() - print(f'static FD_FN_UNUSED {ret_type} * {type_name}_{self.name}_join( void * struct_mem, ulong offset ) {{ // deque', file=header) - print(f' return ({ret_type} *){prefix}_join( fd_type_pun( (uchar *)struct_mem + offset ) );', file=header) + print(f'static FD_FN_UNUSED {ret_type} * {type_name}_{self.name}_join( {type_name}_global_t * type ) {{ // deque', file=header) + print(f' return ({ret_type} *){prefix}_join( fd_type_pun( (uchar *)type + type->{self.name}_offset ) );', file=header) print(f'}}', file=header) def emitNew(self, indent=''): @@ -1544,12 +1548,22 @@ def emitOffsetJoin(self, type_name): mapname = element_type + "_map" nodename = element_type + "_mapnode_t" - print(f'static FD_FN_UNUSED {nodename} * {type_name}_{self.name}_pool_join( void * struct_mem, ulong offset ) {{ // deque', file=header) - print(f' return ({nodename} *){mapname}_join( fd_type_pun( (uchar *)struct_mem + offset ) );', file=header) + print(f'static FD_FN_UNUSED {nodename} * {type_name}_{self.name}_pool_join( {type_name}_global_t const * type ) {{', file=header) + print(f' if( FD_UNLIKELY( !type ) ) return NULL;', file=header) + print(f' return !!type->{self.name}_pool_offset ? ({nodename} *){mapname}_join( fd_type_pun( (uchar *)type + type->{self.name}_pool_offset ) ) : NULL;', file=header) print(f'}}', file=header) - print(f'static FD_FN_UNUSED {nodename} * {type_name}_{self.name}_root_join( void * struct_mem, ulong offset ) {{ // deque', file=header) - print(f' return ({nodename} *)fd_type_pun( (uchar *)struct_mem + offset );', file=header) + print(f'static FD_FN_UNUSED {nodename} * {type_name}_{self.name}_root_join( {type_name}_global_t const * type ) {{', file=header) + print(f' if( FD_UNLIKELY( !type ) ) return NULL;', file=header) + print(f' return !!type->{self.name}_root_offset ? ({nodename} *)fd_type_pun( (uchar *)type + type->{self.name}_root_offset ) : NULL;', file=header) + print(f'}}', file=header) + + print(f'static FD_FN_UNUSED void {type_name}_{self.name}_pool_update( {type_name}_global_t * type, {nodename} * pool ) {{', file=header) + print(f' type->{self.name}_pool_offset = !!pool ? (ulong){mapname}_leave( pool ) - (ulong)type : 0UL;', file=header) + print(f'}}', file=header) + + print(f'static FD_FN_UNUSED void {type_name}_{self.name}_root_update( {type_name}_global_t * type, {nodename} * root ) {{', file=header) + print(f' type->{self.name}_root_offset = !!root ? (ulong)root - (ulong)type : 0UL;', file=header) print(f'}}', file=header) def emitNew(self, indent=''): @@ -2511,6 +2525,22 @@ def emitMemberGlobal(self): else: print(f' ulong {self.name}_offset;', file=header) + def emitOffsetJoin(self, type_name): + if self.flat: + return + + ret_type = None + if self.element in simpletypes: + ret_type = self.element + elif self.element in flattypes: + ret_type = f'{namespace}_{self.element}_t' + else: + ret_type = f'{namespace}_{self.element}_global_t' + + print(f'FD_FN_UNUSED static {ret_type} * {type_name}_{self.name}_join( {type_name}_global_t const * struct_mem ) {{', file=header) + print(f' return ({ret_type} *)fd_type_pun( (uchar *)struct_mem + struct_mem->{self.name}_offset );', file=header) + print(f'}}', file=header) + def emitNew(self, indent=''): pass diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c b/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c index 3d258a8a70..18bffbaee5 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c @@ -10,6 +10,7 @@ #include "../../runtime/context/fd_exec_txn_ctx.h" #include "../../runtime/context/fd_exec_instr_ctx.h" #include "../../runtime/fd_system_ids.h" +#include "../../runtime/fd_bank_mgr.h" int fd_vm_syscall_sol_get_clock_sysvar( /**/ void * _vm, @@ -276,7 +277,8 @@ fd_vm_syscall_sol_get_epoch_stake( /**/ void * _vm, FD_VM_CU_UPDATE( vm, FD_VM_SYSCALL_BASE_COST ); /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2074 */ - *_ret = vm->instr_ctx->txn_ctx->total_epoch_stake; + ulong * total_epoch_stake = fd_bank_mgr_total_epoch_stake_query( vm->instr_ctx->txn_ctx->bank_mgr ); + *_ret = !!total_epoch_stake ? *total_epoch_stake : 0UL; return FD_VM_SUCCESS; } diff --git a/src/flamenco/vm/test_vm_util.c b/src/flamenco/vm/test_vm_util.c index 917c72b2c4..7ddea3a8dc 100644 --- a/src/flamenco/vm/test_vm_util.c +++ b/src/flamenco/vm/test_vm_util.c @@ -30,14 +30,13 @@ test_vm_minimal_exec_instr_ctx( fd_valloc_t valloc, ctx->txn_ctx = txn_ctx; slot_ctx->epoch_ctx = epoch_ctx; - slot_ctx->slot_bank.slot = 1UL; + slot_ctx->slot = 1UL; /* Setup feature flags */ fd_features_disable_all( &epoch_ctx->features ); fd_features_set( &epoch_ctx->features, fd_feature_id_query(TEST_VM_REJECT_CALLX_R10_FEATURE_PREFIX), 0UL ); - txn_ctx->block_hash_queue = slot_ctx->slot_bank.block_hash_queue; - txn_ctx->slot = slot_ctx->slot_bank.slot; + txn_ctx->slot = slot_ctx->slot; txn_ctx->features = epoch_ctx->features; return ctx; diff --git a/src/funk/fd_funk_rec.c b/src/funk/fd_funk_rec.c index d7f56e9fa5..50b4e5ef89 100644 --- a/src/funk/fd_funk_rec.c +++ b/src/funk/fd_funk_rec.c @@ -396,6 +396,7 @@ fd_funk_rec_try_clone_safe( fd_funk_t * funk, fd_funk_rec_prepare_t prepare[1]; fd_funk_rec_t * new_rec = fd_funk_rec_prepare( funk, txn, key, prepare, &err ); if( FD_UNLIKELY( err ) ) { + __asm__("int $3"); FD_LOG_CRIT(( "fd_funk_rec_prepare returned err=%d", err )); } diff --git a/src/funk/fd_funk_rec.h b/src/funk/fd_funk_rec.h index 66f819d54f..217ff4c862 100644 --- a/src/funk/fd_funk_rec.h +++ b/src/funk/fd_funk_rec.h @@ -309,7 +309,7 @@ void fd_funk_rec_cancel( fd_funk_t * funk, fd_funk_rec_prepare_t * prepare ); -/* fd_funk_rec_clone copies a record from an ancestor transaction +/* fd_funk_` copies a record from an ancestor transaction to create a new record in the given transaction. The record can be modified afterward and must then be published. From 5c51a6c3a979a8e236bc83d90a7ef41c9a592f6a Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 15:10:58 +0000 Subject: [PATCH 2/9] nits --- src/funk/fd_funk_rec.c | 1 - src/funk/fd_funk_rec.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/funk/fd_funk_rec.c b/src/funk/fd_funk_rec.c index 50b4e5ef89..d7f56e9fa5 100644 --- a/src/funk/fd_funk_rec.c +++ b/src/funk/fd_funk_rec.c @@ -396,7 +396,6 @@ fd_funk_rec_try_clone_safe( fd_funk_t * funk, fd_funk_rec_prepare_t prepare[1]; fd_funk_rec_t * new_rec = fd_funk_rec_prepare( funk, txn, key, prepare, &err ); if( FD_UNLIKELY( err ) ) { - __asm__("int $3"); FD_LOG_CRIT(( "fd_funk_rec_prepare returned err=%d", err )); } diff --git a/src/funk/fd_funk_rec.h b/src/funk/fd_funk_rec.h index 217ff4c862..66f819d54f 100644 --- a/src/funk/fd_funk_rec.h +++ b/src/funk/fd_funk_rec.h @@ -309,7 +309,7 @@ void fd_funk_rec_cancel( fd_funk_t * funk, fd_funk_rec_prepare_t * prepare ); -/* fd_funk_` copies a record from an ancestor transaction +/* fd_funk_rec_clone copies a record from an ancestor transaction to create a new record in the given transaction. The record can be modified afterward and must then be published. From c67903d0d15a010703fc80db758db9d499428f55 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 18:00:57 +0000 Subject: [PATCH 3/9] standardizing bnak mgr usage in replay tile --- src/discof/replay/fd_replay_tile.c | 54 ++++++++++++------------------ src/flamenco/runtime/fd_bank_mgr.h | 11 ++++-- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index d42bf45c4f..e08fa2010d 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -1169,10 +1169,9 @@ publish_slot_notifications( fd_replay_tile_ctx_t * ctx, .parent_slot = ctx->parent_slot, }; */ - FD_BANK_MGR_DECL( bank_mgr, ctx->funk, ctx->slot_ctx->funk_txn ); - ulong * execution_fees = fd_bank_mgr_execution_fees_query( bank_mgr ); - ulong * priority_fees = fd_bank_mgr_priority_fees_query( bank_mgr ); + ulong * execution_fees = fd_bank_mgr_execution_fees_query( fork->slot_ctx->bank_mgr ); + ulong * priority_fees = fd_bank_mgr_priority_fees_query( fork->slot_ctx->bank_mgr ); ulong msg[11]; msg[ 0 ] = ctx->curr_slot; @@ -1399,23 +1398,21 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot; fork->slot_ctx->slot = curr_slot; - FD_BANK_MGR_DECL( bank_mgr_prev, fork->slot_ctx->funk, fork->slot_ctx->funk_txn ); - - ulong * max_tick_height = fd_bank_mgr_max_tick_height_query( bank_mgr_prev ); - ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( bank_mgr_prev ); - ulong * tick_height = fd_bank_mgr_tick_height_modify( bank_mgr_prev ); + ulong * max_tick_height = fd_bank_mgr_max_tick_height_query( fork->slot_ctx->bank_mgr ); + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_query( fork->slot_ctx->bank_mgr ); + ulong * tick_height = fd_bank_mgr_tick_height_modify( fork->slot_ctx->bank_mgr ); *tick_height = *max_tick_height; - fd_bank_mgr_tick_height_save( bank_mgr_prev ); + fd_bank_mgr_tick_height_save( fork->slot_ctx->bank_mgr ); - max_tick_height = fd_bank_mgr_max_tick_height_modify( bank_mgr_prev ); + max_tick_height = fd_bank_mgr_max_tick_height_modify( fork->slot_ctx->bank_mgr ); if( FD_UNLIKELY( FD_RUNTIME_EXECUTE_SUCCESS != fd_runtime_compute_max_tick_height( *ticks_per_slot, curr_slot, max_tick_height ) ) ) { FD_LOG_ERR(( "couldn't compute tick height/max tick height slot %lu ticks_per_slot %lu", curr_slot, *ticks_per_slot )); } - fd_bank_mgr_max_tick_height_save( bank_mgr_prev ); + fd_bank_mgr_max_tick_height_save( fork->slot_ctx->bank_mgr ); fork->slot_ctx->enable_exec_recording = ctx->tx_metadata_storage; fork->slot_ctx->runtime_wksp = fd_wksp_containing( ctx->runtime_spad ); @@ -1450,7 +1447,7 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, xid.ul[0] = fork->slot_ctx->slot; /* push a new transaction on the stack */ fd_funk_txn_start_write( ctx->funk ); - fork->slot_ctx->funk_txn = fd_funk_txn_prepare(ctx->funk, fork->slot_ctx->funk_txn, &xid, 1); + fork->slot_ctx->funk_txn = fd_funk_txn_prepare(ctx->funk, fork->slot_ctx->funk_txn, &xid, 1 ); fork->slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( fork->slot_ctx->bank_mgr_mem ), fork->slot_ctx->funk, fork->slot_ctx->funk_txn ); @@ -1722,10 +1719,9 @@ exec_slice( fd_replay_tile_ctx_t * ctx, fd_block_map_prepare( ctx->blockstore->block_map, &ctx->curr_slot, NULL, query, FD_MAP_FLAG_BLOCKING ); fd_block_info_t * block_info = fd_block_map_query_ele( query ); - FD_BANK_MGR_DECL( bank_mgr, ctx->slot_ctx->funk, ctx->slot_ctx->funk_txn ); - fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + fd_hash_t * poh = fd_bank_mgr_poh_modify( fork->slot_ctx->bank_mgr ); memcpy( poh->hash, hdr->hash, sizeof(fd_hash_t) ); - fd_bank_mgr_poh_save( bank_mgr ); + fd_bank_mgr_poh_save( fork->slot_ctx->bank_mgr ); block_info->flags = fd_uchar_set_bit( block_info->flags, FD_BLOCK_FLAG_PROCESSED ); FD_COMPILER_MFENCE(); block_info->flags = fd_uchar_clear_bit( block_info->flags, FD_BLOCK_FLAG_REPLAYING ); @@ -2015,15 +2011,13 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, ctx->slot_ctx->slot_bank.prev_slot = 0UL; ctx->slot_ctx->slot = 1UL; - FD_BANK_MGR_DECL( bank_mgr, ctx->slot_ctx->funk, ctx->slot_ctx->funk_txn ); - - ulong hashcnt_per_slot = *(fd_bank_mgr_hashes_per_tick_query( bank_mgr )) * *(fd_bank_mgr_ticks_per_slot_query( bank_mgr )); - fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + ulong hashcnt_per_slot = *(fd_bank_mgr_hashes_per_tick_query( ctx->slot_ctx->bank_mgr )) * *(fd_bank_mgr_ticks_per_slot_query( ctx->slot_ctx->bank_mgr )); + fd_hash_t * poh = fd_bank_mgr_poh_modify( ctx->slot_ctx->bank_mgr ); fd_hash_t poh_hash = *poh; while(hashcnt_per_slot--) { fd_sha256_hash( poh->hash, 32UL, &poh_hash ); } - fd_bank_mgr_poh_save( bank_mgr ); + fd_bank_mgr_poh_save( ctx->slot_ctx->bank_mgr ); FD_TEST( fd_runtime_block_execute_prepare( ctx->slot_ctx, ctx->runtime_spad ) == 0 ); fd_runtime_block_info_t info = { .signature_cnt = 0 }; @@ -2073,9 +2067,8 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, fd_fork_t * snapshot_fork = fd_forks_init( ctx->forks, ctx->slot_ctx ); FD_TEST( snapshot_fork ); - FD_BANK_MGR_DECL( bank_mgr, ctx->funk, snapshot_fork->slot_ctx->funk_txn ); - ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_query( bank_mgr ); - ulong * eah_stop_slot = fd_bank_mgr_eah_stop_slot_query( bank_mgr ); + ulong * eah_start_slot = fd_bank_mgr_eah_start_slot_query( ctx->slot_ctx->bank_mgr ); + ulong * eah_stop_slot = fd_bank_mgr_eah_stop_slot_query( ctx->slot_ctx->bank_mgr ); fd_epoch_init( ctx->epoch, *eah_start_slot, @@ -2295,8 +2288,7 @@ publish_votes_to_plugin( fd_replay_tile_ctx_t * ctx, fd_clock_timestamp_vote_t_mapnode_t query; memcpy( query.elem.pubkey.uc, n->elem.key.uc, 32UL ); - FD_BANK_MGR_DECL( bank_mgr, ctx->funk, fork->slot_ctx->funk_txn ); - fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( bank_mgr ); + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( fork->slot_ctx->bank_mgr ); fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_root = fd_clock_timestamp_votes_votes_root_join( clock_timestamp_votes ); fd_clock_timestamp_vote_t_mapnode_t * timestamp_votes_pool = fd_clock_timestamp_votes_votes_pool_join( clock_timestamp_votes ); @@ -2479,8 +2471,7 @@ after_credit( fd_replay_tile_ctx_t * ctx, /**************************************************************************************************/ fd_runtime_block_info_t runtime_block_info[1]; - FD_BANK_MGR_DECL( bank_mgr, ctx->funk, fork->slot_ctx->funk_txn ); - ulong * signature_cnt = fd_bank_mgr_signature_cnt_query( bank_mgr ); + ulong * signature_cnt = fd_bank_mgr_signature_cnt_query( fork->slot_ctx->bank_mgr ); runtime_block_info->signature_cnt = *signature_cnt; ctx->block_finalizing = 0; @@ -2607,14 +2598,13 @@ after_credit( fd_replay_tile_ctx_t * ctx, ulong prev_slot = child->slot_ctx->slot; child->slot_ctx->slot = curr_slot; - FD_BANK_MGR_DECL( bank_mgr_post, ctx->funk, ctx->slot_ctx->funk_txn ); - ulong * execution_fees = fd_bank_mgr_execution_fees_modify( bank_mgr_post ); + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( fork->slot_ctx->bank_mgr ); *execution_fees = 0UL; - fd_bank_mgr_execution_fees_save( bank_mgr_post ); + fd_bank_mgr_execution_fees_save( fork->slot_ctx->bank_mgr ); - ulong * priority_fees = fd_bank_mgr_priority_fees_modify( bank_mgr ); + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( fork->slot_ctx->bank_mgr ); *priority_fees = 0UL; - fd_bank_mgr_priority_fees_save( bank_mgr ); + fd_bank_mgr_priority_fees_save( fork->slot_ctx->bank_mgr ); if( FD_UNLIKELY( ctx->slots_replayed_file ) ) { FD_LOG_DEBUG(( "writing %lu to slots file", prev_slot )); diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h index fd35e786af..66acec42c3 100644 --- a/src/flamenco/runtime/fd_bank_mgr.h +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -1,7 +1,12 @@ +#ifndef HEADER_fd_src_flamenco_runtime_fd_bank_mgr_h +#define HEADER_fd_src_flamenco_runtime_fd_bank_mgr_h + #include "../../funk/fd_funk.h" #include "../fd_flamenco_base.h" #include "../types/fd_types.h" +FD_PROTOTYPES_BEGIN + /* The bank manager is a wrapper on top of funk that manages on-chain state not represented by accounts. In practice, this on-chain state is a direct parallel to the Bank data structure in the Agave client. @@ -82,8 +87,6 @@ fd_bank_mgr_##name##_save_cleanup( fd_bank_mgr_t ** bank_mgr ) { \ return 0; \ } - - /* These are some convenience wrapper macros for the bank manager. */ #define FD_BANK_MGR_DECL(bank_mgr, funk, funk_txn) \ @@ -143,3 +146,7 @@ if( FD_UNLIKELY( !bank_mgr ) ) { X(fd_rent_fresh_accounts_global_t, rent_fresh_accounts, 31UL, 50000UL, 8UL ) \ X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) FD_BANK_MGR_ITER(BANK_MGR_FUNCTIONS) + +FD_PROTOTYPES_END + +#endif /* HEADER_fd_src_flamenco_runtime_fd_bank_mgr_h */ From 4ce11e1706f50636bd1cab616e0a2fb7cba2d6af Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 18:48:04 +0000 Subject: [PATCH 4/9] making bank manager local to each thread --- src/discof/exec/fd_exec_tile.c | 24 ++-- src/discof/replay/fd_replay_tile.c | 27 ++-- src/discof/writer/fd_writer_tile.c | 17 ++- .../runtime/context/fd_exec_slot_ctx.c | 118 ++++++++---------- .../runtime/context/fd_exec_txn_ctx.h | 1 + src/flamenco/runtime/fd_bank_mgr.h | 3 + src/flamenco/runtime/fd_runtime.c | 13 +- src/flamenco/runtime/fd_runtime.h | 3 +- .../runtime/program/fd_builtin_programs.c | 10 +- .../runtime/program/fd_stake_program.c | 15 +-- .../runtime/program/fd_vote_program.c | 30 ++--- .../runtime/program/fd_vote_program.h | 3 +- src/flamenco/runtime/sysvar/fd_sysvar.c | 6 +- src/flamenco/runtime/sysvar/fd_sysvar_clock.c | 18 +-- src/flamenco/runtime/sysvar/fd_sysvar_fees.c | 22 ++-- .../sysvar/fd_sysvar_last_restart_slot.c | 9 +- .../runtime/sysvar/fd_sysvar_recent_hashes.c | 18 +-- .../runtime/tests/harness/fd_txn_harness.c | 8 +- 18 files changed, 154 insertions(+), 191 deletions(-) diff --git a/src/discof/exec/fd_exec_tile.c b/src/discof/exec/fd_exec_tile.c index e1c594d4af..fdc9535059 100644 --- a/src/discof/exec/fd_exec_tile.c +++ b/src/discof/exec/fd_exec_tile.c @@ -163,6 +163,7 @@ scratch_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED ) { /* clang-format off */ ulong l = FD_LAYOUT_INIT; l = FD_LAYOUT_APPEND( l, alignof(fd_exec_tile_ctx_t), sizeof(fd_exec_tile_ctx_t) ); + l = FD_LAYOUT_APPEND( l, alignof(fd_bank_mgr_t), sizeof(fd_bank_mgr_t) ); return FD_LAYOUT_FINI( l, scratch_align() ); /* clang-format on */ } @@ -254,18 +255,20 @@ prepare_new_slot_execution( fd_exec_tile_ctx_t * ctx, FD_LOG_ERR(( "Could not find valid sysvar cache" )); } - /* Update the local join to the bank manager.*/ - ctx->txn_ctx->bank_mgr = fd_bank_mgr_join( ctx->txn_ctx->bank_mgr_mem, ctx->txn_ctx->funk, ctx->txn_ctx->funk_txn ); - if( FD_UNLIKELY( !ctx->txn_ctx->bank_mgr ) ) { - FD_LOG_ERR(( "Could not join bank mgr" )); + /* Refresh the bank manager join for the slot that's being executed. */ + ctx->bank_mgr = fd_bank_mgr_join( ctx->bank_mgr, ctx->funk, funk_txn ); + if( FD_UNLIKELY( !ctx->bank_mgr ) ) { + FD_LOG_ERR(( "Could not join bank mgr for slot %lu", slot_msg->slot )); } - ctx->txn_ctx->slot = *(fd_bank_mgr_slot_query( ctx->txn_ctx->bank_mgr )); - ctx->txn_ctx->block_hash_queue = fd_bank_mgr_block_hash_queue_query( ctx->txn_ctx->bank_mgr ); + ctx->txn_ctx->slot = *(fd_bank_mgr_slot_query( ctx->bank_mgr )); + ctx->txn_ctx->block_hash_queue = fd_bank_mgr_block_hash_queue_query( ctx->bank_mgr ); if( FD_UNLIKELY( !ctx->txn_ctx->block_hash_queue ) ) { FD_LOG_ERR(( "Could not find valid block hash queue" )); } - ctx->txn_ctx->fee_rate_governor = *(fd_bank_mgr_fee_rate_governor_query( ctx->txn_ctx->bank_mgr )); + ctx->txn_ctx->fee_rate_governor = *(fd_bank_mgr_fee_rate_governor_query( ctx->bank_mgr )); + + ctx->txn_ctx->bank_mgr = ctx->bank_mgr; } static void @@ -542,6 +545,7 @@ unprivileged_init( fd_topo_t * topo, FD_SCRATCH_ALLOC_INIT( l, scratch ); fd_exec_tile_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_tile_ctx_t), sizeof(fd_exec_tile_ctx_t) ); + uchar * bank_mgr_mem = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_bank_mgr_t), sizeof(fd_bank_mgr_t) ); ulong scratch_alloc_mem = FD_SCRATCH_ALLOC_FINI( l, scratch_align() ); if( FD_UNLIKELY( scratch_alloc_mem - (ulong)scratch - scratch_footprint( tile ) ) ) { FD_LOG_ERR( ( "Scratch_alloc_mem did not match scratch_footprint diff: %lu alloc: %lu footprint: %lu", @@ -688,6 +692,12 @@ unprivileged_init( fd_topo_t * topo, ctx->txn_id = 0U; ctx->bpf_id = 0U; + /********************************************************************/ + /* bank manager */ + /********************************************************************/ + + ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( bank_mgr_mem ), ctx->funk, NULL ); + FD_LOG_NOTICE(( "Done booting exec tile idx=%lu", ctx->tile_idx )); } diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index e08fa2010d..c36de65d21 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -337,9 +337,6 @@ struct fd_replay_tile_ctx { fd_replay_tile_metrics_t metrics; ulong * exec_slice_deque; /* Deque to buffer exec slices */ - - /* Local join to the bank_mgr that must be refreshed at every slot. */ - fd_bank_mgr_t * bank_mgr; }; typedef struct fd_replay_tile_ctx fd_replay_tile_ctx_t; @@ -366,7 +363,6 @@ scratch_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED ) { l = FD_LAYOUT_APPEND( l, fd_forks_align(), fd_forks_footprint( FD_BLOCK_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_ghost_align(), fd_ghost_footprint( FD_BLOCK_MAX ) ); l = FD_LAYOUT_APPEND( l, fd_tower_align(), fd_tower_footprint() ); - l = FD_LAYOUT_APPEND( l, fd_bank_mgr_align(), fd_bank_mgr_footprint() ); for( ulong i = 0UL; iskip_frag = 0; if( in_idx==BATCH_IN_IDX ) { - fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_modify( ctx->bank_mgr ); + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_modify( ctx->slot_ctx->bank_mgr ); uchar * src = (uchar *)fd_chunk_to_laddr( ctx->batch_in_mem, chunk ); fd_memcpy( epoch_account_hash, src, sizeof(fd_hash_t) ); - fd_bank_mgr_epoch_account_hash_save( ctx->bank_mgr ); + fd_bank_mgr_epoch_account_hash_save( ctx->slot_ctx->bank_mgr ); FD_LOG_NOTICE(( "Epoch account hash calculated to be %s", FD_BASE58_ENC_32_ALLOCA( epoch_account_hash ) )); } } @@ -1475,8 +1471,6 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, send_exec_epoch_msg( ctx, stem, fork->slot_ctx ); } - ctx->bank_mgr = fd_bank_mgr_join( ctx->bank_mgr, ctx->funk, fork->slot_ctx->funk_txn ); - /* At this point we need to notify all of the exec tiles and tell them that a new slot is ready to be published. At this point, we should also mark the tile as not being ready. */ @@ -1515,12 +1509,12 @@ init_poh( fd_replay_tile_ctx_t * ctx ) { FD_LOG_INFO(( "sending init msg" )); fd_replay_out_ctx_t * bank_out = &ctx->bank_out[ 0UL ]; fd_poh_init_msg_t * msg = fd_chunk_to_laddr( bank_out->mem, bank_out->chunk ); - FD_TEST( ctx->bank_mgr && ctx->bank_mgr->funk && ctx->bank_mgr->funk_txn ); - msg->hashcnt_per_tick = *(fd_bank_mgr_hashes_per_tick_query( ctx->bank_mgr )); - msg->ticks_per_slot = *(fd_bank_mgr_ticks_per_slot_query( ctx->bank_mgr )); - msg->tick_duration_ns = (ulong)(*fd_bank_mgr_ns_per_slot_query( ctx->bank_mgr ) / *(fd_bank_mgr_ticks_per_slot_query( ctx->bank_mgr ))); + FD_TEST( ctx->slot_ctx->bank_mgr && ctx->slot_ctx->bank_mgr->funk && ctx->slot_ctx->bank_mgr->funk_txn ); + msg->hashcnt_per_tick = *(fd_bank_mgr_hashes_per_tick_query( ctx->slot_ctx->bank_mgr )); + msg->ticks_per_slot = *(fd_bank_mgr_ticks_per_slot_query( ctx->slot_ctx->bank_mgr )); + msg->tick_duration_ns = (ulong)(*fd_bank_mgr_ns_per_slot_query( ctx->slot_ctx->bank_mgr ) / *(fd_bank_mgr_ticks_per_slot_query( ctx->slot_ctx->bank_mgr ))); - fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( ctx->bank_mgr ); + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( ctx->slot_ctx->bank_mgr ); fd_hash_t * last_hash = fd_block_hash_queue_last_hash_join( bhq ); if( last_hash ) { memcpy(msg->last_entry_hash, last_hash, sizeof(fd_hash_t)); @@ -2811,7 +2805,6 @@ unprivileged_init( fd_topo_t * topo, void * forks_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_forks_align(), fd_forks_footprint( FD_BLOCK_MAX ) ); void * ghost_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_ghost_align(), fd_ghost_footprint( FD_BLOCK_MAX ) ); void * tower_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_align(), fd_tower_footprint() ); - void * bank_mgr_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_bank_mgr_align(), fd_bank_mgr_footprint() ); for( ulong i = 0UL; ibmtree[i] = FD_SCRATCH_ALLOC_APPEND( l, FD_BMTREE_COMMIT_ALIGN, FD_BMTREE_COMMIT_FOOTPRINT(0) ); } @@ -2859,12 +2852,6 @@ unprivileged_init( fd_topo_t * topo, FD_LOG_NOTICE(( "Snapshot intervals full=%lu incremental=%lu", ctx->snapshot_interval, ctx->incremental_interval )); - /**********************************************************************/ - /* bank_mgr */ - /**********************************************************************/ - - ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( bank_mgr_mem ), ctx->funk, NULL ); - /**********************************************************************/ /* funk */ /**********************************************************************/ diff --git a/src/discof/writer/fd_writer_tile.c b/src/discof/writer/fd_writer_tile.c index f1f894b179..d67a1f207c 100644 --- a/src/discof/writer/fd_writer_tile.c +++ b/src/discof/writer/fd_writer_tile.c @@ -7,6 +7,7 @@ #include "../../flamenco/runtime/fd_runtime.h" #include "../../flamenco/runtime/fd_runtime_public.h" #include "../../flamenco/runtime/fd_executor.h" +#include "../../flamenco/runtime/fd_bank_mgr.h" #include "../../funk/fd_funk.h" #include "../../funk/fd_funk_filemap.h" @@ -52,6 +53,9 @@ struct fd_writer_tile_ctx { /* Local joins of exec tile txn ctx. Read-only. */ fd_exec_txn_ctx_t * txn_ctx[ FD_PACK_MAX_BANK_TILES ]; + + /* Local join of bank manager. R/W */ + fd_bank_mgr_t * bank_mgr; }; typedef struct fd_writer_tile_ctx fd_writer_tile_ctx_t; @@ -65,6 +69,7 @@ scratch_footprint( fd_topo_tile_t const * tile ) { (void)tile; ulong l = FD_LAYOUT_INIT; l = FD_LAYOUT_APPEND( l, alignof(fd_writer_tile_ctx_t), sizeof(fd_writer_tile_ctx_t) ); + l = FD_LAYOUT_APPEND( l, alignof(fd_bank_mgr_t), sizeof(fd_bank_mgr_t) ); l = FD_LAYOUT_APPEND( l, fd_spad_align(), fd_spad_footprint( FD_RUNTIME_TRANSACTION_FINALIZATION_FOOTPRINT ) ); return FD_LAYOUT_FINI( l, scratch_align() ); } @@ -146,12 +151,15 @@ during_frag( fd_writer_tile_ctx_t * ctx, if( FD_LIKELY( sig==FD_WRITER_SLOT_SIG ) ) { //FIXME this should be replaced by bank mgr + fd_runtime_public_replay_writer_slot_msg_t * msg = fd_type_pun( fd_chunk_to_laddr( in_ctx->mem, chunk ) ); fd_exec_slot_ctx_t * slot_ctx = fd_wksp_laddr_fast( ctx->runtime_public_wksp, msg->slot_ctx_gaddr ); if( FD_UNLIKELY( !slot_ctx ) ) { FD_LOG_CRIT(( "Unable to join slot_ctx at gaddr 0x%lx", msg->slot_ctx_gaddr )); } ctx->slot_ctx = slot_ctx; + + ctx->bank_mgr = fd_bank_mgr_join( ctx->bank_mgr, ctx->funk, ctx->slot_ctx->funk_txn ); return; } @@ -189,7 +197,7 @@ during_frag( fd_writer_tile_ctx_t * ctx, FD_SPIN_PAUSE(); } FD_SPAD_FRAME_BEGIN( ctx->spad ) { - fd_runtime_finalize_txn( ctx->slot_ctx, NULL, &info, ctx->spad ); + fd_runtime_finalize_txn( ctx->slot_ctx, NULL, &info, ctx->spad, ctx->bank_mgr ); } FD_SPAD_FRAME_END; } /* Notify the replay tile. */ @@ -233,6 +241,7 @@ unprivileged_init( fd_topo_t * topo, FD_SCRATCH_ALLOC_INIT( l, scratch ); fd_writer_tile_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_writer_tile_ctx_t), sizeof(fd_writer_tile_ctx_t) ); + void * bank_mgr_mem = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_bank_mgr_t), sizeof(fd_bank_mgr_t) ); void * spad_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_spad_align(), fd_spad_footprint( FD_RUNTIME_TRANSACTION_FINALIZATION_FOOTPRINT ) ); ulong scratch_alloc_mem = FD_SCRATCH_ALLOC_FINI( l, scratch_align() ); if( FD_UNLIKELY( scratch_alloc_mem - (ulong)scratch - scratch_footprint( tile ) ) ) { @@ -367,6 +376,12 @@ unprivileged_init( fd_topo_t * topo, FD_LOG_CRIT(( "writer tile %lu fseq setup failed", ctx->tile_idx )); } fd_fseq_update( ctx->fseq, FD_WRITER_STATE_NOT_BOOTED ); + + /********************************************************************/ + /* Bank manager */ + /********************************************************************/ + + ctx->bank_mgr = fd_bank_mgr_join( bank_mgr_mem, ctx->funk, NULL ); } static ulong diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.c b/src/flamenco/runtime/context/fd_exec_slot_ctx.c index 44186ce0d1..534f8ca066 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.c @@ -149,7 +149,7 @@ recover_clock( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { /* Record timestamp */ if( slot != 0 || n->elem.stake != 0 ) { - fd_vote_record_timestamp_vote_with_slot( slot_ctx, &n->elem.key, timestamp, slot ); + fd_vote_record_timestamp_vote_with_slot( slot_ctx, &n->elem.key, timestamp, slot, slot_ctx->bank_mgr ); } } FD_SPAD_FRAME_END; } @@ -248,19 +248,9 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_memcpy( &epoch_bank->rent, &oldbank->rent_collector.rent, sizeof(fd_rent_t) ); fd_memcpy( &epoch_bank->rent_epoch_schedule, &oldbank->rent_collector.epoch_schedule, sizeof(fd_epoch_schedule_t) ); - - fd_funk_t * funk = slot_ctx->funk; - fd_funk_txn_t * funk_txn = slot_ctx->funk_txn; - - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, funk, funk_txn ); - if( FD_UNLIKELY( !bank_mgr ) ) { - FD_LOG_ERR(( "Could not allocate bank manager" )); - } - /* Block Hash Queue */ - fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_modify( bank_mgr ); + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_modify( slot_ctx->bank_mgr ); uchar * last_hash_mem = (uchar *)fd_ulong_align_up( (ulong)bhq + sizeof(fd_block_hash_queue_global_t), alignof(fd_hash_t) ); uchar * ages_pool_mem = (uchar *)fd_ulong_align_up( (ulong)last_hash_mem + sizeof(fd_hash_t), fd_hash_hash_age_pair_t_map_align() ); @@ -287,134 +277,134 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, bhq->max_age = oldbank->blockhash_queue.max_age; - fd_bank_mgr_block_hash_queue_save( bank_mgr ); + fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); /* Slot */ - ulong * slot_ptr = fd_bank_mgr_slot_modify( bank_mgr ); + ulong * slot_ptr = fd_bank_mgr_slot_modify( slot_ctx->bank_mgr ); *slot_ptr = oldbank->slot; - fd_bank_mgr_slot_save( bank_mgr ); + fd_bank_mgr_slot_save( slot_ctx->bank_mgr ); slot_ctx->slot = oldbank->slot; /* Fee Rate Governor */ - fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( bank_mgr ); + fd_fee_rate_governor_t * fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( slot_ctx->bank_mgr ); *fee_rate_governor = oldbank->fee_rate_governor; - fd_bank_mgr_fee_rate_governor_save( bank_mgr ); + fd_bank_mgr_fee_rate_governor_save( slot_ctx->bank_mgr ); /* Capitalization */ - ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); *capitalization = oldbank->capitalization; - fd_bank_mgr_capitalization_save( bank_mgr ); + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); /* Lamports Per Signature */ - ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); *lamports_per_signature = manifest->lamports_per_signature; - fd_bank_mgr_lamports_per_signature_save( bank_mgr ); + fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); /* Previous Lamports Per Signature */ - ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( bank_mgr ); + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); *prev_lamports_per_signature = manifest->lamports_per_signature; - fd_bank_mgr_prev_lamports_per_signature_save( bank_mgr ); + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); /* Transaction Count */ - ulong * transaction_count = fd_bank_mgr_transaction_count_modify( bank_mgr ); + ulong * transaction_count = fd_bank_mgr_transaction_count_modify( slot_ctx->bank_mgr ); *transaction_count = oldbank->transaction_count; - fd_bank_mgr_transaction_count_save( bank_mgr ); + fd_bank_mgr_transaction_count_save( slot_ctx->bank_mgr ); /* Parent Signature Count */ - ulong * parent_signature_cnt = fd_bank_mgr_parent_signature_cnt_modify( bank_mgr ); + ulong * parent_signature_cnt = fd_bank_mgr_parent_signature_cnt_modify( slot_ctx->bank_mgr ); *parent_signature_cnt = oldbank->signature_count; - fd_bank_mgr_parent_signature_cnt_save( bank_mgr ); + fd_bank_mgr_parent_signature_cnt_save( slot_ctx->bank_mgr ); /* Tick Height */ - ulong * tick_height = fd_bank_mgr_tick_height_modify( bank_mgr ); + ulong * tick_height = fd_bank_mgr_tick_height_modify( slot_ctx->bank_mgr ); *tick_height = oldbank->tick_height; - fd_bank_mgr_tick_height_save( bank_mgr ); + fd_bank_mgr_tick_height_save( slot_ctx->bank_mgr ); /* Max Tick Height */ - ulong * max_tick_height = fd_bank_mgr_max_tick_height_modify( bank_mgr ); + ulong * max_tick_height = fd_bank_mgr_max_tick_height_modify( slot_ctx->bank_mgr ); *max_tick_height = oldbank->max_tick_height; - fd_bank_mgr_max_tick_height_save( bank_mgr ); + fd_bank_mgr_max_tick_height_save( slot_ctx->bank_mgr ); /* Hashes Per Tick */ - ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( bank_mgr ); + ulong * hashes_per_tick = fd_bank_mgr_hashes_per_tick_modify( slot_ctx->bank_mgr ); *hashes_per_tick = !!oldbank->hashes_per_tick ? *oldbank->hashes_per_tick : 0UL; - fd_bank_mgr_hashes_per_tick_save( bank_mgr ); + fd_bank_mgr_hashes_per_tick_save( slot_ctx->bank_mgr ); /* NS Per Slot */ - uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_modify( bank_mgr ); + uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_modify( slot_ctx->bank_mgr ); *ns_per_slot = oldbank->ns_per_slot; - fd_bank_mgr_ns_per_slot_save( bank_mgr ); + fd_bank_mgr_ns_per_slot_save( slot_ctx->bank_mgr ); /* Ticks Per Slot */ - ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_modify( bank_mgr ); + ulong * ticks_per_slot = fd_bank_mgr_ticks_per_slot_modify( slot_ctx->bank_mgr ); *ticks_per_slot = oldbank->ticks_per_slot; - fd_bank_mgr_ticks_per_slot_save( bank_mgr ); + fd_bank_mgr_ticks_per_slot_save( slot_ctx->bank_mgr ); /* Genesis Creation Time */ - ulong * genesis_creation_time = fd_bank_mgr_genesis_creation_time_modify( bank_mgr ); + ulong * genesis_creation_time = fd_bank_mgr_genesis_creation_time_modify( slot_ctx->bank_mgr ); *genesis_creation_time = oldbank->genesis_creation_time; - fd_bank_mgr_genesis_creation_time_save( bank_mgr ); + fd_bank_mgr_genesis_creation_time_save( slot_ctx->bank_mgr ); /* Slots Per Year */ - double * slots_per_year = fd_bank_mgr_slots_per_year_modify( bank_mgr ); + double * slots_per_year = fd_bank_mgr_slots_per_year_modify( slot_ctx->bank_mgr ); *slots_per_year = oldbank->slots_per_year; - fd_bank_mgr_slots_per_year_save( bank_mgr ); + fd_bank_mgr_slots_per_year_save( slot_ctx->bank_mgr ); /* Inflation */ - fd_inflation_t * inflation = fd_bank_mgr_inflation_modify( bank_mgr ); + fd_inflation_t * inflation = fd_bank_mgr_inflation_modify( slot_ctx->bank_mgr ); *inflation = oldbank->inflation; - fd_bank_mgr_inflation_save( bank_mgr ); + fd_bank_mgr_inflation_save( slot_ctx->bank_mgr ); /* Block Height */ - ulong * block_height = fd_bank_mgr_block_height_modify( bank_mgr ); + ulong * block_height = fd_bank_mgr_block_height_modify( slot_ctx->bank_mgr ); *block_height = oldbank->block_height; - fd_bank_mgr_block_height_save( bank_mgr ); + fd_bank_mgr_block_height_save( slot_ctx->bank_mgr ); /* Epoch Account Hash */ - fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_modify( bank_mgr ); + fd_hash_t * epoch_account_hash = fd_bank_mgr_epoch_account_hash_modify( slot_ctx->bank_mgr ); if( manifest->epoch_account_hash ) { *epoch_account_hash = *manifest->epoch_account_hash; } else { memset( epoch_account_hash, 0, sizeof(fd_hash_t) ); } - fd_bank_mgr_epoch_account_hash_save( bank_mgr ); + fd_bank_mgr_epoch_account_hash_save( slot_ctx->bank_mgr ); /* Execution Fees */ - ulong * execution_fees = fd_bank_mgr_execution_fees_modify( bank_mgr ); + ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); *execution_fees = oldbank->collector_fees; - fd_bank_mgr_execution_fees_save( bank_mgr ); + fd_bank_mgr_execution_fees_save( slot_ctx->bank_mgr ); /* Priority Fees */ - ulong * priority_fees = fd_bank_mgr_priority_fees_modify( bank_mgr ); + ulong * priority_fees = fd_bank_mgr_priority_fees_modify( slot_ctx->bank_mgr ); *priority_fees = 0UL; - fd_bank_mgr_priority_fees_save( bank_mgr ); + fd_bank_mgr_priority_fees_save( slot_ctx->bank_mgr ); /* PoH */ if( oldbank->blockhash_queue.last_hash ) { - fd_hash_t * poh = fd_bank_mgr_poh_modify( bank_mgr ); + fd_hash_t * poh = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); *poh = *oldbank->blockhash_queue.last_hash; - fd_bank_mgr_poh_save( bank_mgr ); + fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); } /* Last Restart Slot */ @@ -426,7 +416,7 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, To find the last restart slot, take the highest hard fork slot number that is less or equal than the current slot number. (There might be some hard forks in the future, ignore these) */ - fd_sol_sysvar_last_restart_slot_t * last_restart_slot = fd_bank_mgr_last_restart_slot_modify( bank_mgr ); + fd_sol_sysvar_last_restart_slot_t * last_restart_slot = fd_bank_mgr_last_restart_slot_modify( slot_ctx->bank_mgr ); do { last_restart_slot->slot = 0UL; if( FD_UNLIKELY( oldbank->hard_forks.hard_forks_len == 0 ) ) { @@ -444,15 +434,15 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, } } } while (0); - fd_bank_mgr_last_restart_slot_save( bank_mgr ); + fd_bank_mgr_last_restart_slot_save( slot_ctx->bank_mgr ); /* FIXME: Remove the magic number here. */ - fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( bank_mgr ); + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( slot_ctx->bank_mgr ); uchar * clock_pool_mem = (uchar *)fd_ulong_align_up( (ulong)clock_timestamp_votes + sizeof(fd_clock_timestamp_votes_global_t), fd_clock_timestamp_vote_t_map_align() ); fd_clock_timestamp_vote_t_mapnode_t * clock_pool = fd_clock_timestamp_vote_t_map_join( fd_clock_timestamp_vote_t_map_new(clock_pool_mem, 15000UL ) ); clock_timestamp_votes->votes_pool_offset = (ulong)fd_clock_timestamp_vote_t_map_leave( clock_pool) - (ulong)clock_timestamp_votes; clock_timestamp_votes->votes_root_offset = 0UL; - fd_bank_mgr_clock_timestamp_votes_save( bank_mgr ); + fd_bank_mgr_clock_timestamp_votes_save( slot_ctx->bank_mgr ); recover_clock( slot_ctx, runtime_spad ); @@ -517,9 +507,9 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, manifest->versioned_epoch_stakes[i].val.inner.Current.stakes.vote_accounts.vote_accounts_root = NULL; /* We want to save the total epoch stake for the current epoch */ - ulong * total_epoch_stake = fd_bank_mgr_total_epoch_stake_modify( bank_mgr ); + ulong * total_epoch_stake = fd_bank_mgr_total_epoch_stake_modify( slot_ctx->bank_mgr ); *total_epoch_stake = manifest->versioned_epoch_stakes[i].val.inner.Current.total_stake; - fd_bank_mgr_total_epoch_stake_save( bank_mgr ); + fd_bank_mgr_total_epoch_stake_save( slot_ctx->bank_mgr ); } if( manifest->versioned_epoch_stakes[i].epoch == epoch+1UL ) { @@ -534,9 +524,9 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, // } } - ulong * use_prev_stakes = fd_bank_mgr_use_prev_epoch_stake_modify( bank_mgr ); + ulong * use_prev_stakes = fd_bank_mgr_use_prev_epoch_stake_modify( slot_ctx->bank_mgr ); *use_prev_stakes = epoch + 2UL; - fd_bank_mgr_use_prev_epoch_stake_save( bank_mgr ); + fd_bank_mgr_use_prev_epoch_stake_save( slot_ctx->bank_mgr ); // slot_ctx->slot_bank.use_preceeding_epoch_stakes = epoch + 2UL; @@ -601,7 +591,7 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_lthash_zero( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ); - fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( bank_mgr ); + fd_rent_fresh_accounts_global_t * rent_fresh_accounts = fd_bank_mgr_rent_fresh_accounts_modify( slot_ctx->bank_mgr ); /* Setup rent fresh accounts */ rent_fresh_accounts->total_count = 0UL; @@ -611,12 +601,10 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, memset( fresh_accounts, 0, rent_fresh_accounts->fresh_accounts_len * sizeof(fd_rent_fresh_account_t) ); fd_rent_fresh_accounts_fresh_accounts_update( rent_fresh_accounts, fresh_accounts ); - fd_bank_mgr_rent_fresh_accounts_save( bank_mgr ); + fd_bank_mgr_rent_fresh_accounts_save( slot_ctx->bank_mgr ); /* Setup next epoch stakes */ - - return slot_ctx; } diff --git a/src/flamenco/runtime/context/fd_exec_txn_ctx.h b/src/flamenco/runtime/context/fd_exec_txn_ctx.h index 335522e00c..90f25a114c 100644 --- a/src/flamenco/runtime/context/fd_exec_txn_ctx.h +++ b/src/flamenco/runtime/context/fd_exec_txn_ctx.h @@ -70,6 +70,7 @@ struct __attribute__((aligned(8UL))) fd_exec_txn_ctx { uchar bank_mgr_mem[48]__attribute__((aligned(8UL))); fd_bank_mgr_t * bank_mgr; + /* All pointers starting here are valid local joins in txn execution. */ fd_features_t features; fd_sysvar_cache_t const * sysvar_cache; diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h index 66acec42c3..2d64e945b1 100644 --- a/src/flamenco/runtime/fd_bank_mgr.h +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -22,6 +22,9 @@ FD_PROTOTYPES_BEGIN not contain gaddrs or local pointers -- all data must be accessed directly or with an offset. + Important Note: The bank manager object should NOT be shared across + threads. Each thread should have its own bank manager object. + The standard usage pattern of the bank manager is to first refresh a local join for each slot via a call to fd_bank_mgr_join(). If this join is not refreshed with the latest funk txn, then the diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 4e821b5a11..2293897544 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1868,7 +1868,8 @@ void fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, fd_capture_ctx_t * capture_ctx, fd_execute_txn_task_info_t * task_info, - fd_spad_t * finalize_spad ) { + fd_spad_t * finalize_spad, + fd_bank_mgr_t * bank_mgr ) { /* for all accounts, if account->is_verified==true, propagate update to cache entry. */ @@ -1878,8 +1879,6 @@ fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, /* Collect fees */ - fd_bank_mgr_t * bank_mgr = task_info->txn_ctx->bank_mgr; - ulong * execution_fee = fd_bank_mgr_execution_fees_modify( bank_mgr ); *execution_fee += task_info->txn_ctx->execution_fee; fd_bank_mgr_execution_fees_save( bank_mgr ); @@ -1984,7 +1983,8 @@ fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, fd_vote_record_timestamp_vote_with_slot( slot_ctx, acc_rec->pubkey, ts->timestamp, - ts->slot ); + ts->slot, + bank_mgr ); } FD_SPAD_FRAME_END; } @@ -2104,7 +2104,7 @@ fd_runtime_prepare_execute_finalize_txn_task( void * tpool, return; } - fd_runtime_finalize_txn( slot_ctx, capture_ctx, task_info, task_info->txn_ctx->spad ); + fd_runtime_finalize_txn( slot_ctx, capture_ctx, task_info, task_info->txn_ctx->spad, task_info->txn_ctx->bank_mgr ); } /* fd_executor_txn_verify and fd_runtime_pre_execute_check are responisble @@ -2188,7 +2188,8 @@ fd_runtime_process_txns_in_microblock_stream( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_ERR(( "failed to allocate txn ctx" )); } - task_infos[ curr_exec_idx ].txn_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( task_infos[ curr_exec_idx ].txn_ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); + FD_BANK_MGR_DECL( bank_mgr, slot_ctx->funk, slot_ctx->funk_txn ); + task_infos[ curr_exec_idx ].txn_ctx->bank_mgr = bank_mgr; fd_tpool_exec( tpool, worker_idx, fd_runtime_prepare_execute_finalize_txn_task, slot_ctx, (ulong)capture_ctx, (ulong)task_infos[curr_exec_idx].txn, diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index c06b89308c..f9322d556f 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -576,7 +576,8 @@ void fd_runtime_finalize_txn( fd_exec_slot_ctx_t * slot_ctx, fd_capture_ctx_t * capture_ctx, fd_execute_txn_task_info_t * task_info, - fd_spad_t * finalize_spad ); + fd_spad_t * finalize_spad, + fd_bank_mgr_t * bank_mgr ); /* Epoch Boundary *************************************************************/ diff --git a/src/flamenco/runtime/program/fd_builtin_programs.c b/src/flamenco/runtime/program/fd_builtin_programs.c index 0f9db5da6f..20d3c2a052 100644 --- a/src/flamenco/runtime/program/fd_builtin_programs.c +++ b/src/flamenco/runtime/program/fd_builtin_programs.c @@ -151,11 +151,9 @@ fd_write_builtin_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_mutable_fini( rec, funk, txn ); - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, funk, txn ); - ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); (*capitalization)++; - fd_bank_mgr_capitalization_save( bank_mgr ); + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); // err = fd_acc_mgr_commit( acc_mgr, rec, slot_ctx ); FD_TEST( !err ); @@ -218,9 +216,7 @@ void fd_builtin_programs_init( fd_exec_slot_ctx_t * slot_ctx ) { fd_write_builtin_account( slot_ctx, fd_solana_zk_elgamal_proof_program_id, "zk_elgamal_proof_program", 24UL ); } - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - fd_cluster_version_t * cluster_version = fd_bank_mgr_cluster_version_query( bank_mgr ); + fd_cluster_version_t * cluster_version = fd_bank_mgr_cluster_version_query( slot_ctx->bank_mgr ); /* Precompiles have empty account data */ if( cluster_version &&cluster_version->major<2 ) { diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index 9b434f572a..d67d05cf1c 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -3243,10 +3243,7 @@ fd_stake_activating_and_deactivating( fd_delegation_t const * self, static void fd_stakes_remove_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * stake_account ) { - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - - fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( bank_mgr ); + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( slot_ctx->bank_mgr ); fd_account_keys_pair_t_mapnode_t * account_keys_pool = fd_account_keys_account_keys_pool_join( stake_account_keys ); fd_account_keys_pair_t_mapnode_t * account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); @@ -3265,7 +3262,7 @@ fd_stakes_remove_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account fd_account_keys_account_keys_pool_update( stake_account_keys, account_keys_pool ); fd_account_keys_account_keys_root_update( stake_account_keys, account_keys_root ); - fd_bank_mgr_stake_account_keys_save( bank_mgr ); + fd_bank_mgr_stake_account_keys_save( slot_ctx->bank_mgr ); } /* Updates stake delegation in epoch stakes */ @@ -3283,9 +3280,7 @@ fd_stakes_upsert_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account return; } - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( bank_mgr ); + fd_account_keys_global_t * stake_account_keys = fd_bank_mgr_stake_account_keys_modify( slot_ctx->bank_mgr ); fd_account_keys_pair_t_mapnode_t * account_keys_pool = NULL; fd_account_keys_pair_t_mapnode_t * account_keys_root = NULL; @@ -3298,7 +3293,7 @@ fd_stakes_upsert_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account account_keys_root = fd_account_keys_account_keys_root_join( stake_account_keys ); } - fd_delegation_pair_t_mapnode_t * entry = fd_delegation_pair_t_map_find( stakes->stake_delegations_pool, stakes->stake_delegations_root, &key); + fd_delegation_pair_t_mapnode_t * entry = fd_delegation_pair_t_map_find( stakes->stake_delegations_pool, stakes->stake_delegations_root, &key ); if( FD_UNLIKELY( !entry ) ) { fd_account_keys_pair_t_mapnode_t key; fd_memcpy( key.elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) ); @@ -3325,7 +3320,7 @@ fd_stakes_upsert_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account fd_account_keys_account_keys_pool_update( stake_account_keys, account_keys_pool ); fd_account_keys_account_keys_root_update( stake_account_keys, account_keys_root ); - fd_bank_mgr_stake_account_keys_save( bank_mgr ); + fd_bank_mgr_stake_account_keys_save( slot_ctx->bank_mgr ); } void fd_store_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * stake_account ) { diff --git a/src/flamenco/runtime/program/fd_vote_program.c b/src/flamenco/runtime/program/fd_vote_program.c index 0c68492bc8..8a8cb67d0c 100644 --- a/src/flamenco/runtime/program/fd_vote_program.c +++ b/src/flamenco/runtime/program/fd_vote_program.c @@ -2161,10 +2161,8 @@ void fd_vote_record_timestamp_vote_with_slot( fd_exec_slot_ctx_t * slot_ctx, fd_pubkey_t const * vote_acc, long timestamp, - ulong slot ) { - - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + ulong slot, + fd_bank_mgr_t * bank_mgr ) { fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_modify( bank_mgr ); fd_clock_timestamp_vote_t_mapnode_t * pool = fd_clock_timestamp_votes_votes_pool_join( clock_timestamp_votes ); @@ -2921,10 +2919,7 @@ fd_vote_convert_to_current( fd_vote_state_versioned_t * self, static void remove_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_account ) { - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - - fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( bank_mgr ); + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( slot_ctx->bank_mgr ); fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); @@ -2932,7 +2927,7 @@ remove_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_acco fd_vote_accounts_t * epoch_vote_accounts = &epoch_bank->stakes.vote_accounts; if( FD_UNLIKELY( epoch_vote_accounts->vote_accounts_pool==NULL ) ) { FD_LOG_DEBUG(("Vote accounts pool does not exist")); - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); return; } @@ -2945,7 +2940,7 @@ remove_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_acco if( FD_UNLIKELY( vote_account_keys_pool==NULL ) ) { FD_LOG_DEBUG(("Vote accounts pool does not exist")); - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); return; } @@ -2956,23 +2951,20 @@ remove_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_acco fd_account_keys_pair_t_map_remove( vote_account_keys_pool, &vote_account_keys_root, account_key_entry ); } - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); } static void upsert_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_txn_account_t * vote_account ) { - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - - fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( bank_mgr ); + fd_account_keys_global_t * vote_account_keys = fd_bank_mgr_vote_account_keys_modify( slot_ctx->bank_mgr ); fd_account_keys_pair_t_mapnode_t * vote_account_keys_pool = fd_account_keys_account_keys_pool_join( vote_account_keys ); fd_account_keys_pair_t_mapnode_t * vote_account_keys_root = fd_account_keys_account_keys_root_join( vote_account_keys ); if( FD_UNLIKELY( vote_account_keys_pool==NULL ) ) { FD_LOG_DEBUG(( "Vote accounts pool does not exist" )); - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); return; } @@ -2987,7 +2979,7 @@ upsert_vote_account( fd_exec_slot_ctx_t * slot_ctx, // Skip duplicates if( FD_LIKELY( fd_account_keys_pair_t_map_find( vote_account_keys_pool, vote_account_keys_root, &key ) || fd_vote_accounts_pair_t_map_find( epoch_bank->stakes.vote_accounts.vote_accounts_pool, epoch_bank->stakes.vote_accounts.vote_accounts_root, &vote_acc ) ) ) { - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); return; } @@ -2998,9 +2990,9 @@ upsert_vote_account( fd_exec_slot_ctx_t * slot_ctx, fd_memcpy( &new_node->elem.key, vote_account->pubkey, sizeof(fd_pubkey_t)); fd_account_keys_pair_t_map_insert( vote_account_keys_pool, &vote_account_keys_root, new_node ); - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); } else { - fd_bank_mgr_vote_account_keys_save( bank_mgr ); + fd_bank_mgr_vote_account_keys_save( slot_ctx->bank_mgr ); remove_vote_account( slot_ctx, vote_account ); } } diff --git a/src/flamenco/runtime/program/fd_vote_program.h b/src/flamenco/runtime/program/fd_vote_program.h index 14e3eaaa84..6c963ddf35 100644 --- a/src/flamenco/runtime/program/fd_vote_program.h +++ b/src/flamenco/runtime/program/fd_vote_program.h @@ -68,7 +68,8 @@ void fd_vote_record_timestamp_vote_with_slot( fd_exec_slot_ctx_t * slot_ctx, fd_pubkey_t const * vote_acc, long timestamp, - ulong slot ); + ulong slot, + fd_bank_mgr_t * bank_mgr ); struct fd_commission_split { ulong voter_portion; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar.c b/src/flamenco/runtime/sysvar/fd_sysvar.c index 4b98086da3..2e77067b69 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar.c @@ -33,9 +33,7 @@ fd_sysvar_set( fd_exec_slot_ctx_t * slot_ctx, fd_acc_lamports_t lamports_after = fd_ulong_max( lamports_before, fd_rent_exempt_minimum_balance( &epoch_bank->rent, sz ) ); rec->vt->set_lamports( rec, lamports_after ); - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, funk, funk_txn ); - ulong * capitalization = fd_bank_mgr_capitalization_modify( bank_mgr ); + ulong * capitalization = fd_bank_mgr_capitalization_modify( slot_ctx->bank_mgr ); /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank.rs#L1826 */ if( lamports_after > lamports_before ) { @@ -44,7 +42,7 @@ fd_sysvar_set( fd_exec_slot_ctx_t * slot_ctx, *capitalization -= ( lamports_before - lamports_after ); } - fd_bank_mgr_capitalization_save( bank_mgr ); + fd_bank_mgr_capitalization_save( slot_ctx->bank_mgr ); rec->vt->set_data_len( rec, sz ); rec->vt->set_owner( rec, owner ); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_clock.c b/src/flamenco/runtime/sysvar/fd_sysvar_clock.c index e8ccf36e6d..6539aace03 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_clock.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_clock.c @@ -28,14 +28,10 @@ static long timestamp_from_genesis( fd_exec_slot_ctx_t * slot_ctx ) { /* TODO: maybe make types of timestamps the same throughout the runtime codebase. as Solana uses a signed representation */ - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - - - uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( bank_mgr ); + uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( slot_ctx->bank_mgr ); uint128 ns_per_slot = !!ns_per_slot_bm ? *ns_per_slot_bm : 0; - ulong * genesis_creation_time_bm = fd_bank_mgr_genesis_creation_time_query( bank_mgr ); + ulong * genesis_creation_time_bm = fd_bank_mgr_genesis_creation_time_query( slot_ctx->bank_mgr ); ulong genesis_creation_time = !!genesis_creation_time_bm ? *genesis_creation_time_bm : 0; return (long)(genesis_creation_time + ((slot_ctx->slot * ns_per_slot) / NS_IN_S)); @@ -96,9 +92,7 @@ bound_timestamp_estimate( fd_exec_slot_ctx_t * slot_ctx, long estimate, long epoch_start_timestamp ) { - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( bank_mgr ); + uint128 * ns_per_slot_bm = fd_bank_mgr_ns_per_slot_query( slot_ctx->bank_mgr ); uint128 ns_per_slot = !!ns_per_slot_bm ? *ns_per_slot_bm : 0; /* Determine offsets from start of epoch */ /* TODO: handle epoch boundary case */ @@ -130,14 +124,12 @@ estimate_timestamp( fd_exec_slot_ctx_t * slot_ctx ) { /* TODO: bound the estimate to ensure it stays within a certain range of the expected PoH clock: https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/runtime/src/stake_weighted_timestamp.rs#L13 */ - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( bank_mgr ); + fd_clock_timestamp_votes_global_t * clock_timestamp_votes = fd_bank_mgr_clock_timestamp_votes_query( slot_ctx->bank_mgr ); fd_clock_timestamp_vote_t_mapnode_t * votes = !!clock_timestamp_votes ? fd_clock_timestamp_votes_votes_root_join( clock_timestamp_votes ) : NULL; if( NULL==votes ) { return timestamp_from_genesis( slot_ctx ); } - uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_query( bank_mgr ); + uint128 * ns_per_slot = fd_bank_mgr_ns_per_slot_query( slot_ctx->bank_mgr ); /* TODO: actually take the stake-weighted median. For now, just use the root node. */ fd_clock_timestamp_vote_t * head = &votes->elem; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_fees.c b/src/flamenco/runtime/sysvar/fd_sysvar_fees.c index 46a9df84ac..541b2497f4 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_fees.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_fees.c @@ -44,10 +44,8 @@ fd_sysvar_fees_read( fd_funk_t * funk, void fd_sysvar_fees_new_derived( fd_exec_slot_ctx_t * slot_ctx, ulong latest_singatures_per_slot ) { - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - fd_fee_rate_governor_t * base_fee_rate_governor = fd_bank_mgr_fee_rate_governor_query( bank_mgr ); - ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( bank_mgr ); + fd_fee_rate_governor_t * base_fee_rate_governor = fd_bank_mgr_fee_rate_governor_query( slot_ctx->bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( slot_ctx->bank_mgr ); fd_fee_rate_governor_t me = { .target_signatures_per_slot = base_fee_rate_governor->target_signatures_per_slot, @@ -91,21 +89,21 @@ fd_sysvar_fees_new_derived( fd_exec_slot_ctx_t * slot_ctx, me.max_lamports_per_signature = me.target_lamports_per_signature; } - ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( bank_mgr ); + ulong * prev_lamports_per_signature = fd_bank_mgr_prev_lamports_per_signature_modify( slot_ctx->bank_mgr ); if( FD_UNLIKELY( *lamports_per_signature==0UL ) ) { *prev_lamports_per_signature = new_lamports_per_signature; } else { *prev_lamports_per_signature = *lamports_per_signature; } - fd_bank_mgr_prev_lamports_per_signature_save( bank_mgr ); + fd_bank_mgr_prev_lamports_per_signature_save( slot_ctx->bank_mgr ); - base_fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( bank_mgr ); + base_fee_rate_governor = fd_bank_mgr_fee_rate_governor_modify( slot_ctx->bank_mgr ); *base_fee_rate_governor = me; - fd_bank_mgr_fee_rate_governor_save( bank_mgr ); + fd_bank_mgr_fee_rate_governor_save( slot_ctx->bank_mgr ); - lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( bank_mgr ); + lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); *lamports_per_signature = new_lamports_per_signature; - fd_bank_mgr_lamports_per_signature_save( bank_mgr ); + fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); } void @@ -120,9 +118,7 @@ fd_sysvar_fees_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) FD_LOG_ERR(( "failed to read sysvar fees" )); } - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( slot_ctx->bank_mgr ); fees->fee_calculator.lamports_per_signature = *lamports_per_signature; write_fees( slot_ctx, fees ); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c b/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c index 9c8b369b6d..1346d32f2e 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_last_restart_slot.c @@ -12,10 +12,7 @@ fd_sysvar_last_restart_slot_init( fd_exec_slot_ctx_t * slot_ctx ) { return; } - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - - fd_sol_sysvar_last_restart_slot_t const * sysvar = fd_bank_mgr_last_restart_slot_query( bank_mgr ); + fd_sol_sysvar_last_restart_slot_t const * sysvar = fd_bank_mgr_last_restart_slot_query( slot_ctx->bank_mgr ); fd_sol_sysvar_last_restart_slot_t sysvar_default = {0}; sysvar = !!sysvar ? sysvar : &sysvar_default; @@ -76,9 +73,7 @@ fd_sysvar_last_restart_slot_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * r /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2108-L2120 */ /* FIXME: Query hard forks list */ - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - ulong last_restart_slot = fd_bank_mgr_last_restart_slot_query( bank_mgr )->slot; + ulong last_restart_slot = fd_bank_mgr_last_restart_slot_query( slot_ctx->bank_mgr )->slot; /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2122-L2130 */ if( !has_current_last_restart_slot || current_last_restart_slot != last_restart_slot ) { diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c b/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c index 80918db29b..a606c9f6ab 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_recent_hashes.c @@ -25,10 +25,7 @@ static void encode_rbh_from_blockhash_queue( fd_exec_slot_ctx_t * slot_ctx, uchar * enc ) { - fd_bank_mgr_t bank_mgr_obj; - - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( bank_mgr ); + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_query( slot_ctx->bank_mgr ); fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_block_hash_queue_ages_pool_join( bhq ); fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_block_hash_queue_ages_root_join( bhq ); @@ -80,12 +77,10 @@ fd_sysvar_recent_hashes_init( fd_exec_slot_ctx_t * slot_ctx, static void register_blockhash( fd_exec_slot_ctx_t * slot_ctx, fd_hash_t const * hash ) { - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_query( slot_ctx->bank_mgr ); - fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_modify( bank_mgr ); + fd_block_hash_queue_global_t * bhq = fd_bank_mgr_block_hash_queue_modify( slot_ctx->bank_mgr ); fd_hash_hash_age_pair_t_mapnode_t * ages_pool = fd_block_hash_queue_ages_pool_join( bhq ); fd_hash_hash_age_pair_t_mapnode_t * ages_root = fd_block_hash_queue_ages_root_join( bhq ); bhq->last_hash_index++; @@ -118,7 +113,7 @@ register_blockhash( fd_exec_slot_ctx_t * slot_ctx, fd_hash_t const * hash ) { bhq->ages_pool_offset = (ulong)fd_hash_hash_age_pair_t_map_leave( ages_pool ) - (ulong)bhq; bhq->ages_root_offset = (ulong)ages_root - (ulong)bhq; - fd_bank_mgr_block_hash_queue_save( bank_mgr ); + fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); } /* This implementation is more consistent with Agave's bank implementation for updating the block hashes sysvar: @@ -130,9 +125,8 @@ void fd_sysvar_recent_hashes_update( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { FD_SPAD_FRAME_BEGIN( runtime_spad ) { /* Update the blockhash queue */ - fd_bank_mgr_t bank_mgr_obj; - fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); - fd_hash_t * poh = fd_bank_mgr_poh_query( bank_mgr ); + + fd_hash_t * poh = fd_bank_mgr_poh_query( slot_ctx->bank_mgr ); register_blockhash( slot_ctx, poh ); /* Derive the new sysvar recent blockhashes from the blockhash queue */ diff --git a/src/flamenco/runtime/tests/harness/fd_txn_harness.c b/src/flamenco/runtime/tests/harness/fd_txn_harness.c index d3f6def193..1f7fe5ce6c 100644 --- a/src/flamenco/runtime/tests/harness/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_txn_harness.c @@ -34,9 +34,7 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, /* Allocate contexts */ uchar * epoch_ctx_mem = fd_spad_alloc( runner->spad, fd_exec_epoch_ctx_align(), fd_exec_epoch_ctx_footprint( vote_acct_max ) ); - fd_exec_epoch_ctx_t * epoch_ctx - - = fd_exec_epoch_ctx_join( fd_exec_epoch_ctx_new( epoch_ctx_mem, vote_acct_max ) ); + fd_exec_epoch_ctx_t * epoch_ctx = fd_exec_epoch_ctx_join( fd_exec_epoch_ctx_new( epoch_ctx_mem, vote_acct_max ) ); assert( epoch_ctx ); assert( slot_ctx ); @@ -51,6 +49,8 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, slot_ctx->funk = funk; slot_ctx->runtime_wksp = runner->wksp; + slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( slot_ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); + /* Restore feature flags */ fd_exec_test_feature_set_t const * feature_set = &test_ctx->epoch_ctx.features; @@ -89,8 +89,6 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, /* Setup Bank manager */ - slot_ctx->bank_mgr = fd_bank_mgr_join( fd_bank_mgr_new( slot_ctx->bank_mgr_mem ), slot_ctx->funk, slot_ctx->funk_txn ); - ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); *lamports_per_signature = 5000; fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); From a3837ca27b139b9850c7f22e085a5a7d3a8651fb Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 18:58:16 +0000 Subject: [PATCH 5/9] removing prev slot from slot bank --- src/app/ledger/main.c | 4 +++- src/discof/replay/fd_replay_tile.c | 16 +++++++++++----- src/flamenco/runtime/context/fd_exec_slot_ctx.c | 5 ++++- src/flamenco/runtime/fd_bank_mgr.h | 3 ++- src/flamenco/runtime/fd_blockstore.c | 3 ++- src/flamenco/runtime/fd_blockstore_tool.c | 1 - src/flamenco/runtime/fd_hashes.c | 3 ++- src/flamenco/runtime/fd_runtime.c | 13 +++++++++---- .../runtime/sysvar/fd_sysvar_slot_hashes.c | 7 +++++-- src/flamenco/runtime/tests/fd_dump_pb.c | 2 +- .../runtime/tests/harness/fd_block_harness.c | 8 ++++++-- .../runtime/tests/harness/fd_txn_harness.c | 5 ++++- src/flamenco/snapshot/fd_snapshot_create.c | 2 +- src/flamenco/types/fd_fuzz_types.h | 1 - src/flamenco/types/fd_types.c | 7 ------- src/flamenco/types/fd_types.h | 1 - src/flamenco/types/fd_types.json | 1 - 17 files changed, 50 insertions(+), 32 deletions(-) diff --git a/src/app/ledger/main.c b/src/app/ledger/main.c index 7b1fcbe1bc..5f896aea93 100644 --- a/src/app/ledger/main.c +++ b/src/app/ledger/main.c @@ -350,7 +350,9 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { for( ulong slot = start_slot; slot<=ledger_args->end_slot && !aborted; ++slot ) { - ledger_args->slot_ctx->slot_bank.prev_slot = prev_slot; + ulong * prev_slot_bm = fd_bank_mgr_prev_slot_query( ledger_args->slot_ctx->bank_mgr ); + *prev_slot_bm = prev_slot; + fd_bank_mgr_prev_slot_save( ledger_args->slot_ctx->bank_mgr ); FD_LOG_DEBUG(( "reading slot %lu", slot )); diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index c36de65d21..fed30bf5ae 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -1379,8 +1379,10 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( fork->slot_ctx->epoch_ctx ); /* if it is an epoch boundary, push out stake weights */ + + ulong * prev_slot = fd_bank_mgr_prev_slot_query( fork->slot_ctx->bank_mgr ); if( fork->slot_ctx->slot != 0 ) { - is_new_epoch_in_new_block = (int)fd_runtime_is_epoch_boundary( epoch_bank, fork->slot_ctx->slot, fork->slot_ctx->slot_bank.prev_slot ); + is_new_epoch_in_new_block = (int)fd_runtime_is_epoch_boundary( epoch_bank, fork->slot_ctx->slot, *prev_slot ); } fd_block_map_query_t query[1] = { 0 }; @@ -1391,7 +1393,10 @@ prepare_new_block_execution( fd_replay_tile_ctx_t * ctx, // curr_block_info->in_poh_hash = fork->slot_ctx->slot_bank.poh; fd_block_map_publish( query ); - fork->slot_ctx->slot_bank.prev_slot = fork->slot_ctx->slot; + prev_slot = fd_bank_mgr_prev_slot_modify( fork->slot_ctx->bank_mgr ); + *prev_slot = fork->slot_ctx->slot; + fd_bank_mgr_prev_slot_save( fork->slot_ctx->bank_mgr ); + fork->slot_ctx->slot = curr_slot; ulong * max_tick_height = fd_bank_mgr_max_tick_height_query( fork->slot_ctx->bank_mgr ); @@ -2002,7 +2007,9 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, ctx->slot_ctx->slot, ctx->runtime_spad ); - ctx->slot_ctx->slot_bank.prev_slot = 0UL; + ulong * prev_slot = fd_bank_mgr_prev_slot_modify( ctx->slot_ctx->bank_mgr ); + *prev_slot = 0UL; + fd_bank_mgr_prev_slot_save( ctx->slot_ctx->bank_mgr ); ctx->slot_ctx->slot = 1UL; ulong hashcnt_per_slot = *(fd_bank_mgr_hashes_per_tick_query( ctx->slot_ctx->bank_mgr )) * *(fd_bank_mgr_ticks_per_slot_query( ctx->slot_ctx->bank_mgr )); @@ -2029,7 +2036,6 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, ctx->runtime_spad, &exec_para_ctx_block_finalize ); - ctx->slot_ctx->slot_bank.prev_slot = 0UL; ctx->slot_ctx->slot = 1UL; snapshot_slot = 1UL; @@ -2050,7 +2056,7 @@ init_after_snapshot( fd_replay_tile_ctx_t * ctx, } ctx->curr_slot = snapshot_slot; - ctx->parent_slot = ctx->slot_ctx->slot_bank.prev_slot; + ctx->parent_slot = *fd_bank_mgr_prev_slot_query( ctx->slot_ctx->bank_mgr ); ctx->snapshot_slot = snapshot_slot; ctx->blockhash = ( fd_hash_t ){ .hash = { 0 } }; ctx->flags = EXEC_FLAG_READY_NEW; diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.c b/src/flamenco/runtime/context/fd_exec_slot_ctx.c index 534f8ca066..96a701a64a 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.c @@ -240,7 +240,6 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, /* Copy over fields */ - slot_bank->prev_slot = oldbank->parent_slot; fd_memcpy(&slot_bank->banks_hash, &oldbank->hash, sizeof(oldbank->hash)); fd_memcpy(&slot_ctx->slot_bank.prev_banks_hash, &oldbank->parent_hash, sizeof(oldbank->parent_hash)); fd_memcpy( &epoch_bank->epoch_schedule, &oldbank->epoch_schedule, sizeof(fd_epoch_schedule_t) ); @@ -386,6 +385,10 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, } fd_bank_mgr_epoch_account_hash_save( slot_ctx->bank_mgr ); + /* Prev Slot */ + ulong * prev_slot = fd_bank_mgr_prev_slot_modify( slot_ctx->bank_mgr ); + *prev_slot = oldbank->parent_slot; + fd_bank_mgr_prev_slot_save( slot_ctx->bank_mgr ); /* Execution Fees */ diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h index 2d64e945b1..149cf96b35 100644 --- a/src/flamenco/runtime/fd_bank_mgr.h +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -147,7 +147,8 @@ if( FD_UNLIKELY( !bank_mgr ) ) { X(fd_hash_t, poh, 29UL, 32UL, 8UL ) \ X(fd_sol_sysvar_last_restart_slot_t, last_restart_slot, 30UL, 8UL, 8UL ) \ X(fd_rent_fresh_accounts_global_t, rent_fresh_accounts, 31UL, 50000UL, 8UL ) \ - X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) + X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) \ + X(ulong, prev_slot, 33UL, 8UL, 8UL ) FD_BANK_MGR_ITER(BANK_MGR_FUNCTIONS) FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/fd_blockstore.c b/src/flamenco/runtime/fd_blockstore.c index 822dc4acdf..8a9f506dd1 100644 --- a/src/flamenco/runtime/fd_blockstore.c +++ b/src/flamenco/runtime/fd_blockstore.c @@ -252,6 +252,8 @@ fd_blockstore_init( fd_blockstore_t * blockstore, fd_slot_bank_t const * slot_bank, ulong slot ) { + (void)slot_bank; + if( fd_size_max < FD_BLOCKSTORE_ARCHIVE_MIN_SIZE ) { FD_LOG_ERR(( "archive file size too small" )); return NULL; @@ -276,7 +278,6 @@ fd_blockstore_init( fd_blockstore_t * blockstore, if ( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "failed to prepare block map for slot %lu", smr )); ele->slot = smr; - ele->parent_slot = slot_bank->prev_slot; memset( ele->child_slots, UCHAR_MAX, FD_BLOCKSTORE_CHILD_SLOT_MAX * sizeof( ulong ) ); ele->child_slot_cnt = 0; // ele->in_poh_hash = slot_bank->poh; diff --git a/src/flamenco/runtime/fd_blockstore_tool.c b/src/flamenco/runtime/fd_blockstore_tool.c index 55a2743ce1..287adb478e 100644 --- a/src/flamenco/runtime/fd_blockstore_tool.c +++ b/src/flamenco/runtime/fd_blockstore_tool.c @@ -66,7 +66,6 @@ usage( void ) { fd_buf_shred_pool_reset( blockstore->shred_pool, 0 ); \ FD_TEST( blockstore ); \ fd_slot_bank_t slot_bank = { \ - .prev_slot = 0, \ .banks_hash = { .hash = {0} }, \ }; \ fd_slot_bank_new( &slot_bank ); \ diff --git a/src/flamenco/runtime/fd_hashes.c b/src/flamenco/runtime/fd_hashes.c index 5d74b66825..6447503c44 100644 --- a/src/flamenco/runtime/fd_hashes.c +++ b/src/flamenco/runtime/fd_hashes.c @@ -227,7 +227,8 @@ fd_should_include_epoch_accounts_hash( fd_exec_slot_ctx_t * slot_ctx ) { } ulong calculation_stop = *fd_bank_mgr_eah_stop_slot_query( slot_ctx->bank_mgr ); - return slot_ctx->slot_bank.prev_slot < calculation_stop && (slot_ctx->slot >= calculation_stop); + ulong prev_slot = *fd_bank_mgr_prev_slot_query( slot_ctx->bank_mgr ); + return prev_slot < calculation_stop && (slot_ctx->slot >= calculation_stop); } // slot_ctx should be const. diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 2293897544..c6375d4a4b 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -455,8 +455,9 @@ fd_runtime_update_rent_epoch( fd_exec_slot_ctx_t * slot_ctx ) { return; } - ulong slot0 = (slot_ctx->slot_bank.prev_slot == 0) ? 0 : - slot_ctx->slot_bank.prev_slot + 1; /* Accomodate skipped slots */ + ulong * prev_slot = fd_bank_mgr_prev_slot_query( slot_ctx->bank_mgr ); + ulong slot0 = ( *prev_slot == 0 ) ? 0 : + *prev_slot + 1; /* Accomodate skipped slots */ ulong slot1 = slot_ctx->slot; for( ulong s = slot0; s <= slot1; ++s ) { @@ -4317,10 +4318,12 @@ fd_runtime_block_pre_execute_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx, *block_height += 1UL; fd_bank_mgr_block_height_save( slot_ctx->bank_mgr ); + ulong * prev_slot = fd_bank_mgr_prev_slot_query( slot_ctx->bank_mgr ); + if( slot_ctx->slot != 0UL ) { ulong slot_idx; fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - ulong prev_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot_bank.prev_slot, &slot_idx ); + ulong prev_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, *prev_slot, &slot_idx ); ulong new_epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_ctx->slot, &slot_idx ); if( FD_UNLIKELY( slot_idx==1UL && new_epoch==0UL ) ) { /* The block after genesis has a height of 1. */ @@ -4476,7 +4479,9 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, fd_runtime_save_slot_bank( slot_ctx ); - slot_ctx->slot_bank.prev_slot = slot; + ulong * prev_slot = fd_bank_mgr_prev_slot_modify( slot_ctx->bank_mgr ); + *prev_slot = slot; + fd_bank_mgr_prev_slot_save( slot_ctx->bank_mgr ); // FIXME: this shouldn't be doing this, it doesn't work with forking. punting changing it though // slot_ctx->slot = slot+1UL; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c index 82836216f3..1a2da6bd88 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c @@ -4,7 +4,7 @@ #include "../fd_borrowed_account.h" #include "../fd_system_ids.h" #include "../context/fd_exec_slot_ctx.h" - +#include "../fd_bank_mgr.h" /* FIXME These constants should be header defines */ /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/program/src/slot_hashes.rs#L11 */ @@ -116,11 +116,14 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { } } + ulong * prev_slot_bm = fd_bank_mgr_prev_slot_query( slot_ctx->bank_mgr ); + ulong prev_slot = !!prev_slot_bm ? *prev_slot_bm : 0UL; + if( !found ) { // https://github.com/firedancer-io/solana/blob/08a1ef5d785fe58af442b791df6c4e83fe2e7c74/runtime/src/bank.rs#L2371 fd_slot_hash_t slot_hash = { .hash = slot_ctx->slot_bank.banks_hash, // parent hash? - .slot = slot_ctx->slot_bank.prev_slot, // parent_slot + .slot = prev_slot, // parent_slot }; FD_LOG_DEBUG(( "fd_sysvar_slot_hash_update: slot %lu, hash %s", slot_hash.slot, FD_BASE58_ENC_32_ALLOCA( slot_hash.hash.key ) )); diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index c9f18c21c8..5de38ee71d 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -483,7 +483,7 @@ create_block_context_protobuf_from_block( fd_exec_test_block_context_t * block_c // fd_memcpy( block_context->slot_ctx.poh, &slot_ctx->slot_bank.poh, sizeof(fd_pubkey_t) ); // TODO: dump here when process epoch happens after poh verification fd_memcpy( block_context->slot_ctx.parent_bank_hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_pubkey_t) ); fd_memcpy( block_context->slot_ctx.parent_lt_hash, &slot_ctx->slot_bank.lthash.lthash, FD_LTHASH_LEN_BYTES ); - block_context->slot_ctx.prev_slot = slot_ctx->slot_bank.prev_slot; + block_context->slot_ctx.prev_slot = *(fd_bank_mgr_prev_slot_query( bank_mgr )); block_context->slot_ctx.prev_lps = *(fd_bank_mgr_prev_lamports_per_signature_query( bank_mgr )); block_context->slot_ctx.prev_epoch_capitalization = *(fd_bank_mgr_capitalization_query( bank_mgr )); diff --git a/src/flamenco/runtime/tests/harness/fd_block_harness.c b/src/flamenco/runtime/tests/harness/fd_block_harness.c index af61fefccd..38b25b8118 100644 --- a/src/flamenco/runtime/tests/harness/fd_block_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_block_harness.c @@ -86,7 +86,6 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; fd_memcpy( slot_bank->lthash.lthash, test_ctx->slot_ctx.parent_lt_hash, FD_LTHASH_LEN_BYTES ); - slot_bank->prev_slot = test_ctx->slot_ctx.prev_slot; /* Set up epoch context and epoch bank */ /* TODO: Do we need any more of these? */ @@ -96,6 +95,10 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, fd_bank_mgr_t bank_mgr_obj; fd_bank_mgr_t * bank_mgr = fd_bank_mgr_join( &bank_mgr_obj, slot_ctx->funk, slot_ctx->funk_txn ); + ulong * prev_slot = fd_bank_mgr_prev_slot_modify( bank_mgr ); + *prev_slot = test_ctx->slot_ctx.prev_slot; + fd_bank_mgr_prev_slot_save( bank_mgr ); + // self.max_tick_height = (self.slot + 1) * self.ticks_per_slot; ulong * max_tick_height = fd_bank_mgr_max_tick_height_modify( bank_mgr ); *max_tick_height = test_ctx->epoch_ctx.hashes_per_tick; @@ -144,7 +147,8 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, fd_memcpy( &epoch_bank->rent_epoch_schedule, val_epoch_schedule, sizeof(fd_epoch_schedule_t) ); uchar * val_rent = fd_wksp_laddr_fast( runner->wksp, slot_ctx->sysvar_cache->gaddr_rent ); fd_memcpy( &epoch_bank->rent, val_rent, sizeof(fd_rent_t) ); - epoch_bank->stakes.epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, slot_bank->prev_slot, NULL ); + prev_slot = fd_bank_mgr_prev_slot_query( bank_mgr ); + epoch_bank->stakes.epoch = fd_slot_to_epoch( &epoch_bank->epoch_schedule, *prev_slot, NULL ); /* Update stake cache for epoch T */ for( uint i=0U; iepoch_ctx.stake_accounts_count; i++ ) { diff --git a/src/flamenco/runtime/tests/harness/fd_txn_harness.c b/src/flamenco/runtime/tests/harness/fd_txn_harness.c index 1f7fe5ce6c..d49fc84500 100644 --- a/src/flamenco/runtime/tests/harness/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_txn_harness.c @@ -85,10 +85,13 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, /* Set slot bank variables (defaults obtained from GenesisConfig::default() in Agave) */ slot_ctx->slot = slot; - slot_ctx->slot_bank.prev_slot = slot_ctx->slot - 1; // Can underflow, but its fine since it will correctly be ULONG_MAX /* Setup Bank manager */ + ulong * prev_slot = fd_bank_mgr_prev_slot_modify( slot_ctx->bank_mgr ); + *prev_slot = slot_ctx->slot - 1; // Can underflow, but its fine since it will correctly be ULONG_MAX + fd_bank_mgr_prev_slot_save( slot_ctx->bank_mgr ); + ulong * lamports_per_signature = fd_bank_mgr_lamports_per_signature_modify( slot_ctx->bank_mgr ); *lamports_per_signature = 5000; fd_bank_mgr_lamports_per_signature_save( slot_ctx->bank_mgr ); diff --git a/src/flamenco/snapshot/fd_snapshot_create.c b/src/flamenco/snapshot/fd_snapshot_create.c index 0515f008cd..7d18631407 100644 --- a/src/flamenco/snapshot/fd_snapshot_create.c +++ b/src/flamenco/snapshot/fd_snapshot_create.c @@ -632,7 +632,7 @@ fd_snapshot_create_populate_bank( fd_snapshot_ctx_t * snapshot_ctx, bank->hash = slot_bank->banks_hash; bank->parent_hash = slot_bank->prev_banks_hash; - bank->parent_slot = slot_bank->prev_slot; + // bank->parent_slot = slot_bank->prev_slot; // bank->hard_forks = slot_bank->hard_forks; // bank->transaction_count = slot_bank->transaction_count; // bank->signature_count = slot_bank->parent_signature_cnt; diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index 56f488be55..8aee318bc1 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -1825,7 +1825,6 @@ void *fd_slot_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_slot_bank_t *self = (fd_slot_bank_t *) mem; *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_slot_bank_t); fd_slot_bank_new(mem); - self->prev_slot = fd_rng_ulong( rng ); fd_hash_generate( &self->banks_hash, alloc_mem, rng ); fd_vote_accounts_generate( &self->epoch_stakes, alloc_mem, rng ); fd_slot_lthash_generate( &self->lthash, alloc_mem, rng ); diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index 3e228fd97a..caa85c55b9 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -9990,8 +9990,6 @@ int fd_epoch_reward_status_encode( fd_epoch_reward_status_t const * self, fd_bin int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_bincode_uint64_encode( self->prev_slot, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_hash_encode( &self->banks_hash, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_encode( &self->epoch_stakes, ctx ); @@ -10007,8 +10005,6 @@ int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * static int fd_slot_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; - err = fd_bincode_uint64_decode_footprint( ctx ); - if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err; err = fd_hash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_decode_footprint_inner( ctx, total_sz ); @@ -10031,7 +10027,6 @@ int fd_slot_bank_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_ } static void fd_slot_bank_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { fd_slot_bank_t * self = (fd_slot_bank_t *)struct_mem; - fd_bincode_uint64_decode_unsafe( &self->prev_slot, ctx ); fd_hash_decode_inner( &self->banks_hash, alloc_mem, ctx ); fd_vote_accounts_decode_inner( &self->epoch_stakes, alloc_mem, ctx ); fd_slot_lthash_decode_inner( &self->lthash, alloc_mem, ctx ); @@ -10056,7 +10051,6 @@ void fd_slot_bank_new(fd_slot_bank_t * self) { } void fd_slot_bank_walk( void * w, fd_slot_bank_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_slot_bank", level++ ); - fun( w, &self->prev_slot, "prev_slot", FD_FLAMENCO_TYPE_ULONG, "ulong", level ); fd_hash_walk( w, &self->banks_hash, fun, "banks_hash", level ); fd_vote_accounts_walk( w, &self->epoch_stakes, fun, "epoch_stakes", level ); fd_slot_lthash_walk( w, &self->lthash, fun, "lthash", level ); @@ -10066,7 +10060,6 @@ void fd_slot_bank_walk( void * w, fd_slot_bank_t const * self, fd_types_walk_fn_ } ulong fd_slot_bank_size( fd_slot_bank_t const * self ) { ulong size = 0; - size += sizeof(ulong); size += fd_hash_size( &self->banks_hash ); size += fd_vote_accounts_size( &self->epoch_stakes ); size += fd_slot_lthash_size( &self->lthash ); diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index ae4b432ccd..a0d2f57528 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -1765,7 +1765,6 @@ typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; /* Encoded Size: Dynamic */ struct fd_slot_bank { - ulong prev_slot; fd_hash_t banks_hash; fd_vote_accounts_t epoch_stakes; fd_slot_lthash_t lthash; diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 01687262a3..4a59ef5ec6 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -1232,7 +1232,6 @@ "name": "slot_bank", "type": "struct", "fields": [ - { "name": "prev_slot", "type": "ulong" }, { "name": "banks_hash", "type": "hash" }, { "name": "epoch_stakes", "type": "vote_accounts" }, { "name": "lthash", "type": "slot_lthash" }, From 413a8b3c82447ff4dfab51782c745cc3c8c6872e Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 19:03:32 +0000 Subject: [PATCH 6/9] patch --- src/app/ledger/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/ledger/main.c b/src/app/ledger/main.c index 5f896aea93..26db14e6b8 100644 --- a/src/app/ledger/main.c +++ b/src/app/ledger/main.c @@ -350,7 +350,7 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { for( ulong slot = start_slot; slot<=ledger_args->end_slot && !aborted; ++slot ) { - ulong * prev_slot_bm = fd_bank_mgr_prev_slot_query( ledger_args->slot_ctx->bank_mgr ); + ulong * prev_slot_bm = fd_bank_mgr_prev_slot_modify( ledger_args->slot_ctx->bank_mgr ); *prev_slot_bm = prev_slot; fd_bank_mgr_prev_slot_save( ledger_args->slot_ctx->bank_mgr ); From 8213314bb66d3126de7aac7f588202e44e05730f Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 20:14:23 +0000 Subject: [PATCH 7/9] removing bank hash from slot bank --- src/app/ledger/main.c | 5 +++-- src/choreo/forks/fd_forks.c | 4 ++-- src/discof/replay/fd_replay_tile.c | 8 +++++--- src/discof/restart/fd_restart_tile.c | 5 +++-- src/flamenco/runtime/context/fd_exec_slot_ctx.c | 6 +++++- src/flamenco/runtime/fd_bank_mgr.h | 3 ++- src/flamenco/runtime/fd_blockstore_tool.c | 4 +--- src/flamenco/runtime/fd_hashes.c | 6 ++++-- src/flamenco/runtime/fd_runtime.c | 13 ++++++++----- src/flamenco/runtime/fd_runtime_init.c | 12 ++++-------- src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c | 5 +++-- src/flamenco/runtime/tests/fd_dump_pb.c | 3 ++- .../runtime/tests/harness/fd_block_harness.c | 7 +++++-- src/flamenco/snapshot/fd_snapshot_create.c | 2 +- src/flamenco/types/fd_fuzz_types.h | 1 - src/flamenco/types/fd_types.c | 8 -------- src/flamenco/types/fd_types.h | 1 - src/flamenco/types/fd_types.json | 1 - 18 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/app/ledger/main.c b/src/app/ledger/main.c index 26db14e6b8..024f35d32d 100644 --- a/src/app/ledger/main.c +++ b/src/app/ledger/main.c @@ -514,17 +514,18 @@ runtime_replay( fd_ledger_args_t * ledger_args ) { } } + fd_hash_t * bank_hash_bm = fd_bank_mgr_bank_hash_query( ledger_args->slot_ctx->bank_mgr ); err = fd_blockstore_bank_hash_query( blockstore, slot, &expected ); if( FD_UNLIKELY( err) ) { FD_LOG_ERR(( "slot %lu is missing its bank hash", slot )); - } else if( FD_UNLIKELY( 0 != memcmp( ledger_args->slot_ctx->slot_bank.banks_hash.hash, + } else if( FD_UNLIKELY( 0 != memcmp( bank_hash_bm, expected.hash, 32UL ) ) ) { char expected_hash[ FD_BASE58_ENCODED_32_SZ ]; fd_acct_addr_cstr( expected_hash, expected.hash ); char bank_hash[ FD_BASE58_ENCODED_32_SZ ]; - fd_acct_addr_cstr( bank_hash, ledger_args->slot_ctx->slot_bank.banks_hash.hash ); + fd_acct_addr_cstr( bank_hash, bank_hash_bm->hash ); FD_LOG_WARNING(( "Bank hash mismatch! slot=%lu expected=%s, got=%s", slot, diff --git a/src/choreo/forks/fd_forks.c b/src/choreo/forks/fd_forks.c index d49fbb6e8e..f5c98cb578 100644 --- a/src/choreo/forks/fd_forks.c +++ b/src/choreo/forks/fd_forks.c @@ -259,10 +259,10 @@ slot_ctx_restore( ulong slot, // signature_cnt, account_delta_hash, prev_banks_hash are used for the banks // hash calculation and not needed when restoring parent - + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx_out->bank_mgr ); FD_LOG_NOTICE(( "recovered slot_bank for slot=%lu banks_hash=%s", slot_ctx_out->slot, - FD_BASE58_ENC_32_ALLOCA( slot_ctx_out->slot_bank.banks_hash.hash ) )); + FD_BASE58_ENC_32_ALLOCA( bank_hash->hash ) )); /* Prepare bank for next slot */ slot_ctx_out->slot = slot; diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index fed30bf5ae..aef2b508dc 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -1138,7 +1138,8 @@ publish_slot_notifications( fd_replay_tile_ctx_t * ctx, msg->slot_exec.root = fd_fseq_query( ctx->published_wmark ); msg->slot_exec.height = block_entry_block_height; msg->slot_exec.shred_cnt = fork->slot_ctx->shred_cnt; - memcpy( &msg->slot_exec.bank_hash, &fork->slot_ctx->slot_bank.banks_hash, sizeof( fd_hash_t ) ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( fork->slot_ctx->bank_mgr ); + memcpy( &msg->slot_exec.bank_hash, bank_hash, sizeof( fd_hash_t ) ); memcpy( &msg->slot_exec.block_hash, &ctx->blockhash, sizeof( fd_hash_t ) ); memcpy( &msg->slot_exec.identity, ctx->validator_identity_pubkey, sizeof( fd_pubkey_t ) ); msg->slot_exec.ts = tsorig; @@ -1725,7 +1726,8 @@ exec_slice( fd_replay_tile_ctx_t * ctx, FD_COMPILER_MFENCE(); block_info->flags = fd_uchar_clear_bit( block_info->flags, FD_BLOCK_FLAG_REPLAYING ); memcpy( &block_info->block_hash, hdr->hash, sizeof(fd_hash_t) ); - memcpy( &block_info->bank_hash, &fork->slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( fork->slot_ctx->bank_mgr ); + memcpy( &block_info->bank_hash, bank_hash, sizeof(fd_hash_t) ); fd_block_map_publish( query ); ctx->flags = EXEC_FLAG_FINISHED_SLOT; @@ -2620,7 +2622,7 @@ after_credit( fd_replay_tile_ctx_t * ctx, /* Bank hash comparison, and halt if there's a mismatch after replay */ /**********************************************************************/ - fd_hash_t const * bank_hash = &child->slot_ctx->slot_bank.banks_hash; + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( fork->slot_ctx->bank_mgr ); fd_bank_hash_cmp_t * bank_hash_cmp = child->slot_ctx->epoch_ctx->bank_hash_cmp; fd_bank_hash_cmp_lock( bank_hash_cmp ); fd_bank_hash_cmp_insert( bank_hash_cmp, curr_slot, bank_hash, 1, 0 ); diff --git a/src/discof/restart/fd_restart_tile.c b/src/discof/restart/fd_restart_tile.c index 6f6c7beb84..b140eb586a 100644 --- a/src/discof/restart/fd_restart_tile.c +++ b/src/discof/restart/fd_restart_tile.c @@ -335,7 +335,7 @@ after_frag( fd_restart_tile_ctx_t * ctx, fd_funk_txn_end_write( ctx->funk ); /* Copy the bank hash of HeaviestForkSlot to fd_restart_t */ - ctx->restart->heaviest_fork_bank_hash = slot_bank->banks_hash; + // ctx->restart->heaviest_fork_bank_hash = slot_bank->banks_hash; ctx->restart->heaviest_fork_ready = 1; } } @@ -360,6 +360,7 @@ after_credit( fd_restart_tile_ctx_t * ctx, /* Decode the slot bank from funk, referencing fd_runtime_recover_banks() in fd_runtime_init.c */ fd_slot_bank_t * slot_bank = NULL; + (void)slot_bank; { fd_funk_rec_key_t id = fd_runtime_slot_bank_key(); fd_funk_rec_query_t query[1]; @@ -443,7 +444,7 @@ after_credit( fd_restart_tile_ctx_t * ctx, /* FIXME: this has an invalid slot number. */ fd_restart_init( ctx->restart, 0UL, - &slot_bank->banks_hash, + NULL, epoch_stakes, &ctx->epoch_bank.epoch_schedule, ctx->tower_checkpt_fileno, diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.c b/src/flamenco/runtime/context/fd_exec_slot_ctx.c index 96a701a64a..e4c40209c4 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.c @@ -240,7 +240,6 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, /* Copy over fields */ - fd_memcpy(&slot_bank->banks_hash, &oldbank->hash, sizeof(oldbank->hash)); fd_memcpy(&slot_ctx->slot_bank.prev_banks_hash, &oldbank->parent_hash, sizeof(oldbank->parent_hash)); fd_memcpy( &epoch_bank->epoch_schedule, &oldbank->epoch_schedule, sizeof(fd_epoch_schedule_t) ); epoch_bank->rent = oldbank->rent_collector.rent; @@ -278,6 +277,11 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_bank_mgr_block_hash_queue_save( slot_ctx->bank_mgr ); + /* Bank Hash */ + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_modify( slot_ctx->bank_mgr ); + *bank_hash = oldbank->hash; + fd_bank_mgr_bank_hash_save( slot_ctx->bank_mgr ); + /* Slot */ ulong * slot_ptr = fd_bank_mgr_slot_modify( slot_ctx->bank_mgr ); diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h index 149cf96b35..2d18df512f 100644 --- a/src/flamenco/runtime/fd_bank_mgr.h +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -148,7 +148,8 @@ if( FD_UNLIKELY( !bank_mgr ) ) { X(fd_sol_sysvar_last_restart_slot_t, last_restart_slot, 30UL, 8UL, 8UL ) \ X(fd_rent_fresh_accounts_global_t, rent_fresh_accounts, 31UL, 50000UL, 8UL ) \ X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) \ - X(ulong, prev_slot, 33UL, 8UL, 8UL ) + X(ulong, prev_slot, 33UL, 8UL, 8UL ) \ + X(fd_hash_t, bank_hash, 34UL, 32UL, 8UL ) FD_BANK_MGR_ITER(BANK_MGR_FUNCTIONS) FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/fd_blockstore_tool.c b/src/flamenco/runtime/fd_blockstore_tool.c index 287adb478e..2fd6d75ce3 100644 --- a/src/flamenco/runtime/fd_blockstore_tool.c +++ b/src/flamenco/runtime/fd_blockstore_tool.c @@ -65,9 +65,7 @@ usage( void ) { fd_blockstore_t * blockstore = fd_blockstore_join( &blockstore_ljoin, shblockstore ); \ fd_buf_shred_pool_reset( blockstore->shred_pool, 0 ); \ FD_TEST( blockstore ); \ - fd_slot_bank_t slot_bank = { \ - .banks_hash = { .hash = {0} }, \ - }; \ + fd_slot_bank_t slot_bank = {0}; \ fd_slot_bank_new( &slot_bank ); \ int fd = open( "dummy.archv", O_RDWR | O_CREAT, 0666 ); \ FD_TEST( fd > 0 ); diff --git a/src/flamenco/runtime/fd_hashes.c b/src/flamenco/runtime/fd_hashes.c index 6447503c44..aa7452c5e3 100644 --- a/src/flamenco/runtime/fd_hashes.c +++ b/src/flamenco/runtime/fd_hashes.c @@ -238,7 +238,9 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, fd_hash_t * hash, fd_pubkey_hash_pair_t * dirty_keys, ulong dirty_key_cnt ) { - slot_ctx->slot_bank.prev_banks_hash = slot_ctx->slot_bank.banks_hash; + + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ); + slot_ctx->slot_bank.prev_banks_hash = *bank_hash; ulong * signature_cnt_bm = fd_bank_mgr_signature_cnt_query( slot_ctx->bank_mgr ); ulong signature_cnt = !!signature_cnt_bm ? *signature_cnt_bm : 0UL; @@ -265,7 +267,7 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, fd_sha256_t sha; fd_sha256_init( &sha ); - fd_sha256_append( &sha, (uchar const *) &slot_ctx->slot_bank.banks_hash, sizeof( fd_hash_t ) ); + fd_sha256_append( &sha, (uchar const *)bank_hash, sizeof( fd_hash_t ) ); if( !FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ) fd_sha256_append( &sha, (uchar const *) &slot_ctx->account_delta_hash, sizeof( fd_hash_t ) ); fd_sha256_append( &sha, (uchar const *) &signature_cnt, sizeof( ulong ) ); diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index c6375d4a4b..f0b87b052c 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1599,8 +1599,9 @@ fd_runtime_block_execute_finalize_finish( fd_exec_slot_ctx_t * slot_ fd_accounts_hash_task_data_t * task_data, ulong lt_hash_cnt ) { + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ); int err = fd_update_hash_bank_exec_hash( slot_ctx, - &slot_ctx->slot_bank.banks_hash, + bank_hash, capture_ctx, task_data, 1UL, @@ -3447,7 +3448,9 @@ fd_runtime_init_bank_from_genesis( fd_exec_slot_ctx_t * slot_ctx, fd_memcpy( poh_bm->hash, genesis_hash->hash, FD_SHA256_HASH_SZ ); fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); - memset( slot_ctx->slot_bank.banks_hash.hash, 0, FD_SHA256_HASH_SZ ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_modify( slot_ctx->bank_mgr ); + memset( bank_hash->hash, 0, FD_SHA256_HASH_SZ ); + fd_bank_mgr_bank_hash_save( slot_ctx->bank_mgr ); fd_poh_config_t const * poh = &genesis_block->poh_config; fd_exec_epoch_ctx_t * epoch_ctx = slot_ctx->epoch_ctx; @@ -3783,9 +3786,10 @@ fd_runtime_process_genesis_block( fd_exec_slot_ctx_t * slot_ctx, fd_runtime_freeze( slot_ctx, runtime_spad ); /* sort and update bank hash */ + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ); int result = fd_update_hash_bank_tpool( slot_ctx, capture_ctx, - &slot_ctx->slot_bank.banks_hash, + bank_hash, 0UL, NULL, runtime_spad ); @@ -4464,13 +4468,12 @@ fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx, block_eval_time += fd_log_wallclock(); double block_eval_time_ms = (double)block_eval_time * 1e-6; double tps = (double) block_info.txn_cnt / ((double)block_eval_time * 1e-9); - FD_LOG_INFO(( "evaluated block successfully - slot: %lu, elapsed: %6.6f ms, signatures: %lu, txns: %lu, tps: %6.6f, bank_hash: %s, leader: %s", + FD_LOG_INFO(( "evaluated block successfully - slot: %lu, elapsed: %6.6f ms, signatures: %lu, txns: %lu, tps: %6.6f, leader: %s", slot, block_eval_time_ms, block_info.signature_cnt, block_info.txn_cnt, tps, - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ), FD_BASE58_ENC_32_ALLOCA( fd_epoch_leaders_get( fd_exec_epoch_ctx_leaders( slot_ctx->epoch_ctx ), slot ) ) )); ulong * transaction_count = fd_bank_mgr_transaction_count_modify( slot_ctx->bank_mgr ); diff --git a/src/flamenco/runtime/fd_runtime_init.c b/src/flamenco/runtime/fd_runtime_init.c index dad02bf112..9265990c3a 100644 --- a/src/flamenco/runtime/fd_runtime_init.c +++ b/src/flamenco/runtime/fd_runtime_init.c @@ -50,7 +50,7 @@ fd_runtime_save_epoch_bank( fd_exec_slot_ctx_t * slot_ctx ) { fd_funk_rec_publish( funk, prepare ); - FD_LOG_DEBUG(( "epoch frozen, slot=%lu bank_hash=%s", slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ) )); + FD_LOG_DEBUG(( "epoch frozen, slot=%lu", slot_ctx->slot )); return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -99,9 +99,7 @@ int fd_runtime_save_slot_bank( fd_exec_slot_ctx_t * slot_ctx ) { fd_funk_rec_publish( funk, prepare ); - FD_LOG_DEBUG(( "slot frozen, slot=%lu bank_hash=%s", - slot_ctx->slot, - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ) )); + FD_LOG_DEBUG(( "slot frozen, slot=%lu", slot_ctx->slot )); return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -192,10 +190,8 @@ fd_runtime_recover_banks( fd_exec_slot_ctx_t * slot_ctx, continue; } - FD_LOG_NOTICE(( "recovered slot_bank for slot=%ld banks_hash=%s lthash=%s", - (long)slot_ctx->slot, - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.banks_hash.hash ), - FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ) )); + FD_LOG_NOTICE(( "recovered slot_bank for slot=%ld", + (long)slot_ctx->slot )); ulong * execution_fees = fd_bank_mgr_execution_fees_modify( slot_ctx->bank_mgr ); *execution_fees = 0; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c index 1a2da6bd88..027a5e4977 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_slot_hashes.c @@ -111,7 +111,8 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { iter = deq_fd_slot_hash_t_iter_next( hashes, iter ) ) { fd_slot_hash_t * ele = deq_fd_slot_hash_t_iter_ele( hashes, iter ); if( ele->slot == slot_ctx->slot ) { - memcpy( &ele->hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_hash_t) ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ); + memcpy( &ele->hash, bank_hash, sizeof(fd_hash_t) ); found = 1; } } @@ -122,7 +123,7 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) { if( !found ) { // https://github.com/firedancer-io/solana/blob/08a1ef5d785fe58af442b791df6c4e83fe2e7c74/runtime/src/bank.rs#L2371 fd_slot_hash_t slot_hash = { - .hash = slot_ctx->slot_bank.banks_hash, // parent hash? + .hash = *fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ), // parent hash? .slot = prev_slot, // parent_slot }; FD_LOG_DEBUG(( "fd_sysvar_slot_hash_update: slot %lu, hash %s", slot_hash.slot, FD_BASE58_ENC_32_ALLOCA( slot_hash.hash.key ) )); diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 5de38ee71d..c3bd27a4b9 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -481,7 +481,8 @@ create_block_context_protobuf_from_block( fd_exec_test_block_context_t * block_c // HACK FOR NOW: block height gets incremented in process_new_epoch, so we should dump block height + 1 block_context->slot_ctx.block_height = *(fd_bank_mgr_block_height_query( bank_mgr )) + 1UL; // fd_memcpy( block_context->slot_ctx.poh, &slot_ctx->slot_bank.poh, sizeof(fd_pubkey_t) ); // TODO: dump here when process epoch happens after poh verification - fd_memcpy( block_context->slot_ctx.parent_bank_hash, &slot_ctx->slot_bank.banks_hash, sizeof(fd_pubkey_t) ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( bank_mgr ); + fd_memcpy( block_context->slot_ctx.parent_bank_hash, bank_hash, sizeof(fd_pubkey_t) ); fd_memcpy( block_context->slot_ctx.parent_lt_hash, &slot_ctx->slot_bank.lthash.lthash, FD_LTHASH_LEN_BYTES ); block_context->slot_ctx.prev_slot = *(fd_bank_mgr_prev_slot_query( bank_mgr )); block_context->slot_ctx.prev_lps = *(fd_bank_mgr_prev_lamports_per_signature_query( bank_mgr )); diff --git a/src/flamenco/runtime/tests/harness/fd_block_harness.c b/src/flamenco/runtime/tests/harness/fd_block_harness.c index 38b25b8118..50a771a23d 100644 --- a/src/flamenco/runtime/tests/harness/fd_block_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_block_harness.c @@ -80,7 +80,9 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, slot_ctx->runtime_wksp = fd_wksp_containing( slot_ctx ); slot_ctx->slot = slot; - fd_memcpy( &slot_ctx->slot_bank.banks_hash, test_ctx->slot_ctx.parent_bank_hash, sizeof( fd_hash_t ) ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_modify( slot_ctx->bank_mgr ); + fd_memcpy( bank_hash, test_ctx->slot_ctx.parent_bank_hash, sizeof(fd_hash_t) ); + fd_bank_mgr_bank_hash_save( slot_ctx->bank_mgr ); /* Set up slot bank */ fd_slot_bank_t * slot_bank = &slot_ctx->slot_bank; @@ -512,7 +514,8 @@ fd_runtime_fuzz_block_run( fd_runtime_fuzz_runner_t * runner, /* Capture hashes */ uchar out_lt_hash[32]; fd_lthash_hash( (fd_lthash_value_t const *)slot_ctx->slot_bank.lthash.lthash, out_lt_hash ); - fd_memcpy( effects->bank_hash, slot_ctx->slot_bank.banks_hash.hash, sizeof(fd_hash_t) ); + fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ); + fd_memcpy( effects->bank_hash, bank_hash, sizeof(fd_hash_t) ); fd_memcpy( effects->lt_hash, out_lt_hash, sizeof(fd_hash_t) ); fd_memcpy( effects->account_delta_hash, slot_ctx->account_delta_hash.hash, sizeof(fd_hash_t) ); diff --git a/src/flamenco/snapshot/fd_snapshot_create.c b/src/flamenco/snapshot/fd_snapshot_create.c index 7d18631407..fa2bae6a5b 100644 --- a/src/flamenco/snapshot/fd_snapshot_create.c +++ b/src/flamenco/snapshot/fd_snapshot_create.c @@ -630,7 +630,7 @@ fd_snapshot_create_populate_bank( fd_snapshot_ctx_t * snapshot_ctx, bank->ancestors_len = 0UL; bank->ancestors = NULL; - bank->hash = slot_bank->banks_hash; + // bank->hash = slot_bank->banks_hash; bank->parent_hash = slot_bank->prev_banks_hash; // bank->parent_slot = slot_bank->prev_slot; // bank->hard_forks = slot_bank->hard_forks; diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index 8aee318bc1..2f0463f4ec 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -1825,7 +1825,6 @@ void *fd_slot_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_slot_bank_t *self = (fd_slot_bank_t *) mem; *alloc_mem = (uchar *) *alloc_mem + sizeof(fd_slot_bank_t); fd_slot_bank_new(mem); - fd_hash_generate( &self->banks_hash, alloc_mem, rng ); fd_vote_accounts_generate( &self->epoch_stakes, alloc_mem, rng ); fd_slot_lthash_generate( &self->lthash, alloc_mem, rng ); fd_hash_generate( &self->prev_banks_hash, alloc_mem, rng ); diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index caa85c55b9..a36890bdf4 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -9990,8 +9990,6 @@ int fd_epoch_reward_status_encode( fd_epoch_reward_status_t const * self, fd_bin int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * ctx ) { int err; - err = fd_hash_encode( &self->banks_hash, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_encode( &self->epoch_stakes, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_slot_lthash_encode( &self->lthash, ctx ); @@ -10005,8 +10003,6 @@ int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * static int fd_slot_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) { if( ctx->data>=ctx->dataend ) { return FD_BINCODE_ERR_OVERFLOW; }; int err = 0; - err = fd_hash_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; err = fd_slot_lthash_decode_footprint_inner( ctx, total_sz ); @@ -10027,7 +10023,6 @@ int fd_slot_bank_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_ } static void fd_slot_bank_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) { fd_slot_bank_t * self = (fd_slot_bank_t *)struct_mem; - fd_hash_decode_inner( &self->banks_hash, alloc_mem, ctx ); fd_vote_accounts_decode_inner( &self->epoch_stakes, alloc_mem, ctx ); fd_slot_lthash_decode_inner( &self->lthash, alloc_mem, ctx ); fd_hash_decode_inner( &self->prev_banks_hash, alloc_mem, ctx ); @@ -10043,7 +10038,6 @@ void * fd_slot_bank_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { } void fd_slot_bank_new(fd_slot_bank_t * self) { fd_memset( self, 0, sizeof(fd_slot_bank_t) ); - fd_hash_new( &self->banks_hash ); fd_vote_accounts_new( &self->epoch_stakes ); fd_slot_lthash_new( &self->lthash ); fd_hash_new( &self->prev_banks_hash ); @@ -10051,7 +10045,6 @@ void fd_slot_bank_new(fd_slot_bank_t * self) { } void fd_slot_bank_walk( void * w, fd_slot_bank_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_slot_bank", level++ ); - fd_hash_walk( w, &self->banks_hash, fun, "banks_hash", level ); fd_vote_accounts_walk( w, &self->epoch_stakes, fun, "epoch_stakes", level ); fd_slot_lthash_walk( w, &self->lthash, fun, "lthash", level ); fd_hash_walk( w, &self->prev_banks_hash, fun, "prev_banks_hash", level ); @@ -10060,7 +10053,6 @@ void fd_slot_bank_walk( void * w, fd_slot_bank_t const * self, fd_types_walk_fn_ } ulong fd_slot_bank_size( fd_slot_bank_t const * self ) { ulong size = 0; - size += fd_hash_size( &self->banks_hash ); size += fd_vote_accounts_size( &self->epoch_stakes ); size += fd_slot_lthash_size( &self->lthash ); size += fd_hash_size( &self->prev_banks_hash ); diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index a0d2f57528..67ab91861d 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -1765,7 +1765,6 @@ typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; /* Encoded Size: Dynamic */ struct fd_slot_bank { - fd_hash_t banks_hash; fd_vote_accounts_t epoch_stakes; fd_slot_lthash_t lthash; fd_hash_t prev_banks_hash; diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 4a59ef5ec6..c658239099 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -1232,7 +1232,6 @@ "name": "slot_bank", "type": "struct", "fields": [ - { "name": "banks_hash", "type": "hash" }, { "name": "epoch_stakes", "type": "vote_accounts" }, { "name": "lthash", "type": "slot_lthash" }, { "name": "prev_banks_hash", "type": "hash" }, From c191ca5b0a52d6e15b92216d268cad25b048e7ae Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 21:32:22 +0000 Subject: [PATCH 8/9] removing prev bank hash from slot bank --- src/flamenco/runtime/context/fd_exec_slot_ctx.c | 8 +++++++- src/flamenco/runtime/fd_bank_mgr.h | 3 ++- src/flamenco/runtime/fd_hashes.c | 11 +++++++---- src/flamenco/snapshot/fd_snapshot_create.c | 2 +- src/flamenco/types/fd_fuzz_types.h | 1 - src/flamenco/types/fd_types.c | 8 -------- src/flamenco/types/fd_types.h | 1 - src/flamenco/types/fd_types.json | 1 - 8 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/flamenco/runtime/context/fd_exec_slot_ctx.c b/src/flamenco/runtime/context/fd_exec_slot_ctx.c index e4c40209c4..934aa5b278 100644 --- a/src/flamenco/runtime/context/fd_exec_slot_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_slot_ctx.c @@ -240,7 +240,6 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, /* Copy over fields */ - fd_memcpy(&slot_ctx->slot_bank.prev_banks_hash, &oldbank->parent_hash, sizeof(oldbank->parent_hash)); fd_memcpy( &epoch_bank->epoch_schedule, &oldbank->epoch_schedule, sizeof(fd_epoch_schedule_t) ); epoch_bank->rent = oldbank->rent_collector.rent; fd_memcpy( &epoch_bank->rent, &oldbank->rent_collector.rent, sizeof(fd_rent_t) ); @@ -390,6 +389,7 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_bank_mgr_epoch_account_hash_save( slot_ctx->bank_mgr ); /* Prev Slot */ + ulong * prev_slot = fd_bank_mgr_prev_slot_modify( slot_ctx->bank_mgr ); *prev_slot = oldbank->parent_slot; fd_bank_mgr_prev_slot_save( slot_ctx->bank_mgr ); @@ -414,6 +414,12 @@ fd_exec_slot_ctx_recover( fd_exec_slot_ctx_t * slot_ctx, fd_bank_mgr_poh_save( slot_ctx->bank_mgr ); } + /* Prev Bank Hash */ + + fd_hash_t * prev_bank_hash = fd_bank_mgr_prev_bank_hash_modify( slot_ctx->bank_mgr ); + *prev_bank_hash = oldbank->parent_hash; + fd_bank_mgr_prev_bank_hash_save( slot_ctx->bank_mgr ); + /* Last Restart Slot */ /* Update last restart slot diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h index 2d18df512f..91276f841b 100644 --- a/src/flamenco/runtime/fd_bank_mgr.h +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -149,7 +149,8 @@ if( FD_UNLIKELY( !bank_mgr ) ) { X(fd_rent_fresh_accounts_global_t, rent_fresh_accounts, 31UL, 50000UL, 8UL ) \ X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) \ X(ulong, prev_slot, 33UL, 8UL, 8UL ) \ - X(fd_hash_t, bank_hash, 34UL, 32UL, 8UL ) + X(fd_hash_t, bank_hash, 34UL, 32UL, 8UL ) \ + X(fd_hash_t, prev_bank_hash, 35UL, 32UL, 8UL ) FD_BANK_MGR_ITER(BANK_MGR_FUNCTIONS) FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/fd_hashes.c b/src/flamenco/runtime/fd_hashes.c index aa7452c5e3..77d225f25b 100644 --- a/src/flamenco/runtime/fd_hashes.c +++ b/src/flamenco/runtime/fd_hashes.c @@ -240,7 +240,10 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, ulong dirty_key_cnt ) { fd_hash_t * bank_hash = fd_bank_mgr_bank_hash_query( slot_ctx->bank_mgr ); - slot_ctx->slot_bank.prev_banks_hash = *bank_hash; + + fd_hash_t * prev_bank_hash = fd_bank_mgr_prev_bank_hash_modify( slot_ctx->bank_mgr ); + *prev_bank_hash = *bank_hash; + fd_bank_mgr_prev_bank_hash_save( slot_ctx->bank_mgr ); ulong * signature_cnt_bm = fd_bank_mgr_signature_cnt_query( slot_ctx->bank_mgr ); ulong signature_cnt = !!signature_cnt_bm ? *signature_cnt_bm : 0UL; @@ -303,7 +306,7 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, fd_solcap_write_bank_preimage( capture_ctx->capture, hash->hash, - slot_ctx->slot_bank.prev_banks_hash.hash, + prev_bank_hash, FD_FEATURE_ACTIVE( slot_ctx->slot, slot_ctx->epoch_ctx->features, remove_accounts_delta_hash) ? NULL : slot_ctx->account_delta_hash.hash, lthash, poh, @@ -320,7 +323,7 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, "last_blockhash: %s\n", slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( hash->hash ), - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.prev_banks_hash.hash ), + FD_BASE58_ENC_32_ALLOCA( prev_bank_hash ), FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ), signature_cnt, FD_BASE58_ENC_32_ALLOCA( poh->hash ) )); @@ -335,7 +338,7 @@ fd_hash_bank( fd_exec_slot_ctx_t * slot_ctx, "last_blockhash: %s\n", slot_ctx->slot, FD_BASE58_ENC_32_ALLOCA( hash->hash ), - FD_BASE58_ENC_32_ALLOCA( slot_ctx->slot_bank.prev_banks_hash.hash ), + FD_BASE58_ENC_32_ALLOCA( prev_bank_hash ), FD_BASE58_ENC_32_ALLOCA( slot_ctx->account_delta_hash.hash ), FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *) slot_ctx->slot_bank.lthash.lthash ), signature_cnt, diff --git a/src/flamenco/snapshot/fd_snapshot_create.c b/src/flamenco/snapshot/fd_snapshot_create.c index fa2bae6a5b..2233f9ee0f 100644 --- a/src/flamenco/snapshot/fd_snapshot_create.c +++ b/src/flamenco/snapshot/fd_snapshot_create.c @@ -631,7 +631,7 @@ fd_snapshot_create_populate_bank( fd_snapshot_ctx_t * snapshot_ctx, bank->ancestors = NULL; // bank->hash = slot_bank->banks_hash; - bank->parent_hash = slot_bank->prev_banks_hash; + // bank->parent_hash = slot_bank->prev_banks_hash; // bank->parent_slot = slot_bank->prev_slot; // bank->hard_forks = slot_bank->hard_forks; // bank->transaction_count = slot_bank->transaction_count; diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index 2f0463f4ec..cfde99ca9a 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -1827,7 +1827,6 @@ void *fd_slot_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_slot_bank_new(mem); fd_vote_accounts_generate( &self->epoch_stakes, alloc_mem, rng ); fd_slot_lthash_generate( &self->lthash, alloc_mem, rng ); - fd_hash_generate( &self->prev_banks_hash, alloc_mem, rng ); fd_epoch_reward_status_generate( &self->epoch_reward_status, alloc_mem, rng ); return mem; } diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index a36890bdf4..e383023628 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -9994,8 +9994,6 @@ int fd_slot_bank_encode( fd_slot_bank_t const * self, fd_bincode_encode_ctx_t * if( FD_UNLIKELY( err ) ) return err; err = fd_slot_lthash_encode( &self->lthash, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_encode( &self->prev_banks_hash, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_reward_status_encode( &self->epoch_reward_status, ctx ); if( FD_UNLIKELY( err ) ) return err; return FD_BINCODE_SUCCESS; @@ -10007,8 +10005,6 @@ static int fd_slot_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, u if( FD_UNLIKELY( err ) ) return err; err = fd_slot_lthash_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_reward_status_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; return 0; @@ -10025,7 +10021,6 @@ static void fd_slot_bank_decode_inner( void * struct_mem, void * * alloc_mem, fd fd_slot_bank_t * self = (fd_slot_bank_t *)struct_mem; fd_vote_accounts_decode_inner( &self->epoch_stakes, alloc_mem, ctx ); fd_slot_lthash_decode_inner( &self->lthash, alloc_mem, ctx ); - fd_hash_decode_inner( &self->prev_banks_hash, alloc_mem, ctx ); fd_epoch_reward_status_decode_inner( &self->epoch_reward_status, alloc_mem, ctx ); } void * fd_slot_bank_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) { @@ -10040,14 +10035,12 @@ void fd_slot_bank_new(fd_slot_bank_t * self) { fd_memset( self, 0, sizeof(fd_slot_bank_t) ); fd_vote_accounts_new( &self->epoch_stakes ); fd_slot_lthash_new( &self->lthash ); - fd_hash_new( &self->prev_banks_hash ); fd_epoch_reward_status_new( &self->epoch_reward_status ); } void fd_slot_bank_walk( void * w, fd_slot_bank_t const * self, fd_types_walk_fn_t fun, const char *name, uint level ) { fun( w, self, name, FD_FLAMENCO_TYPE_MAP, "fd_slot_bank", level++ ); fd_vote_accounts_walk( w, &self->epoch_stakes, fun, "epoch_stakes", level ); fd_slot_lthash_walk( w, &self->lthash, fun, "lthash", level ); - fd_hash_walk( w, &self->prev_banks_hash, fun, "prev_banks_hash", level ); fd_epoch_reward_status_walk( w, &self->epoch_reward_status, fun, "epoch_reward_status", level ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_slot_bank", level-- ); } @@ -10055,7 +10048,6 @@ ulong fd_slot_bank_size( fd_slot_bank_t const * self ) { ulong size = 0; size += fd_vote_accounts_size( &self->epoch_stakes ); size += fd_slot_lthash_size( &self->lthash ); - size += fd_hash_size( &self->prev_banks_hash ); size += fd_epoch_reward_status_size( &self->epoch_reward_status ); return size; } diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index 67ab91861d..7880494c74 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -1767,7 +1767,6 @@ typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; struct fd_slot_bank { fd_vote_accounts_t epoch_stakes; fd_slot_lthash_t lthash; - fd_hash_t prev_banks_hash; fd_epoch_reward_status_t epoch_reward_status; }; typedef struct fd_slot_bank fd_slot_bank_t; diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index c658239099..3e5badbfd5 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -1234,7 +1234,6 @@ "fields": [ { "name": "epoch_stakes", "type": "vote_accounts" }, { "name": "lthash", "type": "slot_lthash" }, - { "name": "prev_banks_hash", "type": "hash" }, { "name": "epoch_reward_status", "type": "epoch_reward_status" } ] }, From 284d3a3e5863c6978c8b7ebd8ba7a59900ccc717 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 16 May 2025 21:49:49 +0000 Subject: [PATCH 9/9] genesis hash --- src/discof/replay/fd_replay_tile.c | 3 ++- src/discof/rpcserver/fd_rpc_service.c | 2 +- src/flamenco/runtime/fd_bank_mgr.h | 3 ++- src/flamenco/runtime/fd_runtime.c | 6 +++--- src/flamenco/runtime/tests/harness/fd_block_harness.c | 4 +++- src/flamenco/runtime/tests/harness/fd_txn_harness.c | 8 ++++++-- src/flamenco/types/fd_fuzz_types.h | 1 - src/flamenco/types/fd_types.c | 8 -------- src/flamenco/types/fd_types.h | 1 - src/flamenco/types/fd_types.json | 1 - 10 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/discof/replay/fd_replay_tile.c b/src/discof/replay/fd_replay_tile.c index aef2b508dc..672d4d04fa 100644 --- a/src/discof/replay/fd_replay_tile.c +++ b/src/discof/replay/fd_replay_tile.c @@ -2182,7 +2182,8 @@ init_snapshot( fd_replay_tile_ctx_t * ctx, init_after_snapshot( ctx, stem ); if( ctx->replay_plugin_out_mem && strlen( ctx->genesis ) > 0 ) { - replay_plugin_publish( ctx, stem, FD_PLUGIN_MSG_GENESIS_HASH_KNOWN, ctx->epoch_ctx->epoch_bank.genesis_hash.uc, sizeof(fd_hash_t) ); + fd_hash_t * genesis_hash = fd_bank_mgr_genesis_hash_query( ctx->slot_ctx->bank_mgr ); + replay_plugin_publish( ctx, stem, FD_PLUGIN_MSG_GENESIS_HASH_KNOWN, genesis_hash->hash, sizeof(fd_hash_t) ); } /* Redirect ctx->slot_ctx to point to the memory inside forks. */ diff --git a/src/discof/rpcserver/fd_rpc_service.c b/src/discof/rpcserver/fd_rpc_service.c index d4affc843d..ae91dbc064 100644 --- a/src/discof/rpcserver/fd_rpc_service.c +++ b/src/discof/rpcserver/fd_rpc_service.c @@ -861,7 +861,7 @@ method_getGenesisHash(struct json_values* values, fd_rpc_ctx_t * ctx) { } fd_webserver_t * ws = &ctx->global->ws; fd_web_reply_sprintf(ws, "{\"jsonrpc\":\"2.0\",\"result\":\""); - fd_web_reply_encode_base58(ws, epoch_bank->genesis_hash.uc, sizeof(fd_pubkey_t)); + // fd_web_reply_encode_base58(ws, epoch_bank->genesis_hash.uc, sizeof(fd_pubkey_t)); fd_web_reply_sprintf(ws, "\",\"id\":%s}" CRLF, ctx->call_id); } FD_SPAD_FRAME_END; return 0; diff --git a/src/flamenco/runtime/fd_bank_mgr.h b/src/flamenco/runtime/fd_bank_mgr.h index 91276f841b..5ade09994b 100644 --- a/src/flamenco/runtime/fd_bank_mgr.h +++ b/src/flamenco/runtime/fd_bank_mgr.h @@ -150,7 +150,8 @@ if( FD_UNLIKELY( !bank_mgr ) ) { X(fd_cluster_version_t, cluster_version, 32UL, 12UL, 4UL ) \ X(ulong, prev_slot, 33UL, 8UL, 8UL ) \ X(fd_hash_t, bank_hash, 34UL, 32UL, 8UL ) \ - X(fd_hash_t, prev_bank_hash, 35UL, 32UL, 8UL ) + X(fd_hash_t, prev_bank_hash, 35UL, 32UL, 8UL ) \ + X(fd_hash_t, genesis_hash, 36UL, 32UL, 8UL ) FD_BANK_MGR_ITER(BANK_MGR_FUNCTIONS) FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index f0b87b052c..00df3f8b85 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -3829,8 +3829,6 @@ fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx, FD_LOG_ERR(("cannot open %s : %s", genesis_filepath, strerror(errno))); } - fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx ); - fd_genesis_solana_t * genesis_block; fd_hash_t genesis_hash; @@ -3861,7 +3859,9 @@ fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx, // The hash is generated from the raw data... don't mess with this.. fd_sha256_hash( buf, sz, genesis_hash.uc ); - fd_memcpy( epoch_bank->genesis_hash.uc, genesis_hash.uc, sizeof(fd_hash_t) ); + fd_hash_t * genesis_hash_bm = fd_bank_mgr_genesis_hash_modify( slot_ctx->bank_mgr ); + fd_memcpy( genesis_hash_bm, buf, sizeof(fd_hash_t) ); + fd_bank_mgr_genesis_hash_save( slot_ctx->bank_mgr ); if( !is_snapshot ) { fd_runtime_init_bank_from_genesis( slot_ctx, diff --git a/src/flamenco/runtime/tests/harness/fd_block_harness.c b/src/flamenco/runtime/tests/harness/fd_block_harness.c index 50a771a23d..545fadfa4b 100644 --- a/src/flamenco/runtime/tests/harness/fd_block_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_block_harness.c @@ -298,7 +298,9 @@ fd_runtime_fuzz_block_ctx_create( fd_runtime_fuzz_runner_t * runner, fd_bank_mgr_rent_fresh_accounts_save( bank_mgr ); // Set genesis hash to {0} - fd_memset( &epoch_bank->genesis_hash, 0, sizeof(fd_hash_t) ); + fd_hash_t * genesis_hash = fd_bank_mgr_genesis_hash_modify( bank_mgr ); + fd_memset( genesis_hash->hash, 0, sizeof(fd_hash_t) ); + fd_bank_mgr_genesis_hash_save( bank_mgr ); // Use the latest lamports per signature fd_recent_block_hashes_global_t const * rbh_global = fd_sysvar_cache_recent_block_hashes( slot_ctx->sysvar_cache, runner->wksp ); diff --git a/src/flamenco/runtime/tests/harness/fd_txn_harness.c b/src/flamenco/runtime/tests/harness/fd_txn_harness.c index d49fc84500..015e8c0aae 100644 --- a/src/flamenco/runtime/tests/harness/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/harness/fd_txn_harness.c @@ -263,7 +263,9 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, // Blockhash_queue[end] = last (latest) hash // Blockhash_queue[0] = genesis hash if( num_blockhashes > 0 ) { - memcpy( &epoch_bank->genesis_hash, test_ctx->blockhash_queue[0]->bytes, sizeof(fd_hash_t) ); + fd_hash_t * genesis_hash = fd_bank_mgr_genesis_hash_modify( slot_ctx->bank_mgr ); + memcpy( genesis_hash->hash, test_ctx->blockhash_queue[0]->bytes, sizeof(fd_hash_t) ); + fd_bank_mgr_genesis_hash_save( slot_ctx->bank_mgr ); for( ulong i = 0; i < num_blockhashes; ++i ) { // Recent block hashes cap is 150 (actually 151), while blockhash queue capacity is 300 (actually 301) @@ -277,7 +279,9 @@ fd_runtime_fuzz_txn_ctx_create( fd_runtime_fuzz_runner_t * runner, } else { // Add a default empty blockhash and use it as genesis num_blockhashes = 1; - memcpy( &epoch_bank->genesis_hash, empty_bytes, sizeof(fd_hash_t) ); + fd_hash_t * genesis_hash = fd_bank_mgr_genesis_hash_modify( slot_ctx->bank_mgr ); + memcpy( genesis_hash->hash, empty_bytes, sizeof(fd_hash_t) ); + fd_bank_mgr_genesis_hash_save( slot_ctx->bank_mgr ); fd_block_block_hash_entry_t blockhash_entry; memcpy( &blockhash_entry.blockhash, empty_bytes, sizeof(fd_hash_t) ); fd_hash_t * poh = fd_bank_mgr_poh_modify( slot_ctx->bank_mgr ); diff --git a/src/flamenco/types/fd_fuzz_types.h b/src/flamenco/types/fd_fuzz_types.h index cfde99ca9a..f6eb2e2268 100644 --- a/src/flamenco/types/fd_fuzz_types.h +++ b/src/flamenco/types/fd_fuzz_types.h @@ -1637,7 +1637,6 @@ void *fd_epoch_bank_generate( void *mem, void **alloc_mem, fd_rng_t * rng ) { fd_stakes_generate( &self->stakes, alloc_mem, rng ); fd_epoch_schedule_generate( &self->epoch_schedule, alloc_mem, rng ); fd_rent_generate( &self->rent, alloc_mem, rng ); - fd_hash_generate( &self->genesis_hash, alloc_mem, rng ); fd_vote_accounts_generate( &self->next_epoch_stakes, alloc_mem, rng ); fd_epoch_schedule_generate( &self->rent_epoch_schedule, alloc_mem, rng ); return mem; diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index e383023628..10fd20c430 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -8914,8 +8914,6 @@ int fd_epoch_bank_encode( fd_epoch_bank_t const * self, fd_bincode_encode_ctx_t if( FD_UNLIKELY( err ) ) return err; err = fd_rent_encode( &self->rent, ctx ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_encode( &self->genesis_hash, ctx ); - if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_encode( &self->next_epoch_stakes, ctx ); if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_schedule_encode( &self->rent_epoch_schedule, ctx ); @@ -8931,8 +8929,6 @@ static int fd_epoch_bank_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, if( FD_UNLIKELY( err ) ) return err; err = fd_rent_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; - err = fd_hash_decode_footprint_inner( ctx, total_sz ); - if( FD_UNLIKELY( err ) ) return err; err = fd_vote_accounts_decode_footprint_inner( ctx, total_sz ); if( FD_UNLIKELY( err ) ) return err; err = fd_epoch_schedule_decode_footprint_inner( ctx, total_sz ); @@ -8952,7 +8948,6 @@ static void fd_epoch_bank_decode_inner( void * struct_mem, void * * alloc_mem, f fd_stakes_decode_inner( &self->stakes, alloc_mem, ctx ); fd_epoch_schedule_decode_inner( &self->epoch_schedule, alloc_mem, ctx ); fd_rent_decode_inner( &self->rent, alloc_mem, ctx ); - fd_hash_decode_inner( &self->genesis_hash, alloc_mem, ctx ); fd_vote_accounts_decode_inner( &self->next_epoch_stakes, alloc_mem, ctx ); fd_epoch_schedule_decode_inner( &self->rent_epoch_schedule, alloc_mem, ctx ); } @@ -8969,7 +8964,6 @@ void fd_epoch_bank_new(fd_epoch_bank_t * self) { fd_stakes_new( &self->stakes ); fd_epoch_schedule_new( &self->epoch_schedule ); fd_rent_new( &self->rent ); - fd_hash_new( &self->genesis_hash ); fd_vote_accounts_new( &self->next_epoch_stakes ); fd_epoch_schedule_new( &self->rent_epoch_schedule ); } @@ -8978,7 +8972,6 @@ void fd_epoch_bank_walk( void * w, fd_epoch_bank_t const * self, fd_types_walk_f fd_stakes_walk( w, &self->stakes, fun, "stakes", level ); fd_epoch_schedule_walk( w, &self->epoch_schedule, fun, "epoch_schedule", level ); fd_rent_walk( w, &self->rent, fun, "rent", level ); - fd_hash_walk( w, &self->genesis_hash, fun, "genesis_hash", level ); fd_vote_accounts_walk( w, &self->next_epoch_stakes, fun, "next_epoch_stakes", level ); fd_epoch_schedule_walk( w, &self->rent_epoch_schedule, fun, "rent_epoch_schedule", level ); fun( w, self, name, FD_FLAMENCO_TYPE_MAP_END, "fd_epoch_bank", level-- ); @@ -8988,7 +8981,6 @@ ulong fd_epoch_bank_size( fd_epoch_bank_t const * self ) { size += fd_stakes_size( &self->stakes ); size += fd_epoch_schedule_size( &self->epoch_schedule ); size += fd_rent_size( &self->rent ); - size += fd_hash_size( &self->genesis_hash ); size += fd_vote_accounts_size( &self->next_epoch_stakes ); size += fd_epoch_schedule_size( &self->rent_epoch_schedule ); return size; diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index 7880494c74..2e7203ce5d 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -1552,7 +1552,6 @@ struct fd_epoch_bank { fd_stakes_t stakes; fd_epoch_schedule_t epoch_schedule; fd_rent_t rent; - fd_hash_t genesis_hash; fd_vote_accounts_t next_epoch_stakes; fd_epoch_schedule_t rent_epoch_schedule; }; diff --git a/src/flamenco/types/fd_types.json b/src/flamenco/types/fd_types.json index 3e5badbfd5..baa0b3dbcc 100644 --- a/src/flamenco/types/fd_types.json +++ b/src/flamenco/types/fd_types.json @@ -1095,7 +1095,6 @@ { "name": "stakes", "type": "stakes" }, { "name": "epoch_schedule", "type": "epoch_schedule" }, { "name": "rent", "type": "rent" }, - { "name": "genesis_hash", "type": "hash" }, { "name": "next_epoch_stakes", "type": "vote_accounts"}, { "name": "rent_epoch_schedule", "type": "epoch_schedule" } ]