Skip to content

Commit

Permalink
test-validator: Add flag to clone feature set from a cluster (#2480)
Browse files Browse the repository at this point in the history
* test-validator: Add flag to clone feature set from a cluster

#### Problem

Program devs run into issues when testing, where everything works great
with a solana-test-validator, and then fails once they deploy to a real
cluster. Most times, this happens because the test validator enables all
features by default, and their program depended on a new feature without
their knowledge.

#### Summary of changes

To make local development much easier, add a `--clone-feature-set` flag
to solana-test-validator to easily mimic the functionality on the
cluster targeted with `--url`.

* Add changelog entry
  • Loading branch information
joncinque authored Aug 8, 2024
1 parent 1d825df commit 39af6c0
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Release channels have their own copy of this changelog:
* Changes
* SDK: removed the `respan` macro. This was marked as "internal use only" and was no longer used internally.
* `agave-validator`: Update PoH speed check to compare against current hash rate from a Bank (#2447)
* `solana-test-validator`: Add `--clone-feature-set` flag to mimic features from a target cluster (#2480)

## [2.0.0]
* Breaking
Expand Down
27 changes: 27 additions & 0 deletions test-validator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use {
commitment_config::CommitmentConfig,
epoch_schedule::EpochSchedule,
exit::Exit,
feature,
feature_set::FEATURE_NAMES,
fee_calculator::FeeRateGovernor,
instruction::{AccountMeta, Instruction},
Expand Down Expand Up @@ -428,6 +429,32 @@ impl TestValidatorGenesis {
Ok(self)
}

pub fn clone_feature_set(&mut self, rpc_client: &RpcClient) -> Result<&mut Self, String> {
for feature_ids in FEATURE_NAMES
.keys()
.cloned()
.collect::<Vec<Pubkey>>()
.chunks(MAX_MULTIPLE_ACCOUNTS)
{
rpc_client
.get_multiple_accounts(feature_ids)
.map_err(|err| format!("Failed to fetch: {err}"))?
.into_iter()
.zip(feature_ids)
.for_each(|(maybe_account, feature_id)| {
if maybe_account
.as_ref()
.and_then(feature::from_account)
.and_then(|feature| feature.activated_at)
.is_none()
{
self.deactivate_feature_set.insert(*feature_id);
}
});
}
Ok(self)
}

pub fn add_accounts_from_json_files(
&mut self,
accounts: &[AccountInfo],
Expand Down
13 changes: 13 additions & 0 deletions validator/src/bin/solana-test-validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ fn main() {
.map(|v| v.into_iter().collect())
.unwrap_or_default();

let clone_feature_set = matches.is_present("clone_feature_set");

let warp_slot = if matches.is_present("warp_slot") {
Some(match matches.value_of("warp_slot") {
Some(_) => value_t_or_exit!(matches, "warp_slot", Slot),
Expand Down Expand Up @@ -511,6 +513,17 @@ fn main() {
}
}

if clone_feature_set {
if let Err(e) = genesis.clone_feature_set(
cluster_rpc_client
.as_ref()
.expect("bug: --url argument missing?"),
) {
println!("Error: clone_feature_set failed: {e}");
exit(1);
}
}

if let Some(warp_slot) = warp_slot {
genesis.warp_slot(warp_slot);
}
Expand Down
11 changes: 11 additions & 0 deletions validator/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2811,6 +2811,17 @@ pub fn test_app<'a>(version: &'a str, default_args: &'a DefaultTestArgs) -> App<
.validator(is_parsable::<u64>)
.takes_value(true)
.help("Override the runtime's account lock limit per transaction"),
)
.arg(
Arg::with_name("clone_feature_set")
.long("clone-feature-set")
.takes_value(false)
.requires("json_rpc_url")
.help(
"Copy a feature set from the cluster referenced by the --url \
argument in the genesis configuration. If the ledger \
already exists then this parameter is silently ignored",
),
);
}

Expand Down

0 comments on commit 39af6c0

Please sign in to comment.