1use std::io::stderr;
2
3use soroban_rpc::GetTransactionResponse;
4
5use crate::assembled::Assembled;
6use crate::commands::tx::fetch;
7use crate::commands::tx::fetch::fee::FeeTable;
8use crate::commands::HEADING_RPC;
9use crate::xdr;
10
11#[derive(Debug, clap::Args, Clone)]
12#[group(skip)]
13pub struct Args {
14 #[arg(long, default_value = "100", env = "STELLAR_FEE", help_heading = HEADING_RPC)]
16 pub fee: u32,
17 #[arg(long = "cost", help_heading = HEADING_RPC)]
19 pub cost: bool,
20 #[arg(long, help_heading = HEADING_RPC)]
22 pub instructions: Option<u32>,
23 #[arg(long, help_heading = HEADING_RPC)]
25 pub instruction_leeway: Option<u64>,
26 #[arg(long, help_heading = HEADING_RPC)]
28 pub build_only: bool,
29}
30
31impl Args {
32 pub fn apply_to_assembled_txn(&self, txn: Assembled) -> Assembled {
33 if let Some(instructions) = self.instructions {
34 txn.set_max_instructions(instructions)
35 } else {
36 add_padding_to_instructions(txn)
37 }
38 }
39
40 pub fn resource_config(&self) -> Option<soroban_rpc::ResourceConfig> {
41 self.instruction_leeway
42 .map(|instruction_leeway| soroban_rpc::ResourceConfig { instruction_leeway })
43 }
44
45 pub fn print_cost_info(&self, res: &GetTransactionResponse) -> Result<(), fetch::Error> {
46 if !self.cost {
47 return Ok(());
48 }
49
50 let fee_table = FeeTable::new_from_transaction_response(res)?;
51
52 fee_table.table().print(&mut stderr())?;
53
54 Ok(())
55 }
56}
57
58pub fn add_padding_to_instructions(txn: Assembled) -> Assembled {
59 let xdr::TransactionExt::V1(xdr::SorobanTransactionData {
60 resources: xdr::SorobanResources { instructions, .. },
61 ..
62 }) = txn.transaction().ext
63 else {
64 return txn;
65 };
66 let instructions = (instructions.checked_mul(150 / 100)).unwrap_or(instructions);
68 txn.set_max_instructions(instructions)
69}
70
71impl Default for Args {
72 fn default() -> Self {
73 Self {
74 fee: 100,
75 cost: false,
76 instructions: None,
77 instruction_leeway: None,
78 build_only: false,
79 }
80 }
81}