cli: show upgradeable program accounts (#19431)

This commit is contained in:
Jack May 2021-08-25 17:03:55 -07:00 committed by GitHub
parent 481ee48c35
commit 57bbbb83a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 302 additions and 80 deletions

View File

@ -1930,6 +1930,9 @@ pub struct CliUpgradeableProgram {
pub authority: String, pub authority: String,
pub last_deploy_slot: u64, pub last_deploy_slot: u64,
pub data_len: usize, pub data_len: usize,
pub lamports: u64,
#[serde(skip_serializing)]
pub use_lamports_unit: bool,
} }
impl QuietDisplay for CliUpgradeableProgram {} impl QuietDisplay for CliUpgradeableProgram {}
impl VerboseDisplay for CliUpgradeableProgram {} impl VerboseDisplay for CliUpgradeableProgram {}
@ -1950,6 +1953,49 @@ impl fmt::Display for CliUpgradeableProgram {
"Data Length:", "Data Length:",
&format!("{:?} ({:#x?}) bytes", self.data_len, self.data_len), &format!("{:?} ({:#x?}) bytes", self.data_len, self.data_len),
)?; )?;
writeln_name_value(
f,
"Balance:",
&build_balance_message(self.lamports, self.use_lamports_unit, true),
)?;
Ok(())
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CliUpgradeablePrograms {
pub programs: Vec<CliUpgradeableProgram>,
#[serde(skip_serializing)]
pub use_lamports_unit: bool,
}
impl QuietDisplay for CliUpgradeablePrograms {}
impl VerboseDisplay for CliUpgradeablePrograms {}
impl fmt::Display for CliUpgradeablePrograms {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f)?;
writeln!(
f,
"{}",
style(format!(
"{:<44} | {:<9} | {:<44} | {}",
"Program Id", "Slot", "Authority", "Balance"
))
.bold()
)?;
for program in self.programs.iter() {
writeln!(
f,
"{}",
&format!(
"{:<44} | {:<9} | {:<44} | {}",
program.program_id,
program.last_deploy_slot,
program.authority,
build_balance_message(program.lamports, self.use_lamports_unit, true)
)
)?;
}
Ok(()) Ok(())
} }
} }
@ -1977,7 +2023,7 @@ impl fmt::Display for CliUpgradeableProgramClosed {
} }
} }
#[derive(Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CliUpgradeableBuffer { pub struct CliUpgradeableBuffer {
pub address: String, pub address: String,

View File

