use crate::config::network;
use crate::print::Print;
use crate::{commands::global, config};
use semver::Version;
use stellar_xdr::curr::{
ConfigSettingId, ConfigUpgradeSet, LedgerEntryData, LedgerKey, LedgerKeyConfigSetting, Limits,
WriteXdr as _,
};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Config(#[from] config::Error),
#[error(transparent)]
Network(#[from] network::Error),
#[error(transparent)]
Xdr(#[from] stellar_xdr::curr::Error),
#[error(transparent)]
Serde(#[from] serde_json::Error),
#[error(transparent)]
Rpc(#[from] soroban_rpc::Error),
#[error(transparent)]
Semver(#[from] semver::Error),
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, Default)]
pub enum OutputFormat {
Xdr,
#[default]
Json,
JsonFormatted,
}
#[derive(Debug, clap::Parser, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub config: config::ArgsLocatorAndNetwork,
#[arg(long)]
pub internal: bool,
#[arg(long, default_value = "json")]
pub output: OutputFormat,
}
impl Cmd {
pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
let print = Print::new(global_args.quiet);
let rpc = self.config.get_network()?.rpc_client()?;
let network_version = rpc.get_version_info().await?.protocol_version;
let self_version = Version::parse(stellar_xdr::VERSION.pkg)?.major;
if self_version < network_version.into() {
print.warnln(format!("Network protocol version is {network_version} but the stellar-cli supports {self_version}. The config fetched may not represent the complete config settings for the network. Upgrade the stellar-cli."));
}
let keys = ConfigSettingId::variants()
.into_iter()
.filter(|id| match id {
ConfigSettingId::LiveSorobanStateSizeWindow | ConfigSettingId::EvictionIterator => {
self.internal
}
_ => true,
})
.map(|id| {
LedgerKey::ConfigSetting(LedgerKeyConfigSetting {
config_setting_id: id,
})
})
.collect::<Vec<_>>();
let settings = rpc
.get_full_ledger_entries(&keys)
.await?
.entries
.into_iter()
.filter_map(|e| match e.val {
LedgerEntryData::ConfigSetting(setting) => Some(setting),
_ => None,
})
.collect::<Vec<_>>();
let config_upgrade_set = ConfigUpgradeSet {
updated_entry: settings.try_into().unwrap(),
};
match self.output {
OutputFormat::Xdr => println!("{}", config_upgrade_set.to_xdr_base64(Limits::none())?),
OutputFormat::Json => println!("{}", serde_json::to_string(&config_upgrade_set)?),
OutputFormat::JsonFormatted => {
println!("{}", serde_json::to_string_pretty(&config_upgrade_set)?);
}
}
Ok(())
}
}