soroban_cli/commands/network/
settings.rs1use crate::config::network;
2use crate::output::{Format, Output};
3use crate::{commands::global, config};
4use semver::Version;
5use stellar_xdr::{
6 ConfigSettingId, ConfigUpgradeSet, LedgerEntryData, LedgerKey, LedgerKeyConfigSetting, Limits,
7 WriteXdr as _,
8};
9
10#[derive(thiserror::Error, Debug)]
11pub enum Error {
12 #[error(transparent)]
13 Config(#[from] config::Error),
14 #[error(transparent)]
15 Network(#[from] network::Error),
16 #[error(transparent)]
17 Xdr(#[from] stellar_xdr::Error),
18 #[error(transparent)]
19 Serde(#[from] serde_json::Error),
20 #[error(transparent)]
21 Rpc(#[from] soroban_rpc::Error),
22 #[error(transparent)]
23 Semver(#[from] semver::Error),
24}
25
26#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, Default)]
27pub enum OutputFormat {
28 Xdr,
30 #[default]
32 Json,
33 JsonFormatted,
35}
36
37impl From<OutputFormat> for Format {
38 fn from(value: OutputFormat) -> Self {
39 match value {
40 OutputFormat::Xdr => Format::Readable,
42 OutputFormat::Json => Format::Json,
43 OutputFormat::JsonFormatted => Format::JsonFormatted,
44 }
45 }
46}
47
48#[derive(Debug, clap::Parser, Clone)]
49#[group(skip)]
50pub struct Cmd {
51 #[command(flatten)]
52 pub config: config::ArgsLocatorAndNetwork,
53 #[arg(long)]
56 pub internal: bool,
57 #[arg(long, default_value = "json")]
59 pub output: OutputFormat,
60}
61
62impl Cmd {
63 pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
64 let output = Output::new(self.output.into(), global_args.quiet);
65 let rpc = self.config.get_network()?.rpc_client()?;
66
67 let network_version = rpc.get_version_info().await?.protocol_version;
72 let self_version = Version::parse(stellar_xdr::VERSION.pkg)?.major;
73 if self_version < network_version.into() {
74 output.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."));
77 }
78
79 let keys = ConfigSettingId::variants()
81 .into_iter()
82 .filter(|id| match id {
83 ConfigSettingId::LiveSorobanStateSizeWindow | ConfigSettingId::EvictionIterator => {
86 self.internal
87 }
88 _ => true,
90 })
91 .map(|id| {
92 LedgerKey::ConfigSetting(LedgerKeyConfigSetting {
93 config_setting_id: id,
94 })
95 })
96 .collect::<Vec<_>>();
97 let settings = rpc
98 .get_full_ledger_entries(&keys)
99 .await?
100 .entries
101 .into_iter()
102 .filter_map(|e| match e.val {
103 LedgerEntryData::ConfigSetting(setting) => Some(setting),
104 _ => None,
105 })
106 .collect::<Vec<_>>();
107
108 let config_upgrade_set = ConfigUpgradeSet {
109 updated_entry: settings.try_into().unwrap(),
110 };
111 match self.output {
112 OutputFormat::Xdr => println!("{}", config_upgrade_set.to_xdr_base64(Limits::none())?),
114 OutputFormat::Json | OutputFormat::JsonFormatted => {
115 output.json_value(&config_upgrade_set)?;
116 }
117 }
118 Ok(())
119 }
120}