@ -14,7 +14,7 @@ use solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*}
use solana_cli_output::{ use solana_cli_output::{
display::new_spinner_progress_bar, CliProgram, CliProgramAccountType, CliProgramAuthority, display::new_spinner_progress_bar, CliProgram, CliProgramAccountType, CliProgramAuthority,
CliProgramBuffer, CliProgramId, CliUpgradeableBuffer, CliUpgradeableBuffers, CliProgramBuffer, CliProgramId, CliUpgradeableBuffer, CliUpgradeableBuffers,
CliUpgradeableProgram, CliUpgradeableProgramClosed, CliUpgradeableProgram, CliUpgradeableProgramClosed, CliUpgradeablePrograms,
}; };
use solana_client::{ use solana_client::{
client_error::ClientErrorKind, client_error::ClientErrorKind,
@ -56,7 +56,9 @@ use std::{
error, error,
fs::File, fs::File,
io::{Read, Write}, io::{Read, Write},
mem::size_of,
path::PathBuf, path::PathBuf,
str::FromStr,
sync::Arc, sync::Arc,
thread::sleep, thread::sleep,
time::Duration, time::Duration,
@ -97,6 +99,8 @@ pub enum ProgramCliCommand {
Show { Show {
account_pubkey: Option<Pubkey>, account_pubkey: Option<Pubkey>,
authority_pubkey: Pubkey, authority_pubkey: Pubkey,
get_programs: bool,
get_buffers: bool,
all: bool, all: bool,
use_lamports_unit: bool, use_lamports_unit: bool,
}, },
@ -284,17 +288,27 @@ impl ProgramSubCommands for App<'_, '_> {
.takes_value(true) .takes_value(true)
.help("Address of the buffer or program to show") .help("Address of the buffer or program to show")
) )
.arg(
Arg::with_name("programs")
.long("programs")
.conflicts_with("account")
.conflicts_with("buffers")
.required_unless_one(&["account", "buffers"])
.help("Show every upgradebale program that matches the authority")
)
.arg( .arg(
Arg::with_name("buffers") Arg::with_name("buffers")
.long("buffers") .long("buffers")
.conflicts_with("account") .conflicts_with("account")
.required_unless("account") .conflicts_with("programs")
.help("Show every buffer account that matches the authority") .required_unless_one(&["account", "programs"])
.help("Show every upgradeable buffer that matches the authority")
) )
.arg( .arg(
Arg::with_name("all") Arg::with_name("all")
.long("all") .long("all")
.conflicts_with("account") .conflicts_with("account")
.conflicts_with("buffer_authority")
.help("Show accounts for all authorities") .help("Show accounts for all authorities")
) )
.arg( .arg(
@ -577,12 +591,6 @@ pub fn parse_program_subcommand(
} }
} }
("show", Some(matches)) => { ("show", Some(matches)) => {
let account_pubkey = if matches.is_present("buffers") {
None
} else {
pubkey_of(matches, "account")
};
let authority_pubkey = if let Some(authority_pubkey) = let authority_pubkey = if let Some(authority_pubkey) =
pubkey_of_signer(matches, "buffer_authority", wallet_manager)? pubkey_of_signer(matches, "buffer_authority", wallet_manager)?
{ {
@ -595,8 +603,10 @@ pub fn parse_program_subcommand(
CliCommandInfo { CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::Show { command: CliCommand::Program(ProgramCliCommand::Show {
account_pubkey, account_pubkey: pubkey_of(matches, "account"),
authority_pubkey, authority_pubkey,
get_programs: matches.is_present("programs"),
get_buffers: matches.is_present("buffers"),
all: matches.is_present("all"), all: matches.is_present("all"),
use_lamports_unit: matches.is_present("lamports"), use_lamports_unit: matches.is_present("lamports"),
}), }),
@ -725,6 +735,8 @@ pub fn process_program_subcommand(
ProgramCliCommand::Show { ProgramCliCommand::Show {
account_pubkey, account_pubkey,
authority_pubkey, authority_pubkey,
get_programs,
get_buffers,
all, all,
use_lamports_unit, use_lamports_unit,
} => process_show( } => process_show(
@ -732,6 +744,8 @@ pub fn process_program_subcommand(
config, config,
*account_pubkey, *account_pubkey,
*authority_pubkey, *authority_pubkey,
*get_programs,
*get_buffers,
*all, *all,
*use_lamports_unit, *use_lamports_unit,
), ),
@ -1124,24 +1138,152 @@ fn process_set_authority(
Ok(config.output_format.formatted_string(&authority)) Ok(config.output_format.formatted_string(&authority))
} }
const ACCOUNT_TYPE_SIZE: usize = 4;
const SLOT_SIZE: usize = size_of::<u64>();
const OPTION_SIZE: usize = 1;
const PUBKEY_LEN: usize = 32;
fn get_buffers( fn get_buffers(
rpc_client: &RpcClient, rpc_client: &RpcClient,
authority_pubkey: Option<Pubkey>, authority_pubkey: Option<Pubkey>,
) -> Result<Vec<(Pubkey, Account)>, Box<dyn std::error::Error>> { use_lamports_unit: bool,
let mut bytes = vec![1, 0, 0, 0, 1]; ) -> Result<CliUpgradeableBuffers, Box<dyn std::error::Error>> {
let length = bytes.len() + 32; // Pubkey length let mut filters = vec![RpcFilterType::Memcmp(Memcmp {
offset: 0,
bytes: MemcmpEncodedBytes::Binary(bs58::encode(vec![1, 0, 0, 0]).into_string()),
encoding: None,
})];
if let Some(authority_pubkey) = authority_pubkey { if let Some(authority_pubkey) = authority_pubkey {
bytes.extend_from_slice(authority_pubkey.as_ref()); filters.push(RpcFilterType::Memcmp(Memcmp {
offset: ACCOUNT_TYPE_SIZE,
bytes: MemcmpEncodedBytes::Binary(bs58::encode(vec![1]).into_string()),
encoding: None,
}));
filters.push(RpcFilterType::Memcmp(Memcmp {
offset: ACCOUNT_TYPE_SIZE + OPTION_SIZE,
bytes: MemcmpEncodedBytes::Binary(
bs58::encode(authority_pubkey.as_ref()).into_string(),
),
encoding: None,
}));
} }
let results = rpc_client.get_program_accounts_with_config( let results = get_accounts_with_filter(
&bpf_loader_upgradeable::id(), rpc_client,
RpcProgramAccountsConfig { filters,
filters: Some(vec![RpcFilterType::Memcmp(Memcmp { ACCOUNT_TYPE_SIZE + OPTION_SIZE + PUBKEY_LEN,
)?;
let mut buffers = vec![];
for (address, account) in results.iter() {
if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state() {
buffers.push(CliUpgradeableBuffer {
address: address.to_string(),
authority: authority_address
.map(|pubkey| pubkey.to_string())
.unwrap_or_else(|| "none".to_string()),
data_len: 0,
lamports: account.lamports,
use_lamports_unit,
});
} else {
return Err(format!("Error parsing Buffer account {}", address).into());
}
}
Ok(CliUpgradeableBuffers {
buffers,
use_lamports_unit,
})
}
fn get_programs(
rpc_client: &RpcClient,
authority_pubkey: Option<Pubkey>,
use_lamports_unit: bool,
) -> Result<CliUpgradeablePrograms, Box<dyn std::error::Error>> {
let mut filters = vec![RpcFilterType::Memcmp(Memcmp {
offset: 0,
bytes: MemcmpEncodedBytes::Binary(bs58::encode(vec![3, 0, 0, 0]).into_string()),
encoding: None,
})];
if let Some(authority_pubkey) = authority_pubkey {
filters.push(RpcFilterType::Memcmp(Memcmp {
offset: ACCOUNT_TYPE_SIZE + SLOT_SIZE,
bytes: MemcmpEncodedBytes::Binary(bs58::encode(vec![1]).into_string()),
encoding: None,
}));
filters.push(RpcFilterType::Memcmp(Memcmp {
offset: ACCOUNT_TYPE_SIZE + SLOT_SIZE + OPTION_SIZE,
bytes: MemcmpEncodedBytes::Binary(
bs58::encode(authority_pubkey.as_ref()).into_string(),
),
encoding: None,
}));
}
let results = get_accounts_with_filter(
rpc_client,
filters,
ACCOUNT_TYPE_SIZE + SLOT_SIZE + OPTION_SIZE + PUBKEY_LEN,
)?;
let mut programs = vec![];
for (programdata_address, programdata_account) in results.iter() {
if let Ok(UpgradeableLoaderState::ProgramData {
slot,
upgrade_authority_address,
}) = programdata_account.state()
{
let mut bytes = vec![2, 0, 0, 0];
bytes.extend_from_slice(programdata_address.as_ref());
let filters = vec![RpcFilterType::Memcmp(Memcmp {
offset: 0, offset: 0,
bytes: MemcmpEncodedBytes::Binary(bs58::encode(bytes).into_string()), bytes: MemcmpEncodedBytes::Binary(bs58::encode(bytes).into_string()),
encoding: None, encoding: None,
})]), })];
let results = get_accounts_with_filter(rpc_client, filters, 0)?;
if results.len() != 1 {
return Err(format!(
"Error: More than one Program associated with ProgramData account {}",
programdata_address
)
.into());
}
programs.push(CliUpgradeableProgram {
program_id: results[0].0.to_string(),
owner: programdata_account.owner.to_string(),
programdata_address: programdata_address.to_string(),
authority: upgrade_authority_address
.map(|pubkey| pubkey.to_string())
.unwrap_or_else(|| "none".to_string()),
last_deploy_slot: slot,
data_len: programdata_account.data.len()
- UpgradeableLoaderState::programdata_data_offset()?,
lamports: programdata_account.lamports,
use_lamports_unit,
});
} else {
return Err(
format!("Error parsing ProgramData account {}", programdata_address).into(),
);
}
}
Ok(CliUpgradeablePrograms {
programs,
use_lamports_unit,
})
}
fn get_accounts_with_filter(
rpc_client: &RpcClient,
filters: Vec<RpcFilterType>,
length: usize,
) -> Result<Vec<(Pubkey, Account)>, Box<dyn std::error::Error>> {
let results = rpc_client.get_program_accounts_with_config(
&bpf_loader_upgradeable::id(),
RpcProgramAccountsConfig {
filters: Some(filters),
account_config: RpcAccountInfoConfig { account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64), encoding: Some(UiAccountEncoding::Base64),
data_slice: Some(UiDataSliceConfig { offset: 0, length }), data_slice: Some(UiDataSliceConfig { offset: 0, length }),
@ -1158,6 +1300,8 @@ fn process_show(
config: &CliConfig, config: &CliConfig,
account_pubkey: Option<Pubkey>, account_pubkey: Option<Pubkey>,
authority_pubkey: Pubkey, authority_pubkey: Pubkey,
programs: bool,
buffers: bool,
all: bool, all: bool,
use_lamports_unit: bool, use_lamports_unit: bool,
) -> ProcessResult { ) -> ProcessResult {
@ -1198,6 +1342,8 @@ fn process_show(
last_deploy_slot: slot, last_deploy_slot: slot,
data_len: programdata_account.data.len() data_len: programdata_account.data.len()
- UpgradeableLoaderState::programdata_data_offset()?, - UpgradeableLoaderState::programdata_data_offset()?,
lamports: programdata_account.lamports,
use_lamports_unit,
})) }))
} else { } else {
Err(format!("Program {} has been closed", account_pubkey).into()) Err(format!("Program {} has been closed", account_pubkey).into())
@ -1222,7 +1368,7 @@ fn process_show(
})) }))
} else { } else {
Err(format!( Err(format!(
"{} is not an upgradeble loader buffer or program account", "{} is not an upgradeble loader Buffer or Program account",
account_pubkey account_pubkey
) )
.into()) .into())
@ -1233,31 +1379,16 @@ fn process_show(
} else { } else {
Err(format!("Unable to find the account {}", account_pubkey).into()) Err(format!("Unable to find the account {}", account_pubkey).into())
} }
} else { } else if programs {
let authority_pubkey = if all { None } else { Some(authority_pubkey) }; let authority_pubkey = if all { None } else { Some(authority_pubkey) };
let mut buffers = vec![]; let programs = get_programs(rpc_client, authority_pubkey, use_lamports_unit)?;
let results = get_buffers(rpc_client, authority_pubkey)?; Ok(config.output_format.formatted_string(&programs))
for (address, account) in results.iter() { } else if buffers {
if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state() { let authority_pubkey = if all { None } else { Some(authority_pubkey) };
buffers.push(CliUpgradeableBuffer { let buffers = get_buffers(rpc_client, authority_pubkey, use_lamports_unit)?;
address: address.to_string(), Ok(config.output_format.formatted_string(&buffers))
authority: authority_address } else {
.map(|pubkey| pubkey.to_string()) Err("Invalid parameters".to_string().into())
.unwrap_or_else(|| "none".to_string()),
data_len: 0,
lamports: account.lamports,
use_lamports_unit,
});
} else {
return Err(format!("Error parsing account {}", address).into());
}
}
Ok(config
.output_format
.formatted_string(&CliUpgradeableBuffers {
buffers,
use_lamports_unit,
}))
} }
} }
@ -1361,6 +1492,12 @@ fn close(
)) = err.kind() )) = err.kind()
{ {
return Err("Closing a buffer account is not supported by the cluster".into()); return Err("Closing a buffer account is not supported by the cluster".into());
} else if let ClientErrorKind::TransactionError(TransactionError::InstructionError(
_,
InstructionError::InvalidArgument,
)) = err.kind()
{
return Err("Closing a program account is not supported by the cluster".into());
} else { } else {
return Err(format!("Close failed: {}", err).into()); return Err(format!("Close failed: {}", err).into());
} }
@ -1377,7 +1514,6 @@ fn process_close(
use_lamports_unit: bool, use_lamports_unit: bool,
) -> ProcessResult { ) -> ProcessResult {
let authority_signer = config.signers[authority_index]; let authority_signer = config.signers[authority_index];
let mut buffers = vec![];
if let Some(account_pubkey) = account_pubkey { if let Some(account_pubkey) = account_pubkey {
if let Some(account) = rpc_client if let Some(account) = rpc_client
@ -1402,17 +1538,21 @@ fn process_close(
authority_signer, authority_signer,
None, None,
)?; )?;
buffers.push(CliUpgradeableBuffer {
address: account_pubkey.to_string(),
authority: authority_address
.map(|pubkey| pubkey.to_string())
.unwrap_or_else(|| "none".to_string()),
data_len: 0,
lamports: account.lamports,
use_lamports_unit,
});
} }
Ok(config
.output_format
.formatted_string(&CliUpgradeableBuffers {
buffers: vec![CliUpgradeableBuffer {
address: account_pubkey.to_string(),
authority: authority_address
.map(|pubkey| pubkey.to_string())
.unwrap_or_else(|| "none".to_string()),
data_len: 0,
lamports: account.lamports,
use_lamports_unit,
}],
use_lamports_unit,
}))
} }
Ok(UpgradeableLoaderState::Program { Ok(UpgradeableLoaderState::Program {
programdata_address: programdata_pubkey, programdata_address: programdata_pubkey,
@ -1442,13 +1582,13 @@ fn process_close(
authority_signer, authority_signer,
Some(&account_pubkey), Some(&account_pubkey),
)?; )?;
return Ok(config.output_format.formatted_string( Ok(config.output_format.formatted_string(
&CliUpgradeableProgramClosed { &CliUpgradeableProgramClosed {
program_id: account_pubkey.to_string(), program_id: account_pubkey.to_string(),
lamports: account.lamports, lamports: account.lamports,
use_lamports_unit, use_lamports_unit,
}, },
)); ))
} }
} else { } else {
return Err( return Err(
@ -1469,41 +1609,34 @@ fn process_close(
return Err(format!("Unable to find the account {}", account_pubkey).into()); return Err(format!("Unable to find the account {}", account_pubkey).into());
} }
} else { } else {
let results = get_buffers(rpc_client, Some(authority_signer.pubkey()))?; let buffers = get_buffers(
rpc_client,
Some(authority_signer.pubkey()),
use_lamports_unit,
)?;
for (address, account) in results.iter() { let mut closed = vec![];
for buffer in buffers.buffers.iter() {
if close( if close(
rpc_client, rpc_client,
config, config,
address, &Pubkey::from_str(&buffer.address)?,
&recipient_pubkey, &recipient_pubkey,
authority_signer, authority_signer,
None, None,
) )
.is_ok() .is_ok()
{ {
if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state() { closed.push(buffer.clone());
buffers.push(CliUpgradeableBuffer {
address: address.to_string(),
authority: authority_address
.map(|address| address.to_string())
.unwrap_or_else(|| "none".to_string()),
data_len: 0,
lamports: account.lamports,
use_lamports_unit,
});
} else {
return Err(format!("Error parsing account {}", address).into());
}
} }
} }
Ok(config
.output_format
.formatted_string(&CliUpgradeableBuffers {
buffers: closed,
use_lamports_unit,
}))
} }
Ok(config
.output_format
.formatted_string(&CliUpgradeableBuffers {
buffers,
use_lamports_unit,
}))
} }
/// Deploy using non-upgradeable loader /// Deploy using non-upgradeable loader
@ -2740,6 +2873,8 @@ mod tests {
command: CliCommand::Program(ProgramCliCommand::Show { command: CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(buffer_pubkey), account_pubkey: Some(buffer_pubkey),
authority_pubkey: default_keypair.pubkey(), authority_pubkey: default_keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}), }),
@ -2747,6 +2882,29 @@ mod tests {
} }
); );
let test_command = test_commands.clone().get_matches_from(vec![
"test",
"program",
"show",
"--programs",
"--all",
"--lamports",
]);
assert_eq!(
parse_command(&test_command, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: None,
authority_pubkey: default_keypair.pubkey(),
get_programs: true,
get_buffers: false,
all: true,
use_lamports_unit: true,
}),
signers: vec![],
}
);
let test_command = test_commands.clone().get_matches_from(vec![ let test_command = test_commands.clone().get_matches_from(vec![
"test", "test",
"program", "program",
@ -2761,6 +2919,8 @@ mod tests {
command: CliCommand::Program(ProgramCliCommand::Show { command: CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: None, account_pubkey: None,
authority_pubkey: default_keypair.pubkey(), authority_pubkey: default_keypair.pubkey(),
get_programs: false,
get_buffers: true,
all: true, all: true,
use_lamports_unit: true, use_lamports_unit: true,
}), }),
@ -2782,6 +2942,8 @@ mod tests {
command: CliCommand::Program(ProgramCliCommand::Show { command: CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: None, account_pubkey: None,
authority_pubkey: authority_keypair.pubkey(), authority_pubkey: authority_keypair.pubkey(),
get_programs: false,
get_buffers: true,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}), }),
@ -2803,6 +2965,8 @@ mod tests {
command: CliCommand::Program(ProgramCliCommand::Show { command: CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: None, account_pubkey: None,
authority_pubkey: authority_keypair.pubkey(), authority_pubkey: authority_keypair.pubkey(),
get_programs: false,
get_buffers: true,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}), }),

View File

@ -442,6 +442,8 @@ fn test_cli_program_deploy_with_authority() {
config.command = CliCommand::Program(ProgramCliCommand::Show { config.command = CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(program_pubkey), account_pubkey: Some(program_pubkey),
authority_pubkey: keypair.pubkey(), authority_pubkey: keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}); });
@ -533,6 +535,8 @@ fn test_cli_program_deploy_with_authority() {
config.command = CliCommand::Program(ProgramCliCommand::Show { config.command = CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(program_pubkey), account_pubkey: Some(program_pubkey),
authority_pubkey: keypair.pubkey(), authority_pubkey: keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}); });
@ -748,6 +752,8 @@ fn test_cli_program_write_buffer() {
config.command = CliCommand::Program(ProgramCliCommand::Show { config.command = CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(buffer_keypair.pubkey()), account_pubkey: Some(buffer_keypair.pubkey()),
authority_pubkey: keypair.pubkey(), authority_pubkey: keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}); });
@ -841,6 +847,8 @@ fn test_cli_program_write_buffer() {
config.command = CliCommand::Program(ProgramCliCommand::Show { config.command = CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(buffer_pubkey), account_pubkey: Some(buffer_pubkey),
authority_pubkey: keypair.pubkey(), authority_pubkey: keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}); });
@ -1177,6 +1185,8 @@ fn test_cli_program_show() {
config.command = CliCommand::Program(ProgramCliCommand::Show { config.command = CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(buffer_keypair.pubkey()), account_pubkey: Some(buffer_keypair.pubkey()),
authority_pubkey: keypair.pubkey(), authority_pubkey: keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}); });
@ -1237,6 +1247,8 @@ fn test_cli_program_show() {
config.command = CliCommand::Program(ProgramCliCommand::Show { config.command = CliCommand::Program(ProgramCliCommand::Show {
account_pubkey: Some(program_keypair.pubkey()), account_pubkey: Some(program_keypair.pubkey()),
authority_pubkey: keypair.pubkey(), authority_pubkey: keypair.pubkey(),
get_programs: false,
get_buffers: false,
all: false, all: false,
use_lamports_unit: false, use_lamports_unit: false,
}); });