test-validator: Add `--max-compute-units` flag (#24130)

* test-validator: Add `--max-compute-units` flag

* Add `RuntimeConfig` for tweaking runtime behavior

* Actually add the file

* Move RuntimeConfig to runtime
This commit is contained in:
Jon Cinque 2022-04-12 02:28:10 +02:00 committed by GitHub
parent 4fd184c131
commit 9b8850f99e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 106 additions and 29 deletions

1
Cargo.lock generated
View File

@ -5930,6 +5930,7 @@ dependencies = [
"solana-ledger",
"solana-logger 1.11.0",
"solana-net-utils",
"solana-program-runtime",
"solana-program-test",
"solana-rpc",
"solana-runtime",

View File

@ -73,6 +73,7 @@ use {
commitment::BlockCommitmentCache,
cost_model::CostModel,
hardened_unpack::{open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
runtime_config::RuntimeConfig,
snapshot_archive_info::SnapshotArchiveInfoGetter,
snapshot_config::SnapshotConfig,
snapshot_hash::StartingSnapshotHashes,
@ -110,7 +111,6 @@ const MAX_COMPLETED_DATA_SETS_IN_CHANNEL: usize = 100_000;
const WAIT_FOR_SUPERMAJORITY_THRESHOLD_PERCENT: u64 = 80;
pub struct ValidatorConfig {
pub dev_halt_at_slot: Option<Slot>,
pub expected_genesis_hash: Option<Hash>,
pub expected_bank_hash: Option<Hash>,
pub expected_shred_version: Option<u16>,
@ -146,7 +146,6 @@ pub struct ValidatorConfig {
pub debug_keys: Option<Arc<HashSet<Pubkey>>>,
pub contact_debug_interval: u64,
pub contact_save_interval: u64,
pub bpf_jit: bool,
pub send_transaction_service_config: send_transaction_service::Config,
pub no_poh_speed_test: bool,
pub no_os_memory_stats_reporting: bool,
@ -165,12 +164,12 @@ pub struct ValidatorConfig {
pub accounts_shrink_ratio: AccountShrinkThreshold,
pub wait_to_vote_slot: Option<Slot>,
pub ledger_column_options: LedgerColumnOptions,
pub runtime_config: RuntimeConfig,
}
impl Default for ValidatorConfig {
fn default() -> Self {
Self {
dev_halt_at_slot: None,
expected_genesis_hash: None,
expected_bank_hash: None,
expected_shred_version: None,
@ -206,7 +205,6 @@ impl Default for ValidatorConfig {
debug_keys: None,
contact_debug_interval: DEFAULT_CONTACT_DEBUG_INTERVAL_MILLIS,
contact_save_interval: DEFAULT_CONTACT_SAVE_INTERVAL_MILLIS,
bpf_jit: false,
send_transaction_service_config: send_transaction_service::Config::default(),
no_poh_speed_test: true,
no_os_memory_stats_reporting: true,
@ -225,6 +223,7 @@ impl Default for ValidatorConfig {
accounts_db_config: None,
wait_to_vote_slot: None,
ledger_column_options: LedgerColumnOptions::default(),
runtime_config: RuntimeConfig::default(),
}
}
}
@ -736,7 +735,7 @@ impl Validator {
(None, None, None, None)
};
if config.dev_halt_at_slot.is_some() {
if config.runtime_config.dev_halt_at_slot.is_some() {
// Simulate a confirmed root to avoid RPC errors with CommitmentConfig::finalized() and
// to ensure RPC endpoints like getConfirmedBlock, which require a confirmed root, work
block_commitment_cache
@ -1308,9 +1307,7 @@ fn load_blockstore(
let blockstore_root_scan = BlockstoreRootScan::new(config, &blockstore, exit);
let process_options = blockstore_processor::ProcessOptions {
bpf_jit: config.bpf_jit,
poh_verify: config.poh_verify,
dev_halt_at_slot: config.dev_halt_at_slot,
new_hard_forks: config.new_hard_forks.clone(),
debug_keys: config.debug_keys.clone(),
account_indexes: config.account_indexes.clone(),
@ -1319,6 +1316,7 @@ fn load_blockstore(
shrink_ratio: config.accounts_shrink_ratio,
accounts_db_test_hash_calculation: config.accounts_db_test_hash_calculation,
accounts_db_skip_shrink: config.accounts_db_skip_shrink,
runtime_config: config.runtime_config.clone(),
..blockstore_processor::ProcessOptions::default()
};

View File

@ -39,6 +39,7 @@ use {
cost_model::CostModel,
cost_tracker::CostTracker,
hardened_unpack::{open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
runtime_config::RuntimeConfig,
snapshot_archive_info::SnapshotArchiveInfoGetter,
snapshot_config::SnapshotConfig,
snapshot_hash::StartingSnapshotHashes,
@ -1785,9 +1786,12 @@ fn main() {
}
("shred-version", Some(arg_matches)) => {
let process_options = ProcessOptions {
dev_halt_at_slot: Some(0),
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: false,
runtime_config: RuntimeConfig {
dev_halt_at_slot: Some(0),
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
@ -1862,9 +1866,12 @@ fn main() {
}
("bank-hash", Some(arg_matches)) => {
let process_options = ProcessOptions {
dev_halt_at_slot: Some(0),
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: false,
runtime_config: RuntimeConfig {
dev_halt_at_slot: Some(0),
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
@ -2089,10 +2096,8 @@ fn main() {
});
let process_options = ProcessOptions {
dev_halt_at_slot: value_t!(arg_matches, "halt_at_slot", Slot).ok(),
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: !arg_matches.is_present("skip_poh_verify"),
bpf_jit: !matches.is_present("no_bpf_jit"),
accounts_db_caching_enabled: !arg_matches.is_present("no_accounts_db_caching"),
limit_load_slot_count_from_snapshot: value_t!(
arg_matches,
@ -2106,6 +2111,11 @@ fn main() {
accounts_db_test_hash_calculation: arg_matches
.is_present("accounts_db_test_hash_calculation"),
accounts_db_skip_shrink: arg_matches.is_present("accounts_db_skip_shrink"),
runtime_config: RuntimeConfig {
dev_halt_at_slot: value_t!(arg_matches, "halt_at_slot", Slot).ok(),
bpf_jit: !matches.is_present("no_bpf_jit"),
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
let print_accounts_stats = arg_matches.is_present("print_accounts_stats");
@ -2142,9 +2152,12 @@ fn main() {
let output_file = value_t_or_exit!(arg_matches, "graph_filename", String);
let process_options = ProcessOptions {
dev_halt_at_slot: value_t!(arg_matches, "halt_at_slot", Slot).ok(),
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: false,
runtime_config: RuntimeConfig {
dev_halt_at_slot: value_t!(arg_matches, "halt_at_slot", Slot).ok(),
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
@ -2268,9 +2281,12 @@ fn main() {
&genesis_config,
&blockstore,
ProcessOptions {
dev_halt_at_slot: Some(snapshot_slot),
new_hard_forks,
poh_verify: false,
runtime_config: RuntimeConfig {
dev_halt_at_slot: Some(snapshot_slot),
..RuntimeConfig::default()
},
..ProcessOptions::default()
},
snapshot_archive_path,
@ -2565,9 +2581,12 @@ fn main() {
("accounts", Some(arg_matches)) => {
let dev_halt_at_slot = value_t!(arg_matches, "halt_at_slot", Slot).ok();
let process_options = ProcessOptions {
dev_halt_at_slot,
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: false,
runtime_config: RuntimeConfig {
dev_halt_at_slot,
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
@ -2628,9 +2647,12 @@ fn main() {
("capitalization", Some(arg_matches)) => {
let dev_halt_at_slot = value_t!(arg_matches, "halt_at_slot", Slot).ok();
let process_options = ProcessOptions {
dev_halt_at_slot,
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: false,
runtime_config: RuntimeConfig {
dev_halt_at_slot,
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);

View File

@ -211,14 +211,16 @@ fn bank_forks_from_snapshot(
process::exit(1);
}
let (deserialized_bank, full_snapshot_archive_info, incremental_snapshot_archive_info) =
let (mut deserialized_bank, full_snapshot_archive_info, incremental_snapshot_archive_info) =
snapshot_utils::bank_from_latest_snapshot_archives(
&snapshot_config.bank_snapshots_dir,
&snapshot_config.snapshot_archives_dir,
&account_paths,
genesis_config,
process_options.debug_keys.clone(),
Some(&crate::builtins::get(process_options.bpf_jit)),
Some(&crate::builtins::get(
process_options.runtime_config.bpf_jit,
)),
process_options.account_indexes.clone(),
process_options.accounts_db_caching_enabled,
process_options.limit_load_slot_count_from_snapshot,
@ -235,6 +237,8 @@ fn bank_forks_from_snapshot(
deserialized_bank.set_shrink_paths(shrink_paths);
}
deserialized_bank.set_compute_budget(process_options.runtime_config.compute_budget);
let full_snapshot_hash = FullSnapshotHash {
hash: (
full_snapshot_archive_info.slot(),

View File

@ -30,6 +30,7 @@ use {
block_cost_limits::*,
commitment::VOTE_THRESHOLD_SIZE,
cost_model::CostModel,
runtime_config::RuntimeConfig,
snapshot_config::SnapshotConfig,
snapshot_package::{PendingAccountsPackage, SnapshotType},
snapshot_utils,
@ -544,10 +545,8 @@ pub type ProcessCallback = Arc<dyn Fn(&Bank) + Sync + Send>;
#[derive(Default, Clone)]
pub struct ProcessOptions {
pub bpf_jit: bool,
pub poh_verify: bool,
pub full_leader_cache: bool,
pub dev_halt_at_slot: Option<Slot>,
pub entry_callback: Option<ProcessCallback>,
pub override_num_threads: Option<usize>,
pub new_hard_forks: Option<Vec<Slot>>,
@ -561,6 +560,7 @@ pub struct ProcessOptions {
pub accounts_db_config: Option<AccountsDbConfig>,
pub verify_index: bool,
pub shrink_ratio: AccountShrinkThreshold,
pub runtime_config: RuntimeConfig,
}
pub fn test_process_blockstore(
@ -603,11 +603,11 @@ pub(crate) fn process_blockstore_for_bank_0(
accounts_update_notifier: Option<AccountsUpdateNotifier>,
) -> BankForks {
// Setup bank for slot 0
let bank0 = Bank::new_with_paths(
let mut bank0 = Bank::new_with_paths(
genesis_config,
account_paths,
opts.debug_keys.clone(),
Some(&crate::builtins::get(opts.bpf_jit)),
Some(&crate::builtins::get(opts.runtime_config.bpf_jit)),
opts.account_indexes.clone(),
opts.accounts_db_caching_enabled,
opts.shrink_ratio,
@ -615,6 +615,7 @@ pub(crate) fn process_blockstore_for_bank_0(
opts.accounts_db_config.clone(),
accounts_update_notifier,
);
bank0.set_compute_budget(opts.runtime_config.compute_budget);
let bank_forks = BankForks::new(bank0);
info!("processing ledger for slot 0...");
@ -1147,7 +1148,10 @@ fn load_frozen_forks(
&mut pending_slots,
)?;
let dev_halt_at_slot = opts.dev_halt_at_slot.unwrap_or(std::u64::MAX);
let dev_halt_at_slot = opts
.runtime_config
.dev_halt_at_slot
.unwrap_or(std::u64::MAX);
if bank_forks.root() != dev_halt_at_slot {
while !pending_slots.is_empty() {
timing.details.per_program_timings.clear();
@ -3084,8 +3088,11 @@ pub mod tests {
// Specify halting at slot 0
let opts = ProcessOptions {
poh_verify: true,
dev_halt_at_slot: Some(0),
accounts_db_test_hash_calculation: true,
runtime_config: RuntimeConfig {
dev_halt_at_slot: Some(0),
..RuntimeConfig::default()
},
..ProcessOptions::default()
};
let (bank_forks, ..) = test_process_blockstore(&genesis_config, &blockstore, opts);

View File

@ -6,7 +6,6 @@ use {
pub fn safe_clone_config(config: &ValidatorConfig) -> ValidatorConfig {
ValidatorConfig {
dev_halt_at_slot: config.dev_halt_at_slot,
expected_genesis_hash: config.expected_genesis_hash,
expected_bank_hash: config.expected_bank_hash,
expected_shred_version: config.expected_shred_version,
@ -43,7 +42,6 @@ pub fn safe_clone_config(config: &ValidatorConfig) -> ValidatorConfig {
debug_keys: config.debug_keys.clone(),
contact_debug_interval: config.contact_debug_interval,
contact_save_interval: config.contact_save_interval,
bpf_jit: config.bpf_jit,
send_transaction_service_config: config.send_transaction_service_config.clone(),
no_poh_speed_test: config.no_poh_speed_test,
no_os_memory_stats_reporting: config.no_os_memory_stats_reporting,
@ -62,6 +60,7 @@ pub fn safe_clone_config(config: &ValidatorConfig) -> ValidatorConfig {
accounts_db_config: config.accounts_db_config.clone(),
wait_to_vote_slot: config.wait_to_vote_slot,
ledger_column_options: config.ledger_column_options.clone(),
runtime_config: config.runtime_config.clone(),
}
}

View File

@ -44,6 +44,7 @@ mod pubkey_bins;
mod read_only_accounts_cache;
pub mod rent_collector;
mod rolling_bit_field;
pub mod runtime_config;
pub mod secondary_index;
pub mod serde_snapshot;
mod shared_buffer_reader;

View File

@ -0,0 +1,9 @@
use {solana_program_runtime::compute_budget::ComputeBudget, solana_sdk::clock::Slot};
/// Encapsulates flags that can be used to tweak the runtime behavior.
#[derive(Default, Clone)]
pub struct RuntimeConfig {
pub bpf_jit: bool,
pub dev_halt_at_slot: Option<Slot>,
pub compute_budget: Option<ComputeBudget>,
}

View File

@ -22,6 +22,7 @@ solana-gossip = { path = "../gossip", version = "=1.11.0" }
solana-ledger = { path = "../ledger", version = "=1.11.0" }
solana-logger = { path = "../logger", version = "=1.11.0" }
solana-net-utils = { path = "../net-utils", version = "=1.11.0" }
solana-program-runtime = { path = "../program-runtime", version = "=1.11.0" }
solana-program-test = { path = "../program-test", version = "=1.11.0" }
solana-rpc = { path = "../rpc", version = "=1.11.0" }
solana-runtime = { path = "../runtime", version = "=1.11.0" }

View File

@ -16,11 +16,13 @@ use {
blockstore::create_new_ledger, blockstore_db::LedgerColumnOptions, create_new_tmp_ledger,
},
solana_net_utils::PortRange,
solana_program_runtime::compute_budget::ComputeBudget,
solana_rpc::{rpc::JsonRpcConfig, rpc_pubsub_service::PubSubConfig},
solana_runtime::{
accounts_db::AccountsDbConfig, accounts_index::AccountsIndexConfig, bank_forks::BankForks,
genesis_utils::create_genesis_config_with_leader_ex,
hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, snapshot_config::SnapshotConfig,
hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, runtime_config::RuntimeConfig,
snapshot_config::SnapshotConfig,
},
solana_sdk::{
account::{Account, AccountSharedData},
@ -111,6 +113,7 @@ pub struct TestValidatorGenesis {
pub geyser_plugin_config_files: Option<Vec<PathBuf>>,
pub accounts_db_caching_enabled: bool,
deactivate_feature_set: HashSet<Pubkey>,
max_compute_units: Option<u64>,
}
impl Default for TestValidatorGenesis {
@ -138,6 +141,7 @@ impl Default for TestValidatorGenesis {
geyser_plugin_config_files: Option::<Vec<PathBuf>>::default(),
accounts_db_caching_enabled: bool::default(),
deactivate_feature_set: HashSet::<Pubkey>::default(),
max_compute_units: Option::<u64>::default(),
}
}
}
@ -235,6 +239,11 @@ impl TestValidatorGenesis {
self
}
pub fn max_compute_units(&mut self, max_compute_units: u64) -> &mut Self {
self.max_compute_units = Some(max_compute_units);
self
}
/// Add an account to the test environment
pub fn add_account(&mut self, address: Pubkey, account: AccountSharedData) -> &mut Self {
self.accounts.insert(address, account);
@ -666,6 +675,15 @@ impl TestValidator {
..AccountsDbConfig::default()
});
let runtime_config = RuntimeConfig {
bpf_jit: !config.no_bpf_jit,
compute_budget: config.max_compute_units.map(|max_units| ComputeBudget {
max_units,
..ComputeBudget::default()
}),
..RuntimeConfig::default()
};
let mut validator_config = ValidatorConfig {
geyser_plugin_config_files: config.geyser_plugin_config_files.clone(),
accounts_db_caching_enabled: config.accounts_db_caching_enabled,
@ -690,12 +708,12 @@ impl TestValidator {
}),
enforce_ulimit_nofile: false,
warp_slot: config.warp_slot,
bpf_jit: !config.no_bpf_jit,
validator_exit: config.validator_exit.clone(),
rocksdb_compaction_interval: Some(100), // Compact every 100 slots
max_ledger_shreds: config.max_ledger_shreds,
no_wait_for_vote_to_start_leader: true,
accounts_db_config,
runtime_config,
..ValidatorConfig::default_for_test()
};
if let Some(ref tower_storage) = config.tower_storage {

View File

@ -354,6 +354,14 @@ fn main() {
.multiple(true)
.help("deactivate this feature in genesis.")
)
.arg(
Arg::with_name("max_compute_units")
.long("max-compute-units")
.value_name("COMPUTE_UNITS")
.validator(is_parsable::<u64>)
.takes_value(true)
.help("Override the runtime's maximum compute units")
)
.get_matches();
let output = if matches.is_present("quiet") {
@ -462,6 +470,7 @@ fn main() {
exit(1);
})
});
let max_compute_units = value_t!(matches, "max_compute_units", u64).ok();
let faucet_addr = Some(SocketAddr::new(
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
@ -724,6 +733,10 @@ fn main() {
);
}
if let Some(max_compute_units) = max_compute_units {
genesis.max_compute_units(max_compute_units);
}
match genesis.start_with_mint_address(mint_address, socket_addr_space) {
Ok(test_validator) => {
*admin_service_post_init.write().unwrap() =

View File

@ -50,6 +50,7 @@ use {
AccountsIndexConfig,
},
hardened_unpack::MAX_GENESIS_ARCHIVE_UNPACKED_SIZE,
runtime_config::RuntimeConfig,
snapshot_config::SnapshotConfig,
snapshot_utils::{
self, ArchiveFormat, SnapshotVersion, DEFAULT_FULL_SNAPSHOT_ARCHIVE_INTERVAL_SLOTS,
@ -2326,7 +2327,6 @@ pub fn main() {
let mut validator_config = ValidatorConfig {
require_tower: matches.is_present("require_tower"),
tower_storage,
dev_halt_at_slot: value_t!(matches, "dev_halt_at_slot", Slot).ok(),
expected_genesis_hash: matches
.value_of("expected_genesis_hash")
.map(|s| Hash::from_str(s).unwrap()),
@ -2403,7 +2403,6 @@ pub fn main() {
poh_verify: !matches.is_present("skip_poh_verify"),
debug_keys,
contact_debug_interval,
bpf_jit: !matches.is_present("no_bpf_jit"),
send_transaction_service_config: send_transaction_service::Config {
retry_rate_ms: value_t_or_exit!(matches, "rpc_send_transaction_retry_ms", u64),
leader_forward_count: value_t_or_exit!(
@ -2439,6 +2438,11 @@ pub fn main() {
tpu_coalesce_ms,
no_wait_for_vote_to_start_leader: matches.is_present("no_wait_for_vote_to_start_leader"),
accounts_shrink_ratio,
runtime_config: RuntimeConfig {
dev_halt_at_slot: value_t!(matches, "dev_halt_at_slot", Slot).ok(),
bpf_jit: !matches.is_present("no_bpf_jit"),
..RuntimeConfig::default()
},
..ValidatorConfig::default()
};