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