Add cli command to query upgradeable account authorities (#14491)

This commit is contained in:
Jack May 2021-01-08 14:43:36 -08:00 committed by GitHub
parent 9d53eca6e3
commit 638f225dc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 191 additions and 11 deletions

View File

@ -80,6 +80,9 @@ pub enum ProgramCliCommand {
upgrade_authority_index: Option<SignerIndex>,
new_upgrade_authority: Option<Pubkey>,
},
GetAuthority {
account_pubkey: Option<Pubkey>,
},
}
pub trait ProgramSubCommands {
@ -222,7 +225,6 @@ impl ProgramSubCommands for App<'_, '_> {
.conflicts_with("new_buffer_authority")
.help("The buffer will be immutable")
)
.arg(commitment_arg_with_default("singleGossip")),
)
.subcommand(
SubCommand::with_name("set-upgrade-authority")
@ -256,7 +258,18 @@ impl ProgramSubCommands for App<'_, '_> {
.conflicts_with("new_upgrade_authority")
.help("The program will not be upgradeable")
)
.arg(commitment_arg_with_default("singleGossip")),
)
.subcommand(
SubCommand::with_name("get-authority")
.about("Gets a buffer or program account's authority")
.arg(
Arg::with_name("account")
.index(1)
.value_name("ACCOUNT_ADDRESS")
.takes_value(true)
.required(true)
.help("Public key of the account to query")
)
)
)
}
@ -462,6 +475,12 @@ pub fn parse_program_subcommand(
signers: signer_info.signers,
}
}
("get-authority", Some(matches)) => CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::GetAuthority {
account_pubkey: pubkey_of(matches, "account"),
}),
signers: vec![],
},
_ => unreachable!(),
};
Ok(response)
@ -539,6 +558,9 @@ pub fn process_program_subcommand(
*upgrade_authority_index,
*new_upgrade_authority,
),
ProgramCliCommand::GetAuthority { account_pubkey } => {
process_get_authority(&rpc_client, config, *account_pubkey)
}
}
}
@ -872,15 +894,59 @@ fn process_set_authority(
)
.map_err(|e| format!("Setting authority failed: {}", e))?;
match new_authority {
Some(pubkey) => Ok(json!({
"Authority": format!("{:?}", pubkey),
})
.to_string()),
None => Ok(json!({
"Authority": "None",
})
.to_string()),
Ok(option_pubkey_to_string("Authority", new_authority))
}
fn process_get_authority(
rpc_client: &RpcClient,
config: &CliConfig,
account_pubkey: Option<Pubkey>,
) -> ProcessResult {
if let Some(account_pubkey) = account_pubkey {
if let Some(account) = rpc_client
.get_account_with_commitment(&account_pubkey, config.commitment)?
.value
{
if let Ok(UpgradeableLoaderState::Program {
programdata_address,
}) = account.state()
{
if let Some(account) = rpc_client
.get_account_with_commitment(&programdata_address, config.commitment)?
.value
{
if let Ok(UpgradeableLoaderState::ProgramData {
upgrade_authority_address,
..
}) = account.state()
{
Ok(option_pubkey_to_string(
"Program upgrade authority",
upgrade_authority_address,
))
} else {
Err("Invalid associated ProgramData account found for the program".into())
}
} else {
Err(
"Failed to find associated ProgramData account for the provided program"
.into(),
)
}
} else if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state()
{
Ok(option_pubkey_to_string(
"Buffer authority",
authority_address,
))
} else {
Err("Not a buffer or program account".into())
}
} else {
Err("Unable to find the account".into())
}
} else {
Err("No account specified".into())
}
}
@ -1415,6 +1481,19 @@ fn report_ephemeral_mnemonic(words: usize, mnemonic: bip39::Mnemonic) {
);
}
fn option_pubkey_to_string(tag: &str, option: Option<Pubkey>) -> String {
match option {
Some(pubkey) => json!({
tag: format!("{:?}", pubkey),
})
.to_string(),
None => json!({
tag: "None",
})
.to_string(),
}
}
fn send_and_confirm_transactions_with_spinner<T: Signers>(
rpc_client: &RpcClient,
mut transactions: Vec<Transaction>,
@ -2248,6 +2327,37 @@ mod tests {
);
}
#[test]
#[allow(clippy::cognitive_complexity)]
fn test_cli_parse_get_authority() {
let test_commands = app("test", "desc", "version");
let default_keypair = Keypair::new();
let keypair_file = make_tmp_path("keypair_file");
write_keypair_file(&default_keypair, &keypair_file).unwrap();
let default_signer = DefaultSigner {
path: keypair_file,
arg_name: "".to_string(),
};
let buffer_pubkey = Pubkey::new_unique();
let test_deploy = test_commands.clone().get_matches_from(vec![
"test",
"program",
"get-authority",
&buffer_pubkey.to_string(),
]);
assert_eq!(
parse_command(&test_deploy, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::GetAuthority {
account_pubkey: Some(buffer_pubkey)
}),
signers: vec![],
}
);
}
#[test]
fn test_cli_keypair_file() {
solana_logger::setup();

View File

@ -486,6 +486,25 @@ fn test_cli_program_deploy_with_authority() {
program_data[..]
);
// Get upgrade authority
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::GetAuthority {
account_pubkey: Some(program_pubkey),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let authority_pubkey_str = json
.as_object()
.unwrap()
.get("Program upgrade authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
new_upgrade_authority.pubkey(),
Pubkey::from_str(&authority_pubkey_str).unwrap()
);
// Set no authority
config.signers = vec![&keypair, &new_upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::SetUpgradeAuthority {
@ -560,6 +579,22 @@ fn test_cli_program_deploy_with_authority() {
} else {
panic!("not a buffer account");
}
// Get buffer authority
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::GetAuthority {
account_pubkey: Some(program_pubkey),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let authority_pubkey_str = json
.as_object()
.unwrap()
.get("Program upgrade authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!("None", authority_pubkey_str);
}
#[test]
@ -686,6 +721,25 @@ fn test_cli_program_write_buffer() {
program_data[..]
);
// Get buffer authority
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::GetAuthority {
account_pubkey: Some(buffer_keypair.pubkey()),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let authority_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!(
keypair.pubkey(),
Pubkey::from_str(&authority_pubkey_str).unwrap()
);
// Specify buffer authority
let buffer_keypair = Keypair::new();
let authority_keypair = Keypair::new();
@ -799,6 +853,22 @@ fn test_cli_program_write_buffer() {
} else {
panic!("not a buffer account");
}
// Get buffer authority
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::GetAuthority {
account_pubkey: Some(buffer_pubkey),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let authority_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer authority")
.unwrap()
.as_str()
.unwrap();
assert_eq!("None", authority_pubkey_str);
}
#[test]