From 5c4ae705e8b0e08e3db61c6874548c19b25da243 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:34:39 -0500 Subject: [PATCH 01/17] Add tx edit subcommand --- cmd/soroban-cli/src/commands/tx/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/soroban-cli/src/commands/tx/mod.rs b/cmd/soroban-cli/src/commands/tx/mod.rs index 31c97dfbe0..40c874588d 100644 --- a/cmd/soroban-cli/src/commands/tx/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/mod.rs @@ -1,6 +1,7 @@ use super::global; pub mod args; +pub mod edit; pub mod hash; pub mod help; pub mod new; @@ -14,6 +15,9 @@ pub use args::Args; #[derive(Debug, clap::Subcommand)] pub enum Cmd { + /// Edit the transaction + #[command(subcommand)] + Edit(edit::Cmd), /// Calculate the hash of a transaction envelope Hash(hash::Cmd), /// Create a new transaction @@ -32,6 +36,8 @@ pub enum Cmd { #[derive(thiserror::Error, Debug)] pub enum Error { + #[error(transparent)] + Edit(#[from] edit::Error), #[error(transparent)] Hash(#[from] hash::Error), #[error(transparent)] @@ -51,6 +57,7 @@ pub enum Error { impl Cmd { pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { + Cmd::Edit(cmd) => cmd.run(global_args)?, Cmd::Hash(cmd) => cmd.run(global_args)?, Cmd::New(cmd) => cmd.run(global_args).await?, Cmd::Operation(cmd) => cmd.run(global_args).await?, From 8931ecc0740c3f8d0d80319579503664ca290c09 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:34:59 -0500 Subject: [PATCH 02/17] Add tx edit seq-num bump command --- cmd/soroban-cli/src/commands/tx/edit/mod.rs | 25 ++++++++++ .../commands/tx/edit/sequence_number/bump.rs | 46 +++++++++++++++++++ .../commands/tx/edit/sequence_number/mod.rs | 25 ++++++++++ 3 files changed, 96 insertions(+) create mode 100644 cmd/soroban-cli/src/commands/tx/edit/mod.rs create mode 100644 cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs create mode 100644 cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs diff --git a/cmd/soroban-cli/src/commands/tx/edit/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/mod.rs new file mode 100644 index 0000000000..d5113a92e6 --- /dev/null +++ b/cmd/soroban-cli/src/commands/tx/edit/mod.rs @@ -0,0 +1,25 @@ +use super::global; + +pub mod sequence_number; + +#[derive(Debug, clap::Subcommand)] +pub enum Cmd { + /// Set the sequence number on a transaction + #[command(subcommand, visible_alias = "seq-num")] + SequenceNumber(sequence_number::Cmd), +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + SequenceNumber(#[from] sequence_number::Error), +} + +impl Cmd { + pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { + match self { + Cmd::SequenceNumber(cmd) => cmd.run(global_args)?, + }; + Ok(()) + } +} \ No newline at end of file diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs new file mode 100644 index 0000000000..c0dd720f36 --- /dev/null +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs @@ -0,0 +1,46 @@ +use crate::{ + commands::{ + global, + tx::xdr::{tx_envelope_from_input, Error as XdrParsingError}, + }, + xdr::{self, SequenceNumber, TransactionEnvelope, WriteXdr}, +}; + +#[derive(clap::Parser, Debug, Clone)] +pub struct Cmd {} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + XdrStdin(#[from] XdrParsingError), + #[error(transparent)] + Xdr(#[from] xdr::Error), + #[error("only V1 transactions are supported")] + Unsupported, +} + +impl Cmd { + pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { + let mut tx = tx_envelope_from_input(&None)?; + self.update_tx_env(&mut tx, global_args)?; + println!("{}", tx.to_xdr_base64(xdr::Limits::none())?); + Ok(()) + } + + pub fn update_tx_env( + &self, + tx_env: &mut TransactionEnvelope, + _global: &global::Args, + ) -> Result<(), Error> { + match tx_env { + TransactionEnvelope::Tx(transaction_v1_envelope) => { + let bump = transaction_v1_envelope.tx.seq_num.as_ref() + 1; + transaction_v1_envelope.tx.seq_num = SequenceNumber(bump); + } + TransactionEnvelope::TxV0(_) | TransactionEnvelope::TxFeeBump(_) => { + return Err(Error::Unsupported); + } + }; + Ok(()) + } +} \ No newline at end of file diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs new file mode 100644 index 0000000000..4daf714af0 --- /dev/null +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs @@ -0,0 +1,25 @@ +use super::global; + +mod bump; + +#[derive(Debug, clap::Subcommand)] +pub enum Cmd { + /// Bump the transaction's sequence number + #[command()] + Bump(bump::Cmd), +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Bump(#[from] bump::Error), +} + +impl Cmd { + pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { + match self { + Cmd::Bump(cmd) => cmd.run(global_args)?, + }; + Ok(()) + } +} \ No newline at end of file From 4dff945a867cfb81983a761d0c1d91bc03428ab5 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Thu, 6 Mar 2025 14:14:14 -0500 Subject: [PATCH 03/17] Add tx edit seq-num bump it test --- .../soroban-test/tests/it/integration/tx.rs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index e4cb177795..7874a68649 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -56,6 +56,63 @@ async fn simulate() { ); } +pub fn test_address(sandbox: &TestEnv) -> String { + sandbox + .new_assert_cmd("keys") + .arg("address") + .arg("test") + .assert() + .success() + .stdout_as_str() +} + +fn new_account(sandbox: &TestEnv, name: &str) -> String { + sandbox.generate_account(name, None).assert().success(); + sandbox + .new_assert_cmd("keys") + .args(["address", name]) + .assert() + .success() + .stdout_as_str() +} + +fn test_tx_string(sandbox: &TestEnv) -> String { + sandbox + .new_assert_cmd("contract") + .arg("install") + .args([ + "--wasm", + HELLO_WORLD.path().as_os_str().to_str().unwrap(), + "--build-only", + ]) + .assert() + .success() + .stdout_as_str() +} + +#[test] +fn sequence_number_bump() { + let sandbox = &TestEnv::new(); + let test_address = test_address(sandbox); // this returns the address for the account with alias "test" + let tx_base64 = test_tx_string(sandbox); + let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); + let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); + let current_seq_num = tx.seq_num.as_ref(); + + let updated_tx = sandbox + .new_assert_cmd("tx") + .arg("edit") + .arg("sequence-number") + .arg("bump") + .write_stdin(tx_base64.as_bytes()) + .assert() + .success() + .stdout_as_str(); + let updated_tx_env = TransactionEnvelope::from_xdr_base64(&updated_tx, Limits::none()).unwrap(); + let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(updated_tx_env).unwrap(); + assert_eq!(tx.seq_num, soroban_cli::xdr::SequenceNumber(current_seq_num + 1)); +} + #[tokio::test] async fn txn_hash() { let sandbox = &TestEnv::new(); From 06e422f604825fe55d8f2a943a3154dec3f94d35 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:30:16 -0500 Subject: [PATCH 04/17] Factor out an it helper --- .../tests/it/integration/custom_types.rs | 6 ++--- .../soroban-test/tests/it/integration/tx.rs | 24 ++----------------- .../tests/it/integration/tx/operations.rs | 13 ++-------- .../soroban-test/tests/it/integration/util.rs | 12 +++++++++- 4 files changed, 17 insertions(+), 38 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs index f4c2be61b5..43b1364326 100644 --- a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs +++ b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs @@ -3,9 +3,7 @@ use serde_json::json; use soroban_cli::commands; use soroban_test::TestEnv; -use crate::integration::util::{deploy_custom, extend_contract}; - -use super::util::{invoke, invoke_with_roundtrip}; +use crate::integration::util::{deploy_custom, extend_contract, invoke, invoke_with_roundtrip, test_address}; fn invoke_custom(e: &TestEnv, id: &str, func: &str) -> assert_cmd::Command { let mut s = e.new_assert_cmd("contract"); @@ -241,7 +239,7 @@ async fn account_address(sandbox: &TestEnv, id: &str) { async fn account_address_with_alias(sandbox: &TestEnv, id: &str) { let res = invoke(sandbox, id, "addresse", &json!("test").to_string()).await; - let test = format!("\"{}\"", super::tx::operations::test_address(sandbox)); + let test = format!("\"{}\"", test_address(sandbox)); assert_eq!(test, res); } diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 7874a68649..1033eeb3a4 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -2,7 +2,7 @@ use soroban_cli::assembled::simulate_and_assemble_transaction; use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; -use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD}; +use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD, test_address}; pub mod operations; @@ -56,26 +56,6 @@ async fn simulate() { ); } -pub fn test_address(sandbox: &TestEnv) -> String { - sandbox - .new_assert_cmd("keys") - .arg("address") - .arg("test") - .assert() - .success() - .stdout_as_str() -} - -fn new_account(sandbox: &TestEnv, name: &str) -> String { - sandbox.generate_account(name, None).assert().success(); - sandbox - .new_assert_cmd("keys") - .args(["address", name]) - .assert() - .success() - .stdout_as_str() -} - fn test_tx_string(sandbox: &TestEnv) -> String { sandbox .new_assert_cmd("contract") @@ -93,7 +73,7 @@ fn test_tx_string(sandbox: &TestEnv) -> String { #[test] fn sequence_number_bump() { let sandbox = &TestEnv::new(); - let test_address = test_address(sandbox); // this returns the address for the account with alias "test" + let test_address = test_address(sandbox); // address for the account with alias "test" let tx_base64 = test_tx_string(sandbox); let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); diff --git a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs index 880c8b1cf3..9f70e41b90 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs @@ -4,24 +4,15 @@ use soroban_cli::{ utils::contract_id_hash_from_asset, xdr::{self, ReadXdr, SequenceNumber}, }; + use soroban_rpc::LedgerEntryResult; use soroban_test::{AssertExt, TestEnv}; use crate::integration::{ hello_world::invoke_hello_world, - util::{deploy_contract, DeployOptions, HELLO_WORLD}, + util::{deploy_contract, DeployOptions, HELLO_WORLD, test_address}, }; -pub fn test_address(sandbox: &TestEnv) -> String { - sandbox - .new_assert_cmd("keys") - .arg("address") - .arg("test") - .assert() - .success() - .stdout_as_str() -} - fn new_account(sandbox: &TestEnv, name: &str) -> String { sandbox.generate_account(name, None).assert().success(); sandbox diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index 5544791847..16b5de1b6b 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -2,7 +2,7 @@ use soroban_cli::{ commands, xdr::{Limits, WriteXdr}, }; -use soroban_test::{TestEnv, Wasm}; +use soroban_test::{AssertExt, TestEnv, Wasm}; use std::fmt::Display; pub const HELLO_WORLD: &Wasm = &Wasm::Custom("test-wasms", "test_hello_world"); @@ -123,3 +123,13 @@ pub async fn extend(sandbox: &TestEnv, id: &str, value: Option<&str>) { .assert() .success(); } + +pub fn test_address(sandbox: &TestEnv) -> String { + sandbox + .new_assert_cmd("keys") + .arg("address") + .arg("test") + .assert() + .success() + .stdout_as_str() +} \ No newline at end of file From 34ac90b9d47ed0c7a11c411d0e5c1a18d8dffa27 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:57:15 -0500 Subject: [PATCH 05/17] Apply cargo fmt changes --- .../tests/it/integration/custom_types.rs | 4 ++- .../soroban-test/tests/it/integration/tx.rs | 29 +++++++++++-------- .../tests/it/integration/tx/operations.rs | 2 +- .../soroban-test/tests/it/integration/util.rs | 2 +- cmd/soroban-cli/src/commands/tx/edit/mod.rs | 2 +- .../commands/tx/edit/sequence_number/bump.rs | 2 +- .../commands/tx/edit/sequence_number/mod.rs | 2 +- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs index 43b1364326..6ccec4fbb2 100644 --- a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs +++ b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs @@ -3,7 +3,9 @@ use serde_json::json; use soroban_cli::commands; use soroban_test::TestEnv; -use crate::integration::util::{deploy_custom, extend_contract, invoke, invoke_with_roundtrip, test_address}; +use crate::integration::util::{ + deploy_custom, extend_contract, invoke, invoke_with_roundtrip, test_address, +}; fn invoke_custom(e: &TestEnv, id: &str, func: &str) -> assert_cmd::Command { let mut s = e.new_assert_cmd("contract"); diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 560efe60d8..f3f60d300b 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -2,7 +2,9 @@ use soroban_cli::assembled::simulate_and_assemble_transaction; use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; -use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD, test_address}; +use crate::integration::util::{ + deploy_contract, test_address, DeployKind, DeployOptions, HELLO_WORLD, +}; pub mod operations; @@ -62,16 +64,16 @@ async fn simulate() { fn test_tx_string(sandbox: &TestEnv) -> String { sandbox - .new_assert_cmd("contract") - .arg("install") - .args([ - "--wasm", - HELLO_WORLD.path().as_os_str().to_str().unwrap(), - "--build-only", - ]) - .assert() - .success() - .stdout_as_str() + .new_assert_cmd("contract") + .arg("install") + .args([ + "--wasm", + HELLO_WORLD.path().as_os_str().to_str().unwrap(), + "--build-only", + ]) + .assert() + .success() + .stdout_as_str() } #[test] @@ -94,7 +96,10 @@ fn sequence_number_bump() { .stdout_as_str(); let updated_tx_env = TransactionEnvelope::from_xdr_base64(&updated_tx, Limits::none()).unwrap(); let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(updated_tx_env).unwrap(); - assert_eq!(tx.seq_num, soroban_cli::xdr::SequenceNumber(current_seq_num + 1)); + assert_eq!( + tx.seq_num, + soroban_cli::xdr::SequenceNumber(current_seq_num + 1) + ); } #[tokio::test] diff --git a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs index 9f70e41b90..ff3f7aa60c 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs @@ -10,7 +10,7 @@ use soroban_test::{AssertExt, TestEnv}; use crate::integration::{ hello_world::invoke_hello_world, - util::{deploy_contract, DeployOptions, HELLO_WORLD, test_address}, + util::{deploy_contract, test_address, DeployOptions, HELLO_WORLD}, }; fn new_account(sandbox: &TestEnv, name: &str) -> String { diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs index f0e6081699..cdb468898b 100644 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ b/cmd/crates/soroban-test/tests/it/integration/util.rs @@ -134,4 +134,4 @@ pub fn test_address(sandbox: &TestEnv) -> String { .assert() .success() .stdout_as_str() -} \ No newline at end of file +} diff --git a/cmd/soroban-cli/src/commands/tx/edit/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/mod.rs index d5113a92e6..824a283c9e 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/mod.rs @@ -22,4 +22,4 @@ impl Cmd { }; Ok(()) } -} \ No newline at end of file +} diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs index c0dd720f36..b45535186c 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs @@ -43,4 +43,4 @@ impl Cmd { }; Ok(()) } -} \ No newline at end of file +} diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs index 4daf714af0..6db1ae3404 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs @@ -22,4 +22,4 @@ impl Cmd { }; Ok(()) } -} \ No newline at end of file +} From 81f531c7e1e80a7c8941e570ddc7929b204dc13a Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Fri, 7 Mar 2025 16:38:48 -0500 Subject: [PATCH 06/17] Clippy --- cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs index b45535186c..a4815a0c14 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs @@ -22,13 +22,12 @@ pub enum Error { impl Cmd { pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { let mut tx = tx_envelope_from_input(&None)?; - self.update_tx_env(&mut tx, global_args)?; + Self::update_tx_env(&mut tx, global_args)?; println!("{}", tx.to_xdr_base64(xdr::Limits::none())?); Ok(()) } pub fn update_tx_env( - &self, tx_env: &mut TransactionEnvelope, _global: &global::Args, ) -> Result<(), Error> { From daf06fde10521e5a3551488c81533a41480545a1 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:05:35 -0500 Subject: [PATCH 07/17] Check in generated docs --- FULL_HELP_DOCS.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 0470b5fd01..caeca7ef44 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -1515,6 +1515,7 @@ Sign, Simulate, and Send transactions ###### **Subcommands:** +* `edit` — Edit the transaction * `hash` — Calculate the hash of a transaction envelope * `new` — Create a new transaction * `operation` — Manipulate the operations in a transaction, including adding new operations @@ -1524,6 +1525,38 @@ Sign, Simulate, and Send transactions +## `stellar tx edit` + +Edit the transaction + +**Usage:** `stellar tx edit ` + +###### **Subcommands:** + +* `sequence-number` — Set the sequence number on a transaction + + + +## `stellar tx edit sequence-number` + +Set the sequence number on a transaction + +**Usage:** `stellar tx edit sequence-number ` + +###### **Subcommands:** + +* `bump` — Bump the transaction's sequence number + + + +## `stellar tx edit sequence-number bump` + +Bump the transaction's sequence number + +**Usage:** `stellar tx edit sequence-number bump` + + + ## `stellar tx hash` Calculate the hash of a transaction envelope From 84c7251c8673edb63cb8974d21d3ea053be75f1b Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:28:29 -0500 Subject: [PATCH 08/17] Add bump amount arg --- .../soroban-test/tests/it/integration/tx.rs | 32 +++++++++++++++++-- .../commands/tx/edit/sequence_number/bump.rs | 11 +++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index f3f60d300b..da9357ace1 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -3,7 +3,7 @@ use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; use crate::integration::util::{ - deploy_contract, test_address, DeployKind, DeployOptions, HELLO_WORLD, + deploy_contract, DeployKind, DeployOptions, HELLO_WORLD, }; pub mod operations; @@ -77,9 +77,8 @@ fn test_tx_string(sandbox: &TestEnv) -> String { } #[test] -fn sequence_number_bump() { +fn sequence_number_bump_default() { let sandbox = &TestEnv::new(); - let test_address = test_address(sandbox); // address for the account with alias "test" let tx_base64 = test_tx_string(sandbox); let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); @@ -102,6 +101,33 @@ fn sequence_number_bump() { ); } +#[test] +fn sequence_number_bump_with_amount() { + let sandbox = &TestEnv::new(); + let tx_base64 = test_tx_string(sandbox); + let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); + let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); + let current_seq_num = tx.seq_num.as_ref(); + + let updated_tx = sandbox + .new_assert_cmd("tx") + .arg("edit") + .arg("sequence-number") + .arg("bump") + .arg("--amount") + .arg("2") + .write_stdin(tx_base64.as_bytes()) + .assert() + .success() + .stdout_as_str(); + let updated_tx_env = TransactionEnvelope::from_xdr_base64(&updated_tx, Limits::none()).unwrap(); + let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(updated_tx_env).unwrap(); + assert_eq!( + tx.seq_num, + soroban_cli::xdr::SequenceNumber(current_seq_num + 2) + ); +} + #[tokio::test] async fn txn_hash() { let sandbox = &TestEnv::new(); diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs index a4815a0c14..db63f0dec2 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs @@ -7,7 +7,11 @@ use crate::{ }; #[derive(clap::Parser, Debug, Clone)] -pub struct Cmd {} +pub struct Cmd { + /// Amount to increment the sequence-number + #[arg(long, default_value_t = 1)] + pub amount: i64, +} #[derive(thiserror::Error, Debug)] pub enum Error { @@ -22,18 +26,19 @@ pub enum Error { impl Cmd { pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { let mut tx = tx_envelope_from_input(&None)?; - Self::update_tx_env(&mut tx, global_args)?; + self.update_tx_env(&mut tx, global_args)?; println!("{}", tx.to_xdr_base64(xdr::Limits::none())?); Ok(()) } pub fn update_tx_env( + &self, tx_env: &mut TransactionEnvelope, _global: &global::Args, ) -> Result<(), Error> { match tx_env { TransactionEnvelope::Tx(transaction_v1_envelope) => { - let bump = transaction_v1_envelope.tx.seq_num.as_ref() + 1; + let bump = transaction_v1_envelope.tx.seq_num.as_ref() + self.amount; transaction_v1_envelope.tx.seq_num = SequenceNumber(bump); } TransactionEnvelope::TxV0(_) | TransactionEnvelope::TxFeeBump(_) => { From 9a9e6869d52f51a68bb7b3da4da7b32dea847bc2 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:29:35 -0400 Subject: [PATCH 09/17] Fmt --- cmd/crates/soroban-test/tests/it/integration/tx.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index da9357ace1..6845daa8e2 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -2,9 +2,7 @@ use soroban_cli::assembled::simulate_and_assemble_transaction; use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; -use crate::integration::util::{ - deploy_contract, DeployKind, DeployOptions, HELLO_WORLD, -}; +use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD}; pub mod operations; From 0c833a7409c4cf9471e23b983540f99c95440857 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:36:20 -0400 Subject: [PATCH 10/17] Bump -> increment --- cmd/crates/soroban-test/tests/it/integration/tx.rs | 11 +++++------ .../edit/sequence_number/{bump.rs => increment.rs} | 2 +- .../src/commands/tx/edit/sequence_number/mod.rs | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) rename cmd/soroban-cli/src/commands/tx/edit/sequence_number/{bump.rs => increment.rs} (97%) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 6845daa8e2..f5f5480183 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -75,7 +75,7 @@ fn test_tx_string(sandbox: &TestEnv) -> String { } #[test] -fn sequence_number_bump_default() { +fn sequence_number_increment_default() { let sandbox = &TestEnv::new(); let tx_base64 = test_tx_string(sandbox); let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); @@ -85,8 +85,8 @@ fn sequence_number_bump_default() { let updated_tx = sandbox .new_assert_cmd("tx") .arg("edit") - .arg("sequence-number") - .arg("bump") + .arg("seq-num") + .arg("inc") .write_stdin(tx_base64.as_bytes()) .assert() .success() @@ -100,7 +100,7 @@ fn sequence_number_bump_default() { } #[test] -fn sequence_number_bump_with_amount() { +fn sequence_number_increment_with_amount() { let sandbox = &TestEnv::new(); let tx_base64 = test_tx_string(sandbox); let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); @@ -111,8 +111,7 @@ fn sequence_number_bump_with_amount() { .new_assert_cmd("tx") .arg("edit") .arg("sequence-number") - .arg("bump") - .arg("--amount") + .arg("increment") .arg("2") .write_stdin(tx_base64.as_bytes()) .assert() diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs similarity index 97% rename from cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs rename to cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs index db63f0dec2..ba8f92cdba 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/bump.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs @@ -9,7 +9,7 @@ use crate::{ #[derive(clap::Parser, Debug, Clone)] pub struct Cmd { /// Amount to increment the sequence-number - #[arg(long, default_value_t = 1)] + #[arg(default_value_t = 1)] pub amount: i64, } diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs index 6db1ae3404..7e5f7894b1 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs @@ -1,24 +1,24 @@ use super::global; -mod bump; +mod increment; #[derive(Debug, clap::Subcommand)] pub enum Cmd { - /// Bump the transaction's sequence number - #[command()] - Bump(bump::Cmd), + /// Increase the transaction's sequence number + #[command(visible_alias = "inc")] + Increment(increment::Cmd), } #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] - Bump(#[from] bump::Error), + Increment(#[from] increment::Error), } impl Cmd { pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { - Cmd::Bump(cmd) => cmd.run(global_args)?, + Cmd::Increment(cmd) => cmd.run(global_args)?, }; Ok(()) } From bd985f23e3e0c25d190ce2dcaafddf099137574a Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:37:49 -0400 Subject: [PATCH 11/17] Generated docs --- FULL_HELP_DOCS.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index caeca7ef44..cc3f522917 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -1545,15 +1545,21 @@ Set the sequence number on a transaction ###### **Subcommands:** -* `bump` — Bump the transaction's sequence number +* `increment` — Increase the transaction's sequence number -## `stellar tx edit sequence-number bump` +## `stellar tx edit sequence-number increment` -Bump the transaction's sequence number +Increase the transaction's sequence number -**Usage:** `stellar tx edit sequence-number bump` +**Usage:** `stellar tx edit sequence-number increment [AMOUNT]` + +###### **Arguments:** + +* `` — Amount to increment the sequence-number + + Default value: `1` From 5ea223ef057e2b3db84c6f70ce160caa0d4548fa Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:25:18 -0400 Subject: [PATCH 12/17] Implement tx edit seq-num next --- .../soroban-test/tests/it/integration/tx.rs | 43 +++-------- cmd/soroban-cli/src/commands/tx/edit/mod.rs | 6 +- .../tx/edit/sequence_number/increment.rs | 50 ------------- .../commands/tx/edit/sequence_number/mod.rs | 15 ++-- .../commands/tx/edit/sequence_number/next.rs | 73 +++++++++++++++++++ cmd/soroban-cli/src/commands/tx/mod.rs | 2 +- 6 files changed, 97 insertions(+), 92 deletions(-) delete mode 100644 cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs create mode 100644 cmd/soroban-cli/src/commands/tx/edit/sequence_number/next.rs diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index f5f5480183..7302b7ef59 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -2,7 +2,7 @@ use soroban_cli::assembled::simulate_and_assemble_transaction; use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; -use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD}; +use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD, test_address}; pub mod operations; @@ -74,54 +74,35 @@ fn test_tx_string(sandbox: &TestEnv) -> String { .stdout_as_str() } -#[test] -fn sequence_number_increment_default() { +#[tokio::test] +async fn sequence_number_next() { let sandbox = &TestEnv::new(); let tx_base64 = test_tx_string(sandbox); let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); - let current_seq_num = tx.seq_num.as_ref(); + + let test = test_address(sandbox); + let client = sandbox.network.rpc_client().unwrap(); + let test_account = client.get_account(&test).await.unwrap(); + let test_account_seq_num = test_account.seq_num.as_ref(); let updated_tx = sandbox .new_assert_cmd("tx") .arg("edit") .arg("seq-num") - .arg("inc") + .arg("next") + .arg("--source") + .arg("test") // there is an account created in TestEnv with an alias "test" .write_stdin(tx_base64.as_bytes()) .assert() .success() .stdout_as_str(); - let updated_tx_env = TransactionEnvelope::from_xdr_base64(&updated_tx, Limits::none()).unwrap(); - let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(updated_tx_env).unwrap(); - assert_eq!( - tx.seq_num, - soroban_cli::xdr::SequenceNumber(current_seq_num + 1) - ); -} - -#[test] -fn sequence_number_increment_with_amount() { - let sandbox = &TestEnv::new(); - let tx_base64 = test_tx_string(sandbox); - let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); - let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); - let current_seq_num = tx.seq_num.as_ref(); - let updated_tx = sandbox - .new_assert_cmd("tx") - .arg("edit") - .arg("sequence-number") - .arg("increment") - .arg("2") - .write_stdin(tx_base64.as_bytes()) - .assert() - .success() - .stdout_as_str(); let updated_tx_env = TransactionEnvelope::from_xdr_base64(&updated_tx, Limits::none()).unwrap(); let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(updated_tx_env).unwrap(); assert_eq!( tx.seq_num, - soroban_cli::xdr::SequenceNumber(current_seq_num + 2) + soroban_cli::xdr::SequenceNumber(test_account_seq_num + 1) ); } diff --git a/cmd/soroban-cli/src/commands/tx/edit/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/mod.rs index 824a283c9e..65948969da 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/mod.rs @@ -4,7 +4,7 @@ pub mod sequence_number; #[derive(Debug, clap::Subcommand)] pub enum Cmd { - /// Set the sequence number on a transaction + /// Edit the sequence number on a transaction #[command(subcommand, visible_alias = "seq-num")] SequenceNumber(sequence_number::Cmd), } @@ -16,9 +16,9 @@ pub enum Error { } impl Cmd { - pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { + pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { - Cmd::SequenceNumber(cmd) => cmd.run(global_args)?, + Cmd::SequenceNumber(cmd) => cmd.run(global_args).await?, }; Ok(()) } diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs deleted file mode 100644 index ba8f92cdba..0000000000 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/increment.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::{ - commands::{ - global, - tx::xdr::{tx_envelope_from_input, Error as XdrParsingError}, - }, - xdr::{self, SequenceNumber, TransactionEnvelope, WriteXdr}, -}; - -#[derive(clap::Parser, Debug, Clone)] -pub struct Cmd { - /// Amount to increment the sequence-number - #[arg(default_value_t = 1)] - pub amount: i64, -} - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error(transparent)] - XdrStdin(#[from] XdrParsingError), - #[error(transparent)] - Xdr(#[from] xdr::Error), - #[error("only V1 transactions are supported")] - Unsupported, -} - -impl Cmd { - pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { - let mut tx = tx_envelope_from_input(&None)?; - self.update_tx_env(&mut tx, global_args)?; - println!("{}", tx.to_xdr_base64(xdr::Limits::none())?); - Ok(()) - } - - pub fn update_tx_env( - &self, - tx_env: &mut TransactionEnvelope, - _global: &global::Args, - ) -> Result<(), Error> { - match tx_env { - TransactionEnvelope::Tx(transaction_v1_envelope) => { - let bump = transaction_v1_envelope.tx.seq_num.as_ref() + self.amount; - transaction_v1_envelope.tx.seq_num = SequenceNumber(bump); - } - TransactionEnvelope::TxV0(_) | TransactionEnvelope::TxFeeBump(_) => { - return Err(Error::Unsupported); - } - }; - Ok(()) - } -} diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs index 7e5f7894b1..f5b371f4f6 100644 --- a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs @@ -1,24 +1,25 @@ use super::global; -mod increment; +mod next; #[derive(Debug, clap::Subcommand)] pub enum Cmd { - /// Increase the transaction's sequence number - #[command(visible_alias = "inc")] - Increment(increment::Cmd), + + /// Fetch the source account's seq-num and increment for the given tx + #[command()] + Next(next::Cmd), } #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] - Increment(#[from] increment::Error), + Next(#[from] next::Error), } impl Cmd { - pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { + pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { - Cmd::Increment(cmd) => cmd.run(global_args)?, + Cmd::Next(cmd) => cmd.run(global_args).await?, }; Ok(()) } diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/next.rs b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/next.rs new file mode 100644 index 0000000000..8fd39dc1da --- /dev/null +++ b/cmd/soroban-cli/src/commands/tx/edit/sequence_number/next.rs @@ -0,0 +1,73 @@ +use crate::{ + commands::{ + global, + tx::xdr::{tx_envelope_from_input, Error as XdrParsingError}, + }, config, xdr::{self, SequenceNumber, TransactionEnvelope, WriteXdr} +}; + +#[derive(clap::Parser, Debug, Clone)] +pub struct Cmd { + #[command(flatten)] + pub config: config::Args, +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + XdrStdin(#[from] XdrParsingError), + #[error(transparent)] + Xdr(#[from] xdr::Error), + #[error("only V1 transactions are supported")] + Unsupported, + #[error(transparent)] + RpcClient(#[from] crate::rpc::Error), + #[error(transparent)] + Config(#[from] config::Error), + #[error(transparent)] + Network(#[from] config::network::Error), +} + +impl Cmd { + pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { + let mut tx = tx_envelope_from_input(&None)?; + self.update_tx_env(&mut tx, global_args).await?; + println!("{}", tx.to_xdr_base64(xdr::Limits::none())?); + Ok(()) + } + + pub async fn update_tx_env( + &self, + tx_env: &mut TransactionEnvelope, + _global: &global::Args, + ) -> Result<(), Error> { + match tx_env { + TransactionEnvelope::Tx(transaction_v1_envelope) => { + let current_seq_num = self.current_seq_num().await?; + let next_seq_num = current_seq_num + 1; + transaction_v1_envelope.tx.seq_num = SequenceNumber(next_seq_num); + } + TransactionEnvelope::TxV0(_) | TransactionEnvelope::TxFeeBump(_) => { + return Err(Error::Unsupported); + } + }; + Ok(()) + } + + async fn current_seq_num(&self) -> Result{ + let network = &self.config.get_network()?; + let client = network.rpc_client()?; + client.verify_network_passphrase(Some(&network.network_passphrase)) + .await?; + + let muxed_account = self.config.source_account().await?; + + let bytes = match muxed_account { + soroban_sdk::xdr::MuxedAccount::Ed25519(uint256) => uint256.0, + soroban_sdk::xdr::MuxedAccount::MuxedEd25519(muxed_account) => muxed_account.ed25519.0, + }; + let address = stellar_strkey::ed25519::PublicKey(bytes).to_string(); + + let account = client.get_account(&address).await?; + Ok(account.seq_num.as_ref().clone()) + } +} diff --git a/cmd/soroban-cli/src/commands/tx/mod.rs b/cmd/soroban-cli/src/commands/tx/mod.rs index 40c874588d..9b53b8805f 100644 --- a/cmd/soroban-cli/src/commands/tx/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/mod.rs @@ -57,7 +57,7 @@ pub enum Error { impl Cmd { pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { - Cmd::Edit(cmd) => cmd.run(global_args)?, + Cmd::Edit(cmd) => cmd.run(global_args).await?, Cmd::Hash(cmd) => cmd.run(global_args)?, Cmd::New(cmd) => cmd.run(global_args).await?, Cmd::Operation(cmd) => cmd.run(global_args).await?, From c6caa650b4c0d1199fc6d90452eb097571bd8fc2 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 17 Mar 2025 16:54:50 -0400 Subject: [PATCH 13/17] Move seq-num next to update subcommand --- cmd/crates/soroban-test/tests/it/integration/tx.rs | 5 +---- cmd/soroban-cli/src/commands/tx/mod.rs | 10 +++++----- .../src/commands/tx/{edit => update}/mod.rs | 0 .../tx/{edit => update}/sequence_number/mod.rs | 0 .../tx/{edit => update}/sequence_number/next.rs | 0 5 files changed, 6 insertions(+), 9 deletions(-) rename cmd/soroban-cli/src/commands/tx/{edit => update}/mod.rs (100%) rename cmd/soroban-cli/src/commands/tx/{edit => update}/sequence_number/mod.rs (100%) rename cmd/soroban-cli/src/commands/tx/{edit => update}/sequence_number/next.rs (100%) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 7302b7ef59..14cf30f273 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -78,9 +78,6 @@ fn test_tx_string(sandbox: &TestEnv) -> String { async fn sequence_number_next() { let sandbox = &TestEnv::new(); let tx_base64 = test_tx_string(sandbox); - let tx_env = TransactionEnvelope::from_xdr_base64(&tx_base64, Limits::none()).unwrap(); - let tx = soroban_cli::commands::tx::xdr::unwrap_envelope_v1(tx_env).unwrap(); - let test = test_address(sandbox); let client = sandbox.network.rpc_client().unwrap(); let test_account = client.get_account(&test).await.unwrap(); @@ -88,7 +85,7 @@ async fn sequence_number_next() { let updated_tx = sandbox .new_assert_cmd("tx") - .arg("edit") + .arg("update") .arg("seq-num") .arg("next") .arg("--source") diff --git a/cmd/soroban-cli/src/commands/tx/mod.rs b/cmd/soroban-cli/src/commands/tx/mod.rs index 9b53b8805f..13504af470 100644 --- a/cmd/soroban-cli/src/commands/tx/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/mod.rs @@ -1,7 +1,7 @@ use super::global; pub mod args; -pub mod edit; +pub mod update; pub mod hash; pub mod help; pub mod new; @@ -15,9 +15,9 @@ pub use args::Args; #[derive(Debug, clap::Subcommand)] pub enum Cmd { - /// Edit the transaction + /// Update the transaction #[command(subcommand)] - Edit(edit::Cmd), + Update(update::Cmd), /// Calculate the hash of a transaction envelope Hash(hash::Cmd), /// Create a new transaction @@ -37,7 +37,7 @@ pub enum Cmd { #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] - Edit(#[from] edit::Error), + Update(#[from] update::Error), #[error(transparent)] Hash(#[from] hash::Error), #[error(transparent)] @@ -57,7 +57,7 @@ pub enum Error { impl Cmd { pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { - Cmd::Edit(cmd) => cmd.run(global_args).await?, + Cmd::Update(cmd) => cmd.run(global_args).await?, Cmd::Hash(cmd) => cmd.run(global_args)?, Cmd::New(cmd) => cmd.run(global_args).await?, Cmd::Operation(cmd) => cmd.run(global_args).await?, diff --git a/cmd/soroban-cli/src/commands/tx/edit/mod.rs b/cmd/soroban-cli/src/commands/tx/update/mod.rs similarity index 100% rename from cmd/soroban-cli/src/commands/tx/edit/mod.rs rename to cmd/soroban-cli/src/commands/tx/update/mod.rs diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs b/cmd/soroban-cli/src/commands/tx/update/sequence_number/mod.rs similarity index 100% rename from cmd/soroban-cli/src/commands/tx/edit/sequence_number/mod.rs rename to cmd/soroban-cli/src/commands/tx/update/sequence_number/mod.rs diff --git a/cmd/soroban-cli/src/commands/tx/edit/sequence_number/next.rs b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs similarity index 100% rename from cmd/soroban-cli/src/commands/tx/edit/sequence_number/next.rs rename to cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs From e99245c43af7af3b05d4cfadc3097402ef721e7a Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 17 Mar 2025 16:57:54 -0400 Subject: [PATCH 14/17] Update generated docs --- FULL_HELP_DOCS.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 15bce36f3b..bc24ed3558 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -1537,6 +1537,7 @@ Sign, Simulate, and Send transactions ###### **Subcommands:** +* `update` — Update the transaction * `edit` — Edit a transaction envelope from stdin. This command respects the environment variables `STELLAR_EDITOR`, `EDITOR` and `VISUAL`, in that order * `hash` — Calculate the hash of a transaction envelope * `new` — Create a new transaction @@ -1547,6 +1548,49 @@ Sign, Simulate, and Send transactions +## `stellar tx update` + +Update the transaction + +**Usage:** `stellar tx update ` + +###### **Subcommands:** + +* `sequence-number` — Edit the sequence number on a transaction + + + +## `stellar tx update sequence-number` + +Edit the sequence number on a transaction + +**Usage:** `stellar tx update sequence-number ` + +###### **Subcommands:** + +* `next` — Fetch the source account's seq-num and increment for the given tx + + + +## `stellar tx update sequence-number next` + +Fetch the source account's seq-num and increment for the given tx + +**Usage:** `stellar tx update sequence-number next [OPTIONS] --source-account ` + +###### **Options:** + +* `--rpc-url ` — RPC server endpoint +* `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider +* `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server +* `-n`, `--network ` — Name of network to use from config +* `-s`, `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail +* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` +* `--global` — Use global config +* `--config-dir ` — Location of config directory, default is "." + + + ## `stellar tx edit` Edit a transaction envelope from stdin. This command respects the environment variables `STELLAR_EDITOR`, `EDITOR` and `VISUAL`, in that order From 3a6473c6026826c85f6f2b966bb22966159c676b Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Mon, 17 Mar 2025 16:59:46 -0400 Subject: [PATCH 15/17] Cleanup --- .../soroban-test/tests/it/integration/tx.rs | 4 +++- cmd/soroban-cli/src/commands/tx/mod.rs | 8 ++++---- .../src/commands/tx/update/sequence_number/mod.rs | 1 - .../commands/tx/update/sequence_number/next.rs | 15 +++++++++------ 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 14cf30f273..4743d6d605 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -2,7 +2,9 @@ use soroban_cli::assembled::simulate_and_assemble_transaction; use soroban_cli::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr}; use soroban_test::{AssertExt, TestEnv}; -use crate::integration::util::{deploy_contract, DeployKind, DeployOptions, HELLO_WORLD, test_address}; +use crate::integration::util::{ + deploy_contract, test_address, DeployKind, DeployOptions, HELLO_WORLD, +}; pub mod operations; diff --git a/cmd/soroban-cli/src/commands/tx/mod.rs b/cmd/soroban-cli/src/commands/tx/mod.rs index b3685d8a4d..ff74c3fa57 100644 --- a/cmd/soroban-cli/src/commands/tx/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/mod.rs @@ -1,7 +1,6 @@ use super::global; pub mod args; -pub mod update; pub mod edit; pub mod hash; pub mod help; @@ -10,6 +9,7 @@ pub mod op; pub mod send; pub mod sign; pub mod simulate; +pub mod update; pub mod xdr; pub use args::Args; @@ -40,8 +40,6 @@ pub enum Cmd { #[derive(thiserror::Error, Debug)] pub enum Error { - #[error(transparent)] - Update(#[from] update::Error), #[error(transparent)] Hash(#[from] hash::Error), #[error(transparent)] @@ -58,12 +56,13 @@ pub enum Error { Args(#[from] args::Error), #[error(transparent)] Simulate(#[from] simulate::Error), + #[error(transparent)] + Update(#[from] update::Error), } impl Cmd { pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> { match self { - Cmd::Update(cmd) => cmd.run(global_args).await?, Cmd::Hash(cmd) => cmd.run(global_args)?, Cmd::New(cmd) => cmd.run(global_args).await?, Cmd::Edit(cmd) => cmd.run(global_args)?, @@ -71,6 +70,7 @@ impl Cmd { Cmd::Send(cmd) => cmd.run(global_args).await?, Cmd::Sign(cmd) => cmd.run(global_args).await?, Cmd::Simulate(cmd) => cmd.run(global_args).await?, + Cmd::Update(cmd) => cmd.run(global_args).await?, }; Ok(()) } diff --git a/cmd/soroban-cli/src/commands/tx/update/sequence_number/mod.rs b/cmd/soroban-cli/src/commands/tx/update/sequence_number/mod.rs index f5b371f4f6..fee0395e76 100644 --- a/cmd/soroban-cli/src/commands/tx/update/sequence_number/mod.rs +++ b/cmd/soroban-cli/src/commands/tx/update/sequence_number/mod.rs @@ -4,7 +4,6 @@ mod next; #[derive(Debug, clap::Subcommand)] pub enum Cmd { - /// Fetch the source account's seq-num and increment for the given tx #[command()] Next(next::Cmd), diff --git a/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs index 8fd39dc1da..c9892246a0 100644 --- a/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs +++ b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs @@ -2,7 +2,9 @@ use crate::{ commands::{ global, tx::xdr::{tx_envelope_from_input, Error as XdrParsingError}, - }, config, xdr::{self, SequenceNumber, TransactionEnvelope, WriteXdr} + }, + config, + xdr::{self, SequenceNumber, TransactionEnvelope, WriteXdr}, }; #[derive(clap::Parser, Debug, Clone)] @@ -53,11 +55,12 @@ impl Cmd { Ok(()) } - async fn current_seq_num(&self) -> Result{ + async fn current_seq_num(&self) -> Result { let network = &self.config.get_network()?; let client = network.rpc_client()?; - client.verify_network_passphrase(Some(&network.network_passphrase)) - .await?; + client + .verify_network_passphrase(Some(&network.network_passphrase)) + .await?; let muxed_account = self.config.source_account().await?; @@ -66,8 +69,8 @@ impl Cmd { soroban_sdk::xdr::MuxedAccount::MuxedEd25519(muxed_account) => muxed_account.ed25519.0, }; let address = stellar_strkey::ed25519::PublicKey(bytes).to_string(); - + let account = client.get_account(&address).await?; - Ok(account.seq_num.as_ref().clone()) + Ok(*account.seq_num.as_ref()) } } From 2dd1a08aee095fed597fb69a6989990b6b6228d4 Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Tue, 8 Apr 2025 10:40:44 -0400 Subject: [PATCH 16/17] Address pr feedback: use tx source acct for seq num --- .../soroban-test/tests/it/integration/tx.rs | 2 -- .../tx/update/sequence_number/next.rs | 23 +++++++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx.rs b/cmd/crates/soroban-test/tests/it/integration/tx.rs index 4743d6d605..6fc618e58f 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx.rs @@ -90,8 +90,6 @@ async fn sequence_number_next() { .arg("update") .arg("seq-num") .arg("next") - .arg("--source") - .arg("test") // there is an account created in TestEnv with an alias "test" .write_stdin(tx_base64.as_bytes()) .assert() .success() diff --git a/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs index c9892246a0..1f26ac9c67 100644 --- a/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs +++ b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs @@ -1,16 +1,20 @@ +use stellar_xdr::curr::MuxedAccount; + use crate::{ commands::{ global, tx::xdr::{tx_envelope_from_input, Error as XdrParsingError}, }, - config, + config::{self, locator, network}, xdr::{self, SequenceNumber, TransactionEnvelope, WriteXdr}, }; #[derive(clap::Parser, Debug, Clone)] pub struct Cmd { #[command(flatten)] - pub config: config::Args, + pub network: network::Args, + #[command(flatten)] + pub locator: locator::Args, } #[derive(thiserror::Error, Debug)] @@ -44,7 +48,8 @@ impl Cmd { ) -> Result<(), Error> { match tx_env { TransactionEnvelope::Tx(transaction_v1_envelope) => { - let current_seq_num = self.current_seq_num().await?; + let tx_source_acct = &transaction_v1_envelope.tx.source_account; + let current_seq_num = self.current_seq_num(tx_source_acct).await?; let next_seq_num = current_seq_num + 1; transaction_v1_envelope.tx.seq_num = SequenceNumber(next_seq_num); } @@ -55,20 +60,14 @@ impl Cmd { Ok(()) } - async fn current_seq_num(&self) -> Result { - let network = &self.config.get_network()?; + async fn current_seq_num(&self, tx_source_acct: &MuxedAccount) -> Result { + let network = &self.network.get(&self.locator)?; let client = network.rpc_client()?; client .verify_network_passphrase(Some(&network.network_passphrase)) .await?; - let muxed_account = self.config.source_account().await?; - - let bytes = match muxed_account { - soroban_sdk::xdr::MuxedAccount::Ed25519(uint256) => uint256.0, - soroban_sdk::xdr::MuxedAccount::MuxedEd25519(muxed_account) => muxed_account.ed25519.0, - }; - let address = stellar_strkey::ed25519::PublicKey(bytes).to_string(); + let address = tx_source_acct.to_string(); let account = client.get_account(&address).await?; Ok(*account.seq_num.as_ref()) From 3b728ae72dec872d00dee90039afab957c3774ab Mon Sep 17 00:00:00 2001 From: elizabethengelman <4752801+elizabethengelman@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:02:32 -0400 Subject: [PATCH 17/17] Address feedback: update xdr error --- FULL_HELP_DOCS.md | 4 +--- .../src/commands/tx/update/sequence_number/next.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index a36a02ea60..28d9f5dde7 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -1614,7 +1614,7 @@ Edit the sequence number on a transaction Fetch the source account's seq-num and increment for the given tx -**Usage:** `stellar tx update sequence-number next [OPTIONS] --source-account ` +**Usage:** `stellar tx update sequence-number next [OPTIONS]` ###### **Options:** @@ -1622,8 +1622,6 @@ Fetch the source account's seq-num and increment for the given tx * `--rpc-header ` — RPC Header(s) to include in requests to the RPC provider * `--network-passphrase ` — Network passphrase to sign the transaction sent to the rpc server * `-n`, `--network ` — Name of network to use from config -* `-s`, `--source-account ` — Account that where transaction originates from. Alias `source`. Can be an identity (--source alice), a public key (--source GDKW...), a muxed account (--source MDA…), a secret key (--source SC36…), or a seed phrase (--source "kite urban…"). If `--build-only` or `--sim-only` flags were NOT provided, this key will also be used to sign the final transaction. In that case, trying to sign with public key will fail -* `--hd-path ` — If using a seed phrase, which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0` * `--global` — Use global config * `--config-dir ` — Location of config directory, default is "." diff --git a/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs index 1f26ac9c67..b552037994 100644 --- a/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs +++ b/cmd/soroban-cli/src/commands/tx/update/sequence_number/next.rs @@ -23,7 +23,7 @@ pub enum Error { XdrStdin(#[from] XdrParsingError), #[error(transparent)] Xdr(#[from] xdr::Error), - #[error("only V1 transactions are supported")] + #[error("V0 and fee bump transactions are not supported")] Unsupported, #[error(transparent)] RpcClient(#[from] crate::rpc::Error),