forked from solana-labs/solana
-
Notifications
You must be signed in to change notification settings - Fork 381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add set_identity tests #3794
Merged
mergify
merged 6 commits into
anza-xyz:master
from
KirillLykov:klykov/add-set-identity-tests
Dec 2, 2024
Merged
Add set_identity tests #3794
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
2eb0a30
add set_identity test
KirillLykov 8bc8cc5
add test_set_identity_with_validator
KirillLykov 45e0691
fix formatting, comments
KirillLykov d30cc41
extract utility code in admin rpc test
KirillLykov edddf78
Merge branch 'master' into klykov/add-set-identity-tests
KirillLykov 795b7d6
Merge branch 'master' into klykov/add-set-identity-tests
KirillLykov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -869,10 +869,18 @@ mod tests { | |
accounts_db::{AccountsDbConfig, ACCOUNTS_DB_CONFIG_FOR_TESTING}, | ||
accounts_index::AccountSecondaryIndexes, | ||
}, | ||
solana_core::consensus::tower_storage::NullTowerStorage, | ||
solana_gossip::cluster_info::ClusterInfo, | ||
solana_core::{ | ||
consensus::tower_storage::NullTowerStorage, | ||
validator::{Validator, ValidatorConfig}, | ||
}, | ||
solana_gossip::cluster_info::{ClusterInfo, Node}, | ||
solana_inline_spl::token, | ||
solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo}, | ||
solana_ledger::{ | ||
create_new_tmp_ledger, | ||
genesis_utils::{ | ||
create_genesis_config, create_genesis_config_with_leader, GenesisConfigInfo, | ||
}, | ||
}, | ||
solana_net_utils::bind_to_unspecified, | ||
solana_rpc::rpc::create_validator_exit, | ||
solana_runtime::{ | ||
|
@@ -885,11 +893,14 @@ mod tests { | |
system_program, | ||
}, | ||
solana_streamer::socket::SocketAddrSpace, | ||
solana_tpu_client::tpu_client::{ | ||
DEFAULT_TPU_CONNECTION_POOL_SIZE, DEFAULT_TPU_ENABLE_UDP, DEFAULT_TPU_USE_QUIC, | ||
}, | ||
spl_token_2022::{ | ||
solana_program::{program_option::COption, program_pack::Pack}, | ||
state::{Account as TokenAccount, AccountState as TokenAccountState, Mint}, | ||
}, | ||
std::{collections::HashSet, sync::atomic::AtomicBool}, | ||
std::{collections::HashSet, fs::remove_dir_all, sync::atomic::AtomicBool}, | ||
}; | ||
|
||
#[derive(Default)] | ||
|
@@ -1287,4 +1298,180 @@ mod tests { | |
} | ||
} | ||
} | ||
|
||
// This test checks that the rpc call to `set_identity` works a expected with | ||
// Bank but without validator. | ||
#[test] | ||
fn test_set_identity() { | ||
let rpc = RpcHandler::start_with_config(TestConfig::default()); | ||
|
||
let RpcHandler { io, meta, .. } = rpc; | ||
|
||
let expected_validator_id = Keypair::new(); | ||
let validator_id_bytes = format!("{:?}", expected_validator_id.to_bytes()); | ||
|
||
let set_id_request = format!( | ||
r#"{{"jsonrpc":"2.0","id":1,"method":"setIdentityFromBytes","params":[{validator_id_bytes}, false]}}"#, | ||
); | ||
let response = io.handle_request_sync(&set_id_request, meta.clone()); | ||
let actual_parsed_response: Value = | ||
serde_json::from_str(&response.expect("actual response")) | ||
.expect("actual response deserialization"); | ||
|
||
let expected_parsed_response: Value = serde_json::from_str( | ||
r#"{ | ||
"id": 1, | ||
"jsonrpc": "2.0", | ||
"result": null | ||
}"#, | ||
) | ||
.expect("Failed to parse expected response"); | ||
assert_eq!(actual_parsed_response, expected_parsed_response); | ||
|
||
let contact_info_request = | ||
r#"{"jsonrpc":"2.0","id":1,"method":"contactInfo","params":[]}"#.to_string(); | ||
let response = io.handle_request_sync(&contact_info_request, meta.clone()); | ||
let parsed_response: Value = serde_json::from_str(&response.expect("actual response")) | ||
.expect("actual response deserialization"); | ||
let actual_validator_id = parsed_response["result"]["id"] | ||
.as_str() | ||
.expect("Expected a string"); | ||
assert_eq!( | ||
actual_validator_id, | ||
expected_validator_id.pubkey().to_string() | ||
); | ||
} | ||
|
||
struct TestValidatorWithAdminRpc { | ||
meta: AdminRpcRequestMetadata, | ||
io: MetaIoHandler<AdminRpcRequestMetadata>, | ||
validator_ledger_path: PathBuf, | ||
} | ||
|
||
impl TestValidatorWithAdminRpc { | ||
fn new() -> Self { | ||
let leader_keypair = Keypair::new(); | ||
let leader_node = Node::new_localhost_with_pubkey(&leader_keypair.pubkey()); | ||
|
||
let validator_keypair = Keypair::new(); | ||
let validator_node = Node::new_localhost_with_pubkey(&validator_keypair.pubkey()); | ||
let genesis_config = | ||
create_genesis_config_with_leader(10_000, &leader_keypair.pubkey(), 1000) | ||
.genesis_config; | ||
let (validator_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_config); | ||
|
||
let voting_keypair = Arc::new(Keypair::new()); | ||
let voting_pubkey = voting_keypair.pubkey(); | ||
let authorized_voter_keypairs = Arc::new(RwLock::new(vec![voting_keypair])); | ||
let validator_config = ValidatorConfig { | ||
rpc_addrs: Some(( | ||
validator_node.info.rpc().unwrap(), | ||
validator_node.info.rpc_pubsub().unwrap(), | ||
)), | ||
..ValidatorConfig::default_for_test() | ||
}; | ||
let start_progress = Arc::new(RwLock::new(ValidatorStartProgress::default())); | ||
|
||
let post_init = Arc::new(RwLock::new(None)); | ||
let meta = AdminRpcRequestMetadata { | ||
rpc_addr: validator_config.rpc_addrs.map(|(rpc_addr, _)| rpc_addr), | ||
start_time: SystemTime::now(), | ||
start_progress: start_progress.clone(), | ||
validator_exit: validator_config.validator_exit.clone(), | ||
authorized_voter_keypairs: authorized_voter_keypairs.clone(), | ||
tower_storage: Arc::new(NullTowerStorage {}), | ||
post_init: post_init.clone(), | ||
staked_nodes_overrides: Arc::new(RwLock::new(HashMap::new())), | ||
rpc_to_plugin_manager_sender: None, | ||
}; | ||
|
||
let _validator = Validator::new( | ||
validator_node, | ||
Arc::new(validator_keypair), | ||
&validator_ledger_path, | ||
&voting_pubkey, | ||
authorized_voter_keypairs, | ||
vec![leader_node.info], | ||
&validator_config, | ||
true, // should_check_duplicate_instance | ||
None, // rpc_to_plugin_manager_receiver | ||
start_progress.clone(), | ||
SocketAddrSpace::Unspecified, | ||
DEFAULT_TPU_USE_QUIC, | ||
DEFAULT_TPU_CONNECTION_POOL_SIZE, | ||
DEFAULT_TPU_ENABLE_UDP, | ||
32, // max connections per IpAddr per minute for test | ||
post_init, | ||
) | ||
.expect("assume successful validator start"); | ||
assert_eq!( | ||
*start_progress.read().unwrap(), | ||
ValidatorStartProgress::Running | ||
); | ||
let mut io = MetaIoHandler::default(); | ||
io.extend_with(AdminRpcImpl.to_delegate()); | ||
Self { | ||
meta, | ||
io, | ||
validator_ledger_path, | ||
} | ||
} | ||
|
||
fn handle_request(&self, request: &str) -> Option<String> { | ||
self.io.handle_request_sync(request, self.meta.clone()) | ||
} | ||
} | ||
|
||
impl Drop for TestValidatorWithAdminRpc { | ||
fn drop(&mut self) { | ||
remove_dir_all(self.validator_ledger_path.clone()).unwrap(); | ||
} | ||
} | ||
|
||
// This test checks that `set_identity` call works with working validator and client. | ||
#[test] | ||
fn test_set_identity_with_validator() { | ||
let test_validator = TestValidatorWithAdminRpc::new(); | ||
let expected_validator_id = Keypair::new(); | ||
let validator_id_bytes = format!("{:?}", expected_validator_id.to_bytes()); | ||
|
||
let set_id_request = format!( | ||
r#"{{"jsonrpc":"2.0","id":1,"method":"setIdentityFromBytes","params":[{validator_id_bytes}, false]}}"#, | ||
); | ||
let response = test_validator.handle_request(&set_id_request); | ||
let actual_parsed_response: Value = | ||
serde_json::from_str(&response.expect("actual response")) | ||
.expect("actual response deserialization"); | ||
|
||
let expected_parsed_response: Value = serde_json::from_str( | ||
r#"{ | ||
"id": 1, | ||
"jsonrpc": "2.0", | ||
"result": null | ||
}"#, | ||
) | ||
.expect("Failed to parse expected response"); | ||
assert_eq!(actual_parsed_response, expected_parsed_response); | ||
|
||
let contact_info_request = | ||
r#"{"jsonrpc":"2.0","id":1,"method":"contactInfo","params":[]}"#.to_string(); | ||
let response = test_validator.handle_request(&contact_info_request); | ||
let parsed_response: Value = serde_json::from_str(&response.expect("actual response")) | ||
.expect("actual response deserialization"); | ||
let actual_validator_id = parsed_response["result"]["id"] | ||
.as_str() | ||
.expect("Expected a string"); | ||
assert_eq!( | ||
actual_validator_id, | ||
expected_validator_id.pubkey().to_string() | ||
); | ||
|
||
let contact_info_request = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it also tests that |
||
r#"{"jsonrpc":"2.0","id":1,"method":"exit","params":[]}"#.to_string(); | ||
let exit_response = test_validator.handle_request(&contact_info_request); | ||
let actual_parsed_response: Value = | ||
serde_json::from_str(&exit_response.expect("actual response")) | ||
.expect("actual response deserialization"); | ||
assert_eq!(actual_parsed_response, expected_parsed_response); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this feels a little fragile. Could we just check for null result so that we don't have to update this for benign things like a version change?