cli: add program show for non-upgradeable programs (#15707)
This commit is contained in:
@ -1621,10 +1621,34 @@ impl fmt::Display for CliProgramAuthority {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CliProgram {
|
||||||
|
pub program_id: String,
|
||||||
|
pub owner: String,
|
||||||
|
pub data_len: usize,
|
||||||
|
}
|
||||||
|
impl QuietDisplay for CliProgram {}
|
||||||
|
impl VerboseDisplay for CliProgram {}
|
||||||
|
impl fmt::Display for CliProgram {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
writeln!(f)?;
|
||||||
|
writeln_name_value(f, "Program Id:", &self.program_id)?;
|
||||||
|
writeln_name_value(f, "Owner:", &self.owner)?;
|
||||||
|
writeln_name_value(
|
||||||
|
f,
|
||||||
|
"Data Length:",
|
||||||
|
&format!("{:?} ({:#x?}) bytes", self.data_len, self.data_len),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CliUpgradeableProgram {
|
pub struct CliUpgradeableProgram {
|
||||||
pub program_id: String,
|
pub program_id: String,
|
||||||
|
pub owner: String,
|
||||||
pub programdata_address: String,
|
pub programdata_address: String,
|
||||||
pub authority: String,
|
pub authority: String,
|
||||||
pub last_deploy_slot: u64,
|
pub last_deploy_slot: u64,
|
||||||
@ -1636,6 +1660,7 @@ impl fmt::Display for CliUpgradeableProgram {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
writeln_name_value(f, "Program Id:", &self.program_id)?;
|
writeln_name_value(f, "Program Id:", &self.program_id)?;
|
||||||
|
writeln_name_value(f, "Owner:", &self.owner)?;
|
||||||
writeln_name_value(f, "ProgramData Address:", &self.programdata_address)?;
|
writeln_name_value(f, "ProgramData Address:", &self.programdata_address)?;
|
||||||
writeln_name_value(f, "Authority:", &self.authority)?;
|
writeln_name_value(f, "Authority:", &self.authority)?;
|
||||||
writeln_name_value(
|
writeln_name_value(
|
||||||
|
@ -13,7 +13,7 @@ use log::*;
|
|||||||
use solana_bpf_loader_program::{bpf_verifier, BpfError, ThisInstructionMeter};
|
use solana_bpf_loader_program::{bpf_verifier, BpfError, ThisInstructionMeter};
|
||||||
use solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*};
|
use solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*};
|
||||||
use solana_cli_output::{
|
use solana_cli_output::{
|
||||||
display::new_spinner_progress_bar, CliProgramAccountType, CliProgramAuthority,
|
display::new_spinner_progress_bar, CliProgram, CliProgramAccountType, CliProgramAuthority,
|
||||||
CliProgramBuffer, CliProgramId, CliUpgradeableBuffer, CliUpgradeableProgram,
|
CliProgramBuffer, CliProgramId, CliUpgradeableBuffer, CliUpgradeableProgram,
|
||||||
};
|
};
|
||||||
use solana_client::{
|
use solana_client::{
|
||||||
@ -933,54 +933,69 @@ fn process_show(
|
|||||||
.get_account_with_commitment(&account_pubkey, config.commitment)?
|
.get_account_with_commitment(&account_pubkey, config.commitment)?
|
||||||
.value
|
.value
|
||||||
{
|
{
|
||||||
if let Ok(UpgradeableLoaderState::Program {
|
if account.owner == bpf_loader::id() || account.owner == bpf_loader_deprecated::id() {
|
||||||
programdata_address,
|
Ok(config.output_format.formatted_string(&CliProgram {
|
||||||
}) = account.state()
|
program_id: account_pubkey.to_string(),
|
||||||
{
|
owner: account.owner.to_string(),
|
||||||
if let Some(programdata_account) = rpc_client
|
data_len: account.data.len(),
|
||||||
.get_account_with_commitment(&programdata_address, config.commitment)?
|
}))
|
||||||
.value
|
} else if account.owner == bpf_loader_upgradeable::id() {
|
||||||
|
if let Ok(UpgradeableLoaderState::Program {
|
||||||
|
programdata_address,
|
||||||
|
}) = account.state()
|
||||||
{
|
{
|
||||||
if let Ok(UpgradeableLoaderState::ProgramData {
|
if let Some(programdata_account) = rpc_client
|
||||||
upgrade_authority_address,
|
.get_account_with_commitment(&programdata_address, config.commitment)?
|
||||||
slot,
|
.value
|
||||||
}) = programdata_account.state()
|
|
||||||
{
|
{
|
||||||
Ok(config
|
if let Ok(UpgradeableLoaderState::ProgramData {
|
||||||
.output_format
|
upgrade_authority_address,
|
||||||
.formatted_string(&CliUpgradeableProgram {
|
slot,
|
||||||
program_id: account_pubkey.to_string(),
|
}) = programdata_account.state()
|
||||||
programdata_address: programdata_address.to_string(),
|
{
|
||||||
authority: upgrade_authority_address
|
Ok(config
|
||||||
.map(|pubkey| pubkey.to_string())
|
.output_format
|
||||||
.unwrap_or_else(|| "none".to_string()),
|
.formatted_string(&CliUpgradeableProgram {
|
||||||
last_deploy_slot: slot,
|
program_id: account_pubkey.to_string(),
|
||||||
data_len: programdata_account.data.len()
|
owner: account.owner.to_string(),
|
||||||
- UpgradeableLoaderState::programdata_data_offset()?,
|
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()?,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Err(
|
||||||
|
"Invalid associated ProgramData account found for the program"
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err("Invalid associated ProgramData account found for the program".into())
|
Err(
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(
|
|
||||||
"Failed to find associated ProgramData account for the provided program"
|
"Failed to find associated ProgramData account for the provided program"
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
} else if let Ok(UpgradeableLoaderState::Buffer { authority_address }) =
|
||||||
|
account.state()
|
||||||
|
{
|
||||||
|
Ok(config
|
||||||
|
.output_format
|
||||||
|
.formatted_string(&CliUpgradeableBuffer {
|
||||||
|
address: account_pubkey.to_string(),
|
||||||
|
authority: authority_address
|
||||||
|
.map(|pubkey| pubkey.to_string())
|
||||||
|
.unwrap_or_else(|| "none".to_string()),
|
||||||
|
data_len: account.data.len()
|
||||||
|
- UpgradeableLoaderState::buffer_data_offset()?,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Err("Not a buffer or program account".into())
|
||||||
}
|
}
|
||||||
} else if let Ok(UpgradeableLoaderState::Buffer { authority_address }) = account.state()
|
|
||||||
{
|
|
||||||
Ok(config
|
|
||||||
.output_format
|
|
||||||
.formatted_string(&CliUpgradeableBuffer {
|
|
||||||
address: account_pubkey.to_string(),
|
|
||||||
authority: authority_address
|
|
||||||
.map(|pubkey| pubkey.to_string())
|
|
||||||
.unwrap_or_else(|| "none".to_string()),
|
|
||||||
data_len: account.data.len()
|
|
||||||
- UpgradeableLoaderState::buffer_data_offset()?,
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
Err("Not a buffer or program account".into())
|
Err("Accont is not a BPF program".into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err("Unable to find the account".into())
|
Err("Unable to find the account".into())
|
||||||
|
@ -69,6 +69,7 @@ An example output looks like:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
Program Id: 3KS2k14CmtnuVv2fvYcvdrNgC94Y11WETBpMUGgXyWZL
|
Program Id: 3KS2k14CmtnuVv2fvYcvdrNgC94Y11WETBpMUGgXyWZL
|
||||||
|
Owner: BPFLoaderUpgradeab1e11111111111111111111111
|
||||||
ProgramData Address: EHsACWBhgmw8iq5dmUZzTA1esRqcTognhKNHUkPi4q4g
|
ProgramData Address: EHsACWBhgmw8iq5dmUZzTA1esRqcTognhKNHUkPi4q4g
|
||||||
Authority: FwoGJNUaJN2zfVEex9BB11Dqb3NJKy3e9oY3KTh9XzCU
|
Authority: FwoGJNUaJN2zfVEex9BB11Dqb3NJKy3e9oY3KTh9XzCU
|
||||||
Last Deployed In Slot: 63890568
|
Last Deployed In Slot: 63890568
|
||||||
@ -77,6 +78,7 @@ Data Length: 5216 (0x1460) bytes
|
|||||||
|
|
||||||
- `Program Id` is the address that can be referenced in an instruction's
|
- `Program Id` is the address that can be referenced in an instruction's
|
||||||
`program_id` field when invoking a program.
|
`program_id` field when invoking a program.
|
||||||
|
- `Owner`: The loader this program was deployed with.
|
||||||
- `ProgramData Address` is the account associated with the program account that
|
- `ProgramData Address` is the account associated with the program account that
|
||||||
holds the program's data (shared object).
|
holds the program's data (shared object).
|
||||||
- `Authority` is the program's upgrade authority.
|
- `Authority` is the program's upgrade authority.
|
||||||
|
Reference in New Issue
Block a user