cli: show upgradeable program accounts (#19431)
This commit is contained in:
parent
481ee48c35
commit
57bbbb83a4
|
@ -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,
|
||||||
|
|
|
@ -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
|
|
||||||
.map(|pubkey| pubkey.to_string())
|
|
||||||
.unwrap_or_else(|| "none".to_string()),
|
|
||||||
data_len: 0,
|
|
||||||
lamports: account.lamports,
|
|
||||||
use_lamports_unit,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Error parsing account {}", address).into());
|
Err("Invalid parameters".to_string().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,8 +1538,11 @@ fn process_close(
|
||||||
authority_signer,
|
authority_signer,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
buffers.push(CliUpgradeableBuffer {
|
Ok(config
|
||||||
|
.output_format
|
||||||
|
.formatted_string(&CliUpgradeableBuffers {
|
||||||
|
buffers: vec![CliUpgradeableBuffer {
|
||||||
address: account_pubkey.to_string(),
|
address: account_pubkey.to_string(),
|
||||||
authority: authority_address
|
authority: authority_address
|
||||||
.map(|pubkey| pubkey.to_string())
|
.map(|pubkey| pubkey.to_string())
|
||||||
|
@ -1411,8 +1550,9 @@ fn process_close(
|
||||||
data_len: 0,
|
data_len: 0,
|
||||||
lamports: account.lamports,
|
lamports: account.lamports,
|
||||||
use_lamports_unit,
|
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,42 +1609,35 @@ 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
|
Ok(config
|
||||||
.output_format
|
.output_format
|
||||||
.formatted_string(&CliUpgradeableBuffers {
|
.formatted_string(&CliUpgradeableBuffers {
|
||||||
buffers,
|
buffers: closed,
|
||||||
use_lamports_unit,
|
use_lamports_unit,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Deploy using non-upgradeable loader
|
/// Deploy using non-upgradeable loader
|
||||||
pub fn process_deploy(
|
pub fn process_deploy(
|
||||||
|
@ -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,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue