diff --git a/src/app/fddev/configure/genesis.c b/src/app/fddev/configure/genesis.c index 621b958e5a..62a2ae1600 100644 --- a/src/app/fddev/configure/genesis.c +++ b/src/app/fddev/configure/genesis.c @@ -11,12 +11,81 @@ #include "../../../ballet/poh/fd_poh.h" #include "../../../disco/keyguard/fd_keyload.h" +#include "../../../flamenco/features/fd_features.h" #include "../../../flamenco/genesis/fd_genesis_create.h" #include "../../../flamenco/types/fd_types_custom.h" #include "../../../flamenco/runtime/sysvar/fd_sysvar_clock.h" #define NAME "genesis" +/* default_enable_features is a table of features enabled by default */ + +static void +default_enable_features( fd_features_t * features ) { + features->index_erasure_conflict_duplicate_proofs = 0UL; + features->curve25519_restrict_msm_length = 0UL; + features->commission_updates_only_allowed_in_first_half_of_epoch = 0UL; + features->validate_fee_collector_account = 0UL; + features->zk_token_sdk_enabled = 0UL; + features->enable_zk_transfer_with_fee = 0UL; + features->incremental_snapshot_only_incremental_hash_calculation = 0UL; + features->stake_redelegate_instruction = 0UL; + features->timely_vote_credits = 0UL; + features->apply_cost_tracker_during_replay = 0UL; + features->reject_callx_r10 = 0UL; + features->update_hashes_per_tick = 0UL; + features->enable_partitioned_epoch_reward = 0UL; + features->pico_inflation = 0UL; + features->libsecp256k1_fail_on_bad_count2 = 0UL; + features->remaining_compute_units_syscall_enabled = 0UL; + features->simplify_writable_program_account_check = 0UL; + features->set_exempt_rent_epoch_max = 0UL; + features->enable_bpf_loader_set_authority_checked_ix = 0UL; + features->consume_blockstore_duplicate_proofs = 0UL; + features->disable_deploy_of_alloc_free_syscall = 0UL; + features->disable_bpf_loader_instructions = 0UL; + features->full_inflation_enable = 0UL; + features->vote_state_add_vote_latency = 0UL; + features->curve25519_syscall_enabled = 0UL; + features->error_on_syscall_bpf_function_hash_collisions = 0UL; + features->update_hashes_per_tick3 = 0UL; + features->update_hashes_per_tick4 = 0UL; + features->enable_bpf_loader_extend_program_ix = 0UL; + features->libsecp256k1_fail_on_bad_count = 0UL; + features->enable_program_runtime_v2_and_loader_v4 = 0UL; + features->increase_tx_account_lock_limit = 0UL; + features->stake_raise_minimum_delegation_to_1_sol = 0UL; + features->enable_alt_bn128_syscall = 0UL; + features->revise_turbine_epoch_stakes = 0UL; + features->clean_up_delegation_errors = 0UL; + features->update_hashes_per_tick5 = 0UL; + features->full_inflation_vote = 0UL; + features->skip_rent_rewrites = 0UL; + features->switch_to_new_elf_parser = 0UL; + features->require_rent_exempt_split_destination = 0UL; + features->enable_turbine_fanout_experiments = 0UL; + features->devnet_and_testnet = 0UL; + features->enable_big_mod_exp_syscall = 0UL; + features->enable_alt_bn128_compression_syscall = 0UL; + features->update_hashes_per_tick2 = 0UL; + features->include_loaded_accounts_data_size_in_fee_calculation = 0UL; + features->bpf_account_data_direct_mapping = 0UL; + features->relax_authority_signer_check_for_lookup_table_creation = 0UL; + features->update_hashes_per_tick6 = 0UL; + features->enable_poseidon_syscall = 0UL; + features->better_error_codes_for_tx_lamport_check = 0UL; + features->stake_minimum_delegation_for_rewards = 0UL; + features->loosen_cpi_size_restriction = 0UL; + features->drop_legacy_shreds = 0UL; + features->deprecate_rewards_sysvar = 0UL; + features->warp_timestamp_again = 0UL; + features->reduce_stake_warmup_cooldown = 0UL; + features->disable_turbine_fanout_experiments = 0UL; + features->blake3_syscall_enabled = 0UL; + features->last_restart_slot_sysvar = 0UL; + features->disable_fees_sysvar = 0UL; +} + /* estimate_hashes_per_tick approximates the PoH hashrate of the current tile. Spins PoH hashing for estimate_dur_ns nanoseconds. Returns the hashes per tick achieved, where tick_mhz is the target tick rate @@ -45,6 +114,7 @@ estimate_hashes_per_tick( ulong tick_mhz, return (ulong)hashes_per_tick; } + /* Create a new genesis.bin file contents into the provided blob buffer and return the size of the buffer. Will abort on error if the provided buffer is not large enough. */ @@ -53,39 +123,34 @@ static ulong create_genesis( config_t * const config, uchar * blob, ulong blob_sz ) { + + fd_genesis_options_t options[1]; + /* Read in keys */ uchar const * identity_pubkey_ = fd_keyload_load( config->consensus.identity_path, 1 ); if( FD_UNLIKELY( !identity_pubkey_ ) ) FD_LOG_ERR(( "Failed to load identity key" )); - fd_pubkey_t identity_pubkey; memcpy( identity_pubkey.key, identity_pubkey_, 32 ); + memcpy( options->identity_pubkey.key, identity_pubkey_, 32 ); char file_path[ PATH_MAX ]; FD_TEST( fd_cstr_printf_check( file_path, PATH_MAX, NULL, "%s/faucet.json", config->scratch_directory ) ); uchar const * faucet_pubkey_ = fd_keyload_load( file_path, 1 ); if( FD_UNLIKELY( !faucet_pubkey_ ) ) FD_LOG_ERR(( "Failed to load faucet key" )); - fd_pubkey_t faucet_pubkey; memcpy( faucet_pubkey.key, faucet_pubkey_, 32 ); + memcpy( options->faucet_pubkey.key, faucet_pubkey_, 32 ); FD_TEST( fd_cstr_printf_check( file_path, PATH_MAX, NULL, "%s/stake-account.json", config->scratch_directory ) ); uchar const * stake_pubkey_ = fd_keyload_load( file_path, 1 ); if( FD_UNLIKELY( !stake_pubkey_ ) ) FD_LOG_ERR(( "Failed to load stake account key" )); - fd_pubkey_t stake_pubkey; memcpy( stake_pubkey.key, stake_pubkey_, 32 ); + memcpy( options->stake_pubkey.key, stake_pubkey_, 32 ); FD_TEST( fd_cstr_printf_check( file_path, PATH_MAX, NULL, "%s/vote-account.json", config->scratch_directory ) ); uchar const * vote_pubkey_ = fd_keyload_load( file_path, 1 ); if( FD_UNLIKELY( !vote_pubkey_ ) ) FD_LOG_ERR(( "Failed to load vote account key" )); - fd_pubkey_t vote_pubkey; memcpy( vote_pubkey.key, vote_pubkey_, 32 ); - - uchar pod_mem[ 8192 ]; - uchar * pod = fd_pod_join( fd_pod_new( pod_mem, sizeof(pod_mem) ) ); - - fd_pod_insert_pubkey( pod, "identity.pubkey", &identity_pubkey ); - fd_pod_insert_pubkey( pod, "faucet.pubkey", &faucet_pubkey ); - fd_pod_insert_pubkey( pod, "stake.pubkey", &stake_pubkey ); - fd_pod_insert_pubkey( pod, "vote.pubkey", &vote_pubkey ); + memcpy( options->vote_pubkey.key, vote_pubkey_, 32 ); - fd_pod_insert_ulong( pod, "creation_time", (ulong)fd_log_wallclock() / (ulong)1e9 ); - fd_pod_insert_ulong( pod, "faucet.balance", 500000000000000000UL ); + options->creation_time = (ulong)fd_log_wallclock() / (ulong)1e9; + options->faucet_balance = 500000000000000000UL; /* Set up PoH config */ @@ -102,24 +167,32 @@ create_genesis( config_t * const config, hashes_per_tick = FD_SYSVAR_CLOCK_DEFAULT_HASHES_PER_TICK; } - fd_pod_insert_ulong( pod, "hashes_per_tick", hashes_per_tick ); + options->hashes_per_tick = hashes_per_tick; } else if( 1UL==config->development.genesis.hashes_per_tick ) { - /* do not set hashes_per_tick field */ + /* set hashes_per_tick field to 0, which means sleep mode */ + options->hashes_per_tick = 0UL; } else { /* set hashes_per_tick to the specified value */ - fd_pod_insert_ulong( pod, "hashes_per_tick", config->development.genesis.hashes_per_tick ); + options->hashes_per_tick = config->development.genesis.hashes_per_tick; } - fd_pod_insert_ulong( pod, "ticks_per_slot", config->development.genesis.ticks_per_slot ); - fd_pod_insert_ulong( pod, "target_tick_µs", config->development.genesis.target_tick_duration_micros ); + options->ticks_per_slot = config->development.genesis.ticks_per_slot; + options->target_tick_duration_micros = config->development.genesis.target_tick_duration_micros; + + options->fund_initial_accounts = config->development.genesis.fund_initial_accounts; + options->fund_initial_amount_lamports = config->development.genesis.fund_initial_amount_lamports; + + fd_features_t features[1]; + fd_features_disable_all( features ); + fd_features_enable_hardcoded( features ); + default_enable_features( features ); - fd_pod_insert_ulong( pod, "default_funded.cnt", config->development.genesis.fund_initial_accounts ); - fd_pod_insert_ulong( pod, "default_funded.balance", config->development.genesis.fund_initial_amount_lamports ); + options->features = features; /* Serialize blob */ @@ -128,7 +201,7 @@ create_genesis( config_t * const config, fd_scratch_attach( scratch_smem, scratch_fmem, sizeof(scratch_smem), sizeof(scratch_fmem)/sizeof(ulong) ); - ulong blob_len = fd_genesis_create( blob, blob_sz, pod ); + ulong blob_len = fd_genesis_create( blob, blob_sz, options ); if( FD_UNLIKELY( !blob_sz ) ) FD_LOG_ERR(( "Failed to create genesis blob" )); FD_LOG_DEBUG(( "Created genesis blob (sz=%lu)", blob_len )); diff --git a/src/flamenco/features/fd_features.h b/src/flamenco/features/fd_features.h index 9a0cf6ca52..d3e9f12796 100644 --- a/src/flamenco/features/fd_features.h +++ b/src/flamenco/features/fd_features.h @@ -75,9 +75,9 @@ fd_features_enable_hardcoded( fd_features_t * ); for( fd_feature_id_t const * id = fd_feature_iter_init(); !fd_feature_iter_done( id ); - id = fd_feature_iter_next( id ) ) {{ + id = fd_feature_iter_next( id ) ) { ... - }} */ + } */ static inline fd_feature_id_t const * fd_feature_iter_init( void ) { diff --git a/src/flamenco/genesis/fd_genesis_create.c b/src/flamenco/genesis/fd_genesis_create.c index a8c734394e..b80f68f855 100644 --- a/src/flamenco/genesis/fd_genesis_create.c +++ b/src/flamenco/genesis/fd_genesis_create.c @@ -14,9 +14,9 @@ #include "../../util/tmpl/fd_sort.c" static ulong -genesis_create( void * buf, - ulong bufsz, - uchar const * pod ) { +genesis_create( void * buf, + ulong bufsz, + fd_genesis_options_t const * options ) { # define REQUIRE(c) \ do { \ @@ -26,32 +26,21 @@ genesis_create( void * buf, } \ } while(0); - fd_pubkey_t identity_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "identity.pubkey", &identity_pubkey ) ); - - fd_pubkey_t faucet_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "faucet.pubkey", &faucet_pubkey ) ); - - fd_pubkey_t stake_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "stake.pubkey", &stake_pubkey ) ); - - fd_pubkey_t vote_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "vote.pubkey", &vote_pubkey ) ); - fd_genesis_solana_t genesis[1]; fd_genesis_solana_new( genesis ); genesis->cluster_type = 3; /* development */ - genesis->creation_time = fd_pod_query_ulong( pod, "creation_time", 0UL ); - genesis->ticks_per_slot = fd_pod_query_ulong( pod, "ticks_per_slot", 0UL ); + genesis->creation_time = options->creation_time; + genesis->ticks_per_slot = options->ticks_per_slot; REQUIRE( genesis->ticks_per_slot ); - ulong hashes_per_tick = fd_pod_query_ulong( pod, "hashes_per_tick", 0UL ); - genesis->poh_config.has_hashes_per_tick = !!hashes_per_tick; - genesis->poh_config.hashes_per_tick = hashes_per_tick; + genesis->unused = 1024UL; /* match Anza genesis byte-for-byte */ + + genesis->poh_config.has_hashes_per_tick = !!options->hashes_per_tick; + genesis->poh_config.hashes_per_tick = options->hashes_per_tick; - ulong target_tick_micros = fd_pod_query_ulong( pod, "target_tick_µs", 0UL ); + ulong target_tick_micros = options->target_tick_duration_micros; REQUIRE( target_tick_micros ); genesis->poh_config.target_tick_duration = (fd_rust_duration_t) { .seconds = target_tick_micros / 1000000UL, @@ -61,11 +50,11 @@ genesis_create( void * buf, /* Create fee rate governor */ genesis->fee_rate_governor = (fd_fee_rate_governor_t) { - .target_lamports_per_signature = 10000UL, - .target_signatures_per_slot = 20000UL, - .min_lamports_per_signature = 0UL, - .max_lamports_per_signature = 0UL, - .burn_percent = 50, + .target_lamports_per_signature = 10000UL, + .target_signatures_per_slot = 20000UL, + .min_lamports_per_signature = 5000UL, + .max_lamports_per_signature = 100000UL, + .burn_percent = 50, }; /* Create rent configuration */ @@ -76,6 +65,17 @@ genesis_create( void * buf, .burn_percent = 50, }; + /* Create inflation configuration */ + + genesis->inflation = (fd_inflation_t) { + .initial = 0.08, + .terminal = 0.015, + .taper = 0.15, + .foundation = 0.05, + .foundation_term = 7.0, + .__unused = 0.0, + }; + /* Create epoch schedule */ /* TODO The epoch schedule should be configurable! */ @@ -90,11 +90,11 @@ genesis_create( void * buf, /* Create faucet account */ fd_pubkey_account_pair_t const faucet_account = { - .key = faucet_pubkey, + .key = options->faucet_pubkey, .account = { - .lamports = fd_pod_query_ulong( pod, "faucet.balance", 1000000000UL /* 1 SOL */ ), + .lamports = options->faucet_balance, .owner = fd_solana_system_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; ulong const faucet_account_index = genesis->accounts_len++; @@ -102,11 +102,11 @@ genesis_create( void * buf, /* Create identity account (vote authority, withdraw authority) */ fd_pubkey_account_pair_t const identity_account = { - .key = identity_pubkey, + .key = options->identity_pubkey, .account = { .lamports = 500000000000UL /* 500 SOL */, .owner = fd_solana_system_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; ulong const identity_account_index = genesis->accounts_len++; @@ -122,8 +122,8 @@ genesis_create( void * buf, fd_vote_state_versioned_new_disc( vsv, fd_vote_state_versioned_enum_current ); fd_vote_state_t * vs = &vsv->inner.current; - vs->node_pubkey = identity_pubkey; - vs->authorized_withdrawer = identity_pubkey; + vs->node_pubkey = options->identity_pubkey; + vs->authorized_withdrawer = options->identity_pubkey; vs->commission = 100; vs->authorized_voters.pool = fd_vote_authorized_voters_pool_alloc ( fd_scratch_virtual() ); vs->authorized_voters.treap = fd_vote_authorized_voters_treap_alloc( fd_scratch_virtual() ); @@ -132,8 +132,8 @@ genesis_create( void * buf, fd_vote_authorized_voters_pool_ele_acquire( vs->authorized_voters.pool ); *ele = (fd_vote_authorized_voter_t) { .epoch = 0UL, - .pubkey = identity_pubkey, - .prio = identity_pubkey.ul[0], /* treap prio */ + .pubkey = options->identity_pubkey, + .prio = options->identity_pubkey.ul[0], /* treap prio */ }; fd_vote_authorized_voters_treap_ele_insert( vs->authorized_voters.treap, ele, vs->authorized_voters.pool ); @@ -161,13 +161,13 @@ genesis_create( void * buf, stake->meta = (fd_stake_meta_t) { .rent_exempt_reserve = stake_state_min_bal, .authorized = { - .staker = identity_pubkey, - .withdrawer = identity_pubkey, + .staker = options->identity_pubkey, + .withdrawer = options->identity_pubkey, } }; stake->stake = (fd_stake_t) { .delegation = (fd_delegation_t) { - .voter_pubkey = vote_pubkey, + .voter_pubkey = options->vote_pubkey, .stake = fd_ulong_max( stake_state_min_bal, 500000000UL /* 0.5 SOL */ ), .activation_epoch = ULONG_MAX, /* bootstrap stake denoted with ULONG_MAX */ .deactivation_epoch = ULONG_MAX @@ -181,11 +181,27 @@ genesis_create( void * buf, REQUIRE( fd_stake_state_v2_encode( state, &encode ) == FD_BINCODE_SUCCESS ); } while(0); + /* Read enabled features */ + + ulong feature_cnt = 0UL; + fd_pubkey_t * features = + fd_scratch_alloc( alignof(fd_pubkey_t), FD_FEATURE_ID_CNT * sizeof(fd_pubkey_t) ); + + if( options->features ) { + for( fd_feature_id_t const * id = fd_feature_iter_init(); + !fd_feature_iter_done( id ); + id = fd_feature_iter_next( id ) ) { + if( fd_features_get( options->features, id ) == 0UL ) + features[ feature_cnt++ ] = id->id; + } + } + /* Allocate the account table */ - ulong default_funded_idx = genesis->accounts_len; - ulong default_funded_cnt = fd_pod_query_ulong( pod, "default_funded.cnt", 0UL ); - genesis->accounts_len += default_funded_cnt; + ulong default_funded_cnt = options->fund_initial_accounts; + + ulong default_funded_idx = genesis->accounts_len; genesis->accounts_len += default_funded_cnt; + ulong feature_gate_idx = genesis->accounts_len; genesis->accounts_len += feature_cnt; genesis->accounts = fd_scratch_alloc( alignof(fd_pubkey_account_pair_t), genesis->accounts_len * sizeof(fd_pubkey_account_pair_t) ); @@ -194,29 +210,29 @@ genesis_create( void * buf, genesis->accounts[ faucet_account_index ] = faucet_account; genesis->accounts[ identity_account_index ] = identity_account; genesis->accounts[ stake_account_index ] = (fd_pubkey_account_pair_t) { - .key = stake_pubkey, + .key = options->stake_pubkey, .account = (fd_solana_account_t) { .lamports = stake_state_min_bal, .data_len = FD_STAKE_STATE_V2_SZ, .data = stake_data, .owner = fd_solana_stake_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; genesis->accounts[ vote_account_index ] = (fd_pubkey_account_pair_t) { - .key = vote_pubkey, + .key = options->vote_pubkey, .account = (fd_solana_account_t) { .lamports = vote_min_bal, .data_len = FD_VOTE_STATE_V3_SZ, .data = vote_state_data, .owner = fd_solana_vote_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; /* Set up primordial accounts */ - ulong default_funded_balance = fd_pod_query_ulong( pod, "default_funded.balance", 0UL ); + ulong default_funded_balance = options->fund_initial_amount_lamports; for( ulong j=0UL; jaccounts[ default_funded_idx+j ]; @@ -229,9 +245,28 @@ genesis_create( void * buf, .lamports = default_funded_balance, .data_len = 0UL, .owner = fd_solana_system_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL + }; + } + +#define FEATURE_ENABLED_SZ 9UL + static const uchar feature_enabled_data[ FEATURE_ENABLED_SZ ] = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + ulong default_feature_enabled_balance = fd_rent_exempt_minimum_balance2( &genesis->rent, FEATURE_ENABLED_SZ ); + + /* Set up feature gate accounts */ + for( ulong j=0UL; jaccounts[ feature_gate_idx+j ]; + + pair->key = features[ j ]; + pair->account = (fd_solana_account_t) { + .lamports = default_feature_enabled_balance, + .data_len = FEATURE_ENABLED_SZ, + .data = (uchar *)feature_enabled_data, + .owner = fd_solana_feature_program_id, + .rent_epoch = 0UL, }; } +#undef FEATURE_ENABLED_SZ /* Sort and check for duplicates */ @@ -262,11 +297,11 @@ genesis_create( void * buf, } ulong -fd_genesis_create( void * buf, - ulong bufsz, - uchar const * pod ) { +fd_genesis_create( void * buf, + ulong bufsz, + fd_genesis_options_t const * options ) { fd_scratch_push(); - ulong ret = genesis_create( buf, bufsz, pod ); + ulong ret = genesis_create( buf, bufsz, options ); fd_scratch_pop(); return ret; } diff --git a/src/flamenco/genesis/fd_genesis_create.h b/src/flamenco/genesis/fd_genesis_create.h index 29b293868a..f2dae1ee70 100644 --- a/src/flamenco/genesis/fd_genesis_create.h +++ b/src/flamenco/genesis/fd_genesis_create.h @@ -5,30 +5,58 @@ A genesis blob is used to bootstrap a Solana ledger. */ #include "../fd_flamenco_base.h" +#include "../features/fd_features.h" + + +/* fd_genesis_options_t exists as a convenient way to specify options + for genesis creation. */ + +struct fd_genesis_options { + fd_pubkey_t identity_pubkey; + fd_pubkey_t faucet_pubkey; + fd_pubkey_t stake_pubkey; + fd_pubkey_t vote_pubkey; + + ulong creation_time; /* unix time, i.e. seconds since the unix epoch */ + ulong faucet_balance; /* in lamports */ + + ulong hashes_per_tick; /* 0 means unset */ + ulong ticks_per_slot; + ulong target_tick_duration_micros; + + ulong fund_initial_accounts; + ulong fund_initial_amount_lamports; + + /* features points to an externally owned feature map. + Adds a feature account to the genesis blob for feature enabled at + slot 0. If features==NULL, creates no feature accounts. */ + fd_features_t const * features; +}; + +typedef struct fd_genesis_options fd_genesis_options_t; FD_PROTOTYPES_BEGIN /* fd_genesis_create creates a 'genesis.bin' compatible genesis blob. (Bincode encoded fd_genesis_solana_t) [buf,bufsz) it the output - memory region into which the genesis blob will be written. pod - points to an fd_pod containing the genesis configuration parameters. - (Refer to fd_genesis.c code for the pod layout, there are no docs.) + memory region into which the genesis blob will be written. options + points to a struct containing the genesis configuration parameters. Returns the number of bytes in the output memory region used on success. On failure, returns 0UL and logs reason for error. Assumes that caller is attached to an fd_scratch with sufficient - memory to buffer intermediate data (8192 + 128*n space, 2 frames). + memory to buffer intermediate data (16384 + 128*n space, 2 frames). THIS METHOD IS NOT SAFE FOR PRODUCTION USE. It is intended for development only. */ ulong -fd_genesis_create( void * buf, - ulong bufsz, - uchar const * pod ); +fd_genesis_create( void * buf, + ulong bufsz, + fd_genesis_options_t const * options ); -/* TODO Add method to estimate the scratch and genesis blob size given a pod */ +/* TODO Add method to estimate the scratch and genesis blob size given options */ FD_PROTOTYPES_END diff --git a/src/flamenco/genesis/test_genesis_create.c b/src/flamenco/genesis/test_genesis_create.c index ced20524d1..b565b70532 100644 --- a/src/flamenco/genesis/test_genesis_create.c +++ b/src/flamenco/genesis/test_genesis_create.c @@ -13,42 +13,26 @@ main( int argc, int log_level = fd_log_level_logfile(); fd_log_level_logfile_set( fd_int_max( log_level, 4 ) ); - static uchar scratch_smem[ 8192 ]; + static uchar scratch_smem[ 16384 ]; ulong scratch_fmem[ 4 ]; fd_scratch_attach( scratch_smem, scratch_fmem, sizeof(scratch_smem), sizeof(scratch_fmem)/sizeof(ulong) ); - static uchar pod_mem[ 8192 ]; - uchar * pod = fd_pod_join( fd_pod_new( pod_mem, sizeof(pod_mem) ) ); /* Minimal configuration */ - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t identity_pubkey = { .ul = { 0, 0, 0, 1 } }; - fd_pod_insert_pubkey( pod, "identity.pubkey", &identity_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t faucet_pubkey = { .ul = { 0, 0, 0, 2 } }; - fd_pod_insert_pubkey( pod, "faucet.pubkey", &faucet_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t stake_pubkey = { .ul = { 0, 0, 0, 3 } }; - fd_pod_insert_pubkey( pod, "stake.pubkey", &stake_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t vote_pubkey = { .ul = { 0, 0, 0, 4 } }; - fd_pod_insert_pubkey( pod, "vote.pubkey", &vote_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pod_insert_ulong( pod, "creation_time", 123UL ); - fd_pod_insert_ulong( pod, "ticks_per_slot", 64UL ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pod_insert_ulong( pod, "target_tick_µs", 6250UL ); + fd_genesis_options_t options[1] = {{ + .identity_pubkey = { .ul = { 0, 0, 0, 1 } }, + .faucet_pubkey = { .ul = { 0, 0, 0, 2 } }, + .stake_pubkey = { .ul = { 0, 0, 0, 3 } }, + .vote_pubkey = { .ul = { 0, 0, 0, 4 } }, + .creation_time = 123UL, + .ticks_per_slot = 64UL, + .target_tick_duration_micros = 6250UL + }}; /* Buffer too small */ - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); + FD_TEST( !fd_genesis_create( NULL, 0UL, options ) ); /* No more warnings expected */ @@ -57,18 +41,24 @@ main( int argc, /* Serialize to buffer */ static uchar result_mem[ BUFSZ ]; - ulong result_sz = fd_genesis_create( result_mem, sizeof(result_mem), pod ); + ulong result_sz = fd_genesis_create( result_mem, sizeof(result_mem), options ); FD_TEST( result_sz ); /* Now try adding a few accounts */ - fd_pod_insert_ulong( pod, "default_funded.cnt", 16UL ); - result_sz = fd_genesis_create( result_mem, sizeof(result_mem), pod ); + options->fund_initial_accounts = 16UL; + result_sz = fd_genesis_create( result_mem, sizeof(result_mem), options ); FD_TEST( result_sz ); - /* TODO load this into a Firedancer runtime and verify the resulting slot context */ + /* Add a feature gate */ + fd_features_t features[1]; + fd_features_disable_all( features ); + features->full_inflation_vote = 0UL; + options->features = features; + result_sz = fd_genesis_create( result_mem, sizeof(result_mem), options ); + FD_TEST( result_sz ); - FD_TEST( fd_pod_delete( fd_pod_leave ( pod ) )==pod_mem ); + /* TODO load this into a Firedancer runtime and verify the resulting slot context */ FD_LOG_NOTICE(( "pass" ));