Skip to main content

soroban_cli/commands/tx/
simulate.rs

1use crate::{
2    assembled::{simulate_and_assemble_transaction, Assembled},
3    xdr::{self, TransactionEnvelope, WriteXdr},
4};
5use std::ffi::OsString;
6
7use crate::commands::{config, global};
8
9#[derive(thiserror::Error, Debug)]
10pub enum Error {
11    #[error(transparent)]
12    XdrArgs(#[from] super::xdr::Error),
13    #[error(transparent)]
14    Config(#[from] super::super::config::Error),
15    #[error(transparent)]
16    Rpc(#[from] crate::rpc::Error),
17    #[error(transparent)]
18    Xdr(#[from] xdr::Error),
19    #[error(transparent)]
20    Network(#[from] config::network::Error),
21}
22
23/// Command to simulate a transaction envelope via rpc
24/// e.g. `stellar tx simulate file.txt` or `cat file.txt | stellar tx simulate`
25#[derive(Debug, clap::Parser, Clone, Default)]
26#[group(skip)]
27pub struct Cmd {
28    /// Base-64 transaction envelope XDR or file containing XDR to decode, or stdin if empty
29    #[arg()]
30    pub tx_xdr: Option<OsString>,
31
32    #[clap(flatten)]
33    pub config: config::Args,
34
35    /// Allow this many extra instructions when budgeting resources during transaction simulation
36    #[arg(long)]
37    pub instruction_leeway: Option<u64>,
38}
39
40impl Cmd {
41    pub async fn run(&self, _global_args: &global::Args) -> Result<(), Error> {
42        let res = self.execute(&self.config).await?;
43        let tx_env: TransactionEnvelope = res.transaction().clone().into();
44        println!("{}", tx_env.to_xdr_base64(xdr::Limits::none())?);
45        Ok(())
46    }
47
48    pub async fn execute(&self, config: &config::Args) -> Result<Assembled, Error> {
49        let network = config.get_network()?;
50        let client = network.rpc_client()?;
51        let tx = super::xdr::unwrap_envelope_v1(super::xdr::tx_envelope_from_input(&self.tx_xdr)?)?;
52        let resource_config = self
53            .instruction_leeway
54            .map(|instruction_leeway| soroban_rpc::ResourceConfig { instruction_leeway });
55        let tx = simulate_and_assemble_transaction(&client, &tx, resource_config, None).await?;
56        Ok(tx)
57    }
58}