From 1b264595e32a7e4341acd15fb3aba3f5a68121c1 Mon Sep 17 00:00:00 2001 From: Quentin Le Sceller Date: Mon, 12 Nov 2018 19:18:54 +0100 Subject: [PATCH 1/4] Add retrieve by tx_id in owner_api --- doc/api/wallet_owner_api.md | 10 ++++++---- src/bin/cmd/wallet.rs | 2 +- wallet/src/libwallet/api.rs | 4 +++- wallet/src/libwallet/controller.rs | 12 +++++++++--- wallet/src/libwallet/internal/tx.rs | 4 ++-- wallet/src/libwallet/internal/updater.rs | 9 +++++++++ wallet/tests/accounts.rs | 14 +++++++------- wallet/tests/restore.rs | 4 ++-- wallet/tests/transaction.rs | 20 ++++++++++---------- 9 files changed, 49 insertions(+), 30 deletions(-) diff --git a/doc/api/wallet_owner_api.md b/doc/api/wallet_owner_api.md index 85dd7abef..fd0653767 100644 --- a/doc/api/wallet_owner_api.md +++ b/doc/api/wallet_owner_api.md @@ -189,8 +189,9 @@ Return whether the outputs were validated against a node and an array of TxLogEn * **URL** - */v1/wallet/owner/retrieve_txs - */v1/wallet/owner/retrieve_txs?refresh?id=x + * /v1/wallet/owner/retrieve_txs + * /v1/wallet/owner/retrieve_txs?refresh&id=x + * /v1/wallet/owner/retrieve_txs?tx_id=x * **Method:** @@ -200,8 +201,9 @@ Return whether the outputs were validated against a node and an array of TxLogEn **Optional:** - `refresh` to refresh from node - `tx_id=[number]` to retrieve only the specified output + * `refresh` to refresh from node + * `id=[number]` to retrieve only the specified output by id + * `tx_id=[string]` to retrieve only the specified output by tx id * **Data Params** diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs index 8d5b026e4..553b3bb3b 100644 --- a/src/bin/cmd/wallet.rs +++ b/src/bin/cmd/wallet.rs @@ -524,7 +524,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i }, }; let (height, _) = api.node_height()?; - let (validated, txs) = api.retrieve_txs(true, tx_id)?; + let (validated, txs) = api.retrieve_txs(true, tx_id, None)?; let include_status = !tx_id.is_some(); display::txs( account, diff --git a/wallet/src/libwallet/api.rs b/wallet/src/libwallet/api.rs index 19e95acc0..920559fb5 100644 --- a/wallet/src/libwallet/api.rs +++ b/wallet/src/libwallet/api.rs @@ -22,6 +22,7 @@ use std::io::{Read, Write}; use std::marker::PhantomData; use std::sync::Arc; use util::Mutex; +use uuid::Uuid; use serde_json as json; @@ -102,6 +103,7 @@ where &self, refresh_from_node: bool, tx_id: Option, + tx_slate_id: Option, ) -> Result<(bool, Vec), Error> { let mut w = self.wallet.lock(); w.open_with_credentials()?; @@ -114,7 +116,7 @@ where let res = Ok(( validated, - updater::retrieve_txs(&mut *w, tx_id, &parent_key_id)?, + updater::retrieve_txs(&mut *w, tx_id, tx_slate_id, &parent_key_id)?, )); w.close()?; diff --git a/wallet/src/libwallet/controller.rs b/wallet/src/libwallet/controller.rs index dc9b87504..d35f25f50 100644 --- a/wallet/src/libwallet/controller.rs +++ b/wallet/src/libwallet/controller.rs @@ -198,7 +198,8 @@ where req: &Request, api: APIOwner, ) -> Result<(bool, Vec), Error> { - let mut id = None; + let mut tx_id = None; + let mut tx_slate_id = None; let mut update_from_node = false; let params = parse_params(req); @@ -208,10 +209,15 @@ where } if let Some(ids) = params.get("id") { for i in ids { - id = Some(i.parse().unwrap()); + tx_id = Some(i.parse().unwrap()); } } - api.retrieve_txs(update_from_node, id) + if let Some(tx_slate_ids) = params.get("tx_id") { + for i in tx_slate_ids { + tx_slate_id = Some(i.parse().unwrap()); + } + } + api.retrieve_txs(update_from_node, tx_id, tx_slate_id) } fn dump_stored_tx( diff --git a/wallet/src/libwallet/internal/tx.rs b/wallet/src/libwallet/internal/tx.rs index 23e419a45..3aa5a3fec 100644 --- a/wallet/src/libwallet/internal/tx.rs +++ b/wallet/src/libwallet/internal/tx.rs @@ -160,7 +160,7 @@ where C: WalletClient, K: Keychain, { - let tx_vec = updater::retrieve_txs(wallet, Some(tx_id), &parent_key_id)?; + let tx_vec = updater::retrieve_txs(wallet, Some(tx_id), None, &parent_key_id)?; if tx_vec.len() != 1 { return Err(ErrorKind::TransactionDoesntExist(tx_id))?; } @@ -190,7 +190,7 @@ where C: WalletClient, K: Keychain, { - let tx_vec = updater::retrieve_txs(wallet, Some(tx_id), parent_key_id)?; + let tx_vec = updater::retrieve_txs(wallet, Some(tx_id), None, parent_key_id)?; if tx_vec.len() != 1 { return Err(ErrorKind::TransactionDoesntExist(tx_id))?; } diff --git a/wallet/src/libwallet/internal/updater.rs b/wallet/src/libwallet/internal/updater.rs index 3e2baa52e..188106250 100644 --- a/wallet/src/libwallet/internal/updater.rs +++ b/wallet/src/libwallet/internal/updater.rs @@ -17,6 +17,7 @@ use failure::ResultExt; use std::collections::HashMap; +use uuid::Uuid; use core::consensus::reward; use core::core::{Output, TxKernel}; @@ -80,6 +81,7 @@ where pub fn retrieve_txs( wallet: &mut T, tx_id: Option, + tx_slate_id: Option, parent_key_id: &Identifier, ) -> Result, Error> where @@ -95,6 +97,13 @@ where } else { vec![] } + } else if tx_slate_id.is_some() { + let tx = wallet.tx_log_iter().find(|t| t.tx_slate_id == tx_slate_id); + if let Some(t) = tx { + vec![t] + } else { + vec![] + } } else { wallet .tx_log_iter() diff --git a/wallet/tests/accounts.rs b/wallet/tests/accounts.rs index e6eb47197..4c1d8cdcc 100644 --- a/wallet/tests/accounts.rs +++ b/wallet/tests/accounts.rs @@ -134,7 +134,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.total, 5 * reward); assert_eq!(wallet1_info.amount_currently_spendable, (5 - cm) * reward); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; assert_eq!(txs.len(), 5); Ok(()) })?; @@ -153,7 +153,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.total, 7 * reward); assert_eq!(wallet1_info.amount_currently_spendable, 7 * reward); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; assert_eq!(txs.len(), 7); Ok(()) })?; @@ -172,7 +172,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.total, 0,); assert_eq!(wallet1_info.amount_currently_spendable, 0,); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; assert_eq!(txs.len(), 0); Ok(()) })?; @@ -200,7 +200,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, 13); - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; assert_eq!(txs.len(), 9); Ok(()) })?; @@ -215,7 +215,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.last_confirmed_height, 12); let (_, wallet1_info) = api.retrieve_summary_info(true)?; assert_eq!(wallet1_info.last_confirmed_height, 13); - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; println!("{:?}", txs); assert_eq!(txs.len(), 5); Ok(()) @@ -226,7 +226,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.last_confirmed_height, 13); - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; assert_eq!(txs.len(), 1); Ok(()) })?; @@ -244,7 +244,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet2_info.total, 0,); assert_eq!(wallet2_info.amount_currently_spendable, 0,); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; assert_eq!(txs.len(), 0); Ok(()) })?; diff --git a/wallet/tests/restore.rs b/wallet/tests/restore.rs index eb786bae4..618429735 100644 --- a/wallet/tests/restore.rs +++ b/wallet/tests/restore.rs @@ -136,14 +136,14 @@ fn compare_wallet_restore( // Overall wallet info should be the same wallet::controller::owner_single_use(wallet_source.clone(), |api| { src_info = Some(api.retrieve_summary_info(true)?.1); - src_txs = Some(api.retrieve_txs(true, None)?.1); + src_txs = Some(api.retrieve_txs(true, None, None)?.1); src_accts = Some(api.accounts()?); Ok(()) })?; wallet::controller::owner_single_use(wallet_dest.clone(), |api| { dest_info = Some(api.retrieve_summary_info(true)?.1); - dest_txs = Some(api.retrieve_txs(true, None)?.1); + dest_txs = Some(api.retrieve_txs(true, None, None)?.1); dest_accts = Some(api.accounts()?); Ok(()) })?; diff --git a/wallet/tests/transaction.rs b/wallet/tests/transaction.rs index 4a70f3b0c..2e1b372c7 100644 --- a/wallet/tests/transaction.rs +++ b/wallet/tests/transaction.rs @@ -118,7 +118,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { // Check transaction log for wallet 1 wallet::controller::owner_single_use(wallet1.clone(), |api| { let (_, wallet1_info) = api.retrieve_summary_info(true)?; - let (refreshed, txs) = api.retrieve_txs(true, None)?; + let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); let fee = wallet::libtx::tx_fee( wallet1_info.last_confirmed_height as usize - cm as usize, @@ -139,7 +139,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { // Check transaction log for wallet 2 wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (refreshed, txs) = api.retrieve_txs(true, None)?; + let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); // we should have a transaction entry for this slate let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); @@ -185,7 +185,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.amount_immature, cm * reward + fee); // check tx log entry is confirmed - let (refreshed, txs) = api.retrieve_txs(true, None)?; + let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -221,7 +221,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet2_info.amount_currently_spendable, amount); // check tx log entry is confirmed - let (refreshed, txs) = api.retrieve_txs(true, None)?; + let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -249,7 +249,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { let (refreshed, _wallet1_info) = sender_api.retrieve_summary_info(true)?; assert!(refreshed); - let (_, txs) = sender_api.retrieve_txs(true, None)?; + let (_, txs) = sender_api.retrieve_txs(true, None, None)?; // find the transaction let tx = txs @@ -276,7 +276,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet2_info.amount_currently_spendable, amount * 3); // check tx log entry is confirmed - let (refreshed, txs) = api.retrieve_txs(true, None)?; + let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -346,7 +346,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { wallet1_info.last_confirmed_height ); assert!(refreshed); - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; // we should have a transaction entry for this slate let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -371,7 +371,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { // Check transaction log for wallet 2 wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (refreshed, txs) = api.retrieve_txs(true, None)?; + let (refreshed, txs) = api.retrieve_txs(true, None, None)?; assert!(refreshed); let mut unconfirmed_count = 0; let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); @@ -400,7 +400,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { // can't roll back coinbase let res = api.cancel_tx(1); assert!(res.is_err()); - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; let tx = txs .iter() .find(|t| t.tx_slate_id == Some(slate.id)) @@ -427,7 +427,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { // Wallet 2 rolls back wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (_, txs) = api.retrieve_txs(true, None)?; + let (_, txs) = api.retrieve_txs(true, None, None)?; let tx = txs .iter() .find(|t| t.tx_slate_id == Some(slate.id)) From 59b0f1b1d700bf0ff91946b7438f4ad5b337e55b Mon Sep 17 00:00:00 2001 From: Quentin Le Sceller Date: Tue, 13 Nov 2018 11:53:23 +0100 Subject: [PATCH 2/4] Add cancel tx by tx_slate_id --- src/bin/cmd/wallet.rs | 53 ++++++++++++++++++++++------- src/bin/grin.rs | 5 +++ wallet/src/libwallet/api.rs | 8 +++-- wallet/src/libwallet/controller.rs | 20 +++++++++-- wallet/src/libwallet/error.rs | 4 +-- wallet/src/libwallet/internal/tx.rs | 22 ++++++++---- 6 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs index 553b3bb3b..f7bedad2e 100644 --- a/src/bin/cmd/wallet.rs +++ b/src/bin/cmd/wallet.rs @@ -603,22 +603,49 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i } } ("cancel", Some(tx_args)) => { - let tx_id = tx_args - .value_of("id") - .ok_or_else(|| { - ErrorKind::GenericError("'id' argument (-i) is required.".to_string()) - }).and_then(|v| { - v.parse().map_err(|e| { - ErrorKind::GenericError(format!( + let mut tx_id_string = ""; + let tx_id = match tx_args.value_of("id") { + None => None, + Some(tx) => match tx.parse() { + Ok(t) => { + tx_id_string = tx; + Some(t) + } + Err(e) => { + return Err(ErrorKind::GenericError(format!( "Could not parse id parameter. e={:?}", - e - )) - }) - })?; - let result = api.cancel_tx(tx_id); + e, + )).into()); + } + }, + }; + let tx_slate_id = match tx_args.value_of("txid") { + None => None, + Some(tx) => match tx.parse() { + Ok(t) => { + tx_id_string = tx; + Some(t) + } + Err(e) => { + return Err(ErrorKind::GenericError(format!( + "Could not parse txid parameter. e={:?}", + e, + )).into()); + } + }, + }; + if (tx_id.is_none() && tx_slate_id.is_none()) + || (tx_id.is_some() && tx_slate_id.is_some()) + { + return Err(ErrorKind::GenericError(format!( + "'id' (-i) or 'txid' (-t) argument is required." + )).into()); + } + + let result = api.cancel_tx(tx_id, tx_slate_id); match result { Ok(_) => { - info!("Transaction {} Cancelled", tx_id); + info!("Transaction {} Cancelled", tx_id_string); Ok(()) } Err(e) => { diff --git a/src/bin/grin.rs b/src/bin/grin.rs index 8679f7f07..704fda17d 100644 --- a/src/bin/grin.rs +++ b/src/bin/grin.rs @@ -321,6 +321,11 @@ fn real_main() -> i32 { .help("The ID of the transaction to cancel") .short("i") .long("id") + .takes_value(true)) + .arg(Arg::with_name("txid") + .help("The TxID of the transaction to cancel") + .short("t") + .long("txid") .takes_value(true))) .subcommand(SubCommand::with_name("info") diff --git a/wallet/src/libwallet/api.rs b/wallet/src/libwallet/api.rs index 920559fb5..1635e7404 100644 --- a/wallet/src/libwallet/api.rs +++ b/wallet/src/libwallet/api.rs @@ -322,7 +322,11 @@ where /// output if you're recipient), and unlock all locked outputs associated /// with the transaction used when a transaction is created but never /// posted - pub fn cancel_tx(&mut self, tx_id: u32) -> Result<(), Error> { + pub fn cancel_tx( + &mut self, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(), Error> { let mut w = self.wallet.lock(); w.open_with_credentials()?; let parent_key_id = w.parent_key_id(); @@ -331,7 +335,7 @@ where "Can't contact running Grin node. Not Cancelling.", ))?; } - tx::cancel_tx(&mut *w, &parent_key_id, tx_id)?; + tx::cancel_tx(&mut *w, &parent_key_id, tx_id, tx_slate_id)?; w.close()?; Ok(()) } diff --git a/wallet/src/libwallet/controller.rs b/wallet/src/libwallet/controller.rs index d35f25f50..75bdc170b 100644 --- a/wallet/src/libwallet/controller.rs +++ b/wallet/src/libwallet/controller.rs @@ -342,7 +342,7 @@ where let params = parse_params(&req); if let Some(id_string) = params.get("id") { Box::new(match id_string[0].parse() { - Ok(id) => match api.cancel_tx(id) { + Ok(id) => match api.cancel_tx(Some(id), None) { Ok(_) => ok(()), Err(e) => { error!("cancel_tx: failed with error: {}", e); @@ -356,9 +356,25 @@ where ).into()) } }) + } else if let Some(tx_id_string) = params.get("tx_id") { + Box::new(match tx_id_string[0].parse() { + Ok(tx_id) => match api.cancel_tx(None, Some(tx_id)) { + Ok(_) => ok(()), + Err(e) => { + error!("cancel_tx: failed with error: {}", e); + err(e) + } + }, + Err(e) => { + error!("cancel_tx: could not parse tx_id: {}", e); + err(ErrorKind::TransactionCancellationError( + "cancel_tx: cannot cancel transaction. Could not parse tx_id in request.", + ).into()) + } + }) } else { Box::new(err(ErrorKind::TransactionCancellationError( - "cancel_tx: Cannot cancel transaction. Missing id param in request.", + "cancel_tx: Cannot cancel transaction. Missing id or tx_id param in request.", ).into())) } } diff --git a/wallet/src/libwallet/error.rs b/wallet/src/libwallet/error.rs index d7dc888eb..7a84a2a55 100644 --- a/wallet/src/libwallet/error.rs +++ b/wallet/src/libwallet/error.rs @@ -150,11 +150,11 @@ pub enum ErrorKind { /// Transaction doesn't exist #[fail(display = "Transaction {} doesn't exist", _0)] - TransactionDoesntExist(u32), + TransactionDoesntExist(String), /// Transaction already rolled back #[fail(display = "Transaction {} cannot be cancelled", _0)] - TransactionNotCancellable(u32), + TransactionNotCancellable(String), /// Cancellation error #[fail(display = "Cancellation Error: {}", _0)] diff --git a/wallet/src/libwallet/internal/tx.rs b/wallet/src/libwallet/internal/tx.rs index 3aa5a3fec..dd3a885a3 100644 --- a/wallet/src/libwallet/internal/tx.rs +++ b/wallet/src/libwallet/internal/tx.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use util::RwLock; +use uuid::Uuid; use core::core::verifier_cache::LruVerifierCache; use core::core::Transaction; @@ -153,26 +154,33 @@ where pub fn cancel_tx( wallet: &mut T, parent_key_id: &Identifier, - tx_id: u32, + tx_id: Option, + tx_slate_id: Option, ) -> Result<(), Error> where T: WalletBackend, C: WalletClient, K: Keychain, { - let tx_vec = updater::retrieve_txs(wallet, Some(tx_id), None, &parent_key_id)?; + let mut tx_id_string = String::new(); + if let Some(tx_id) = tx_id { + tx_id_string = tx_id.to_string(); + } else if let Some(tx_slate_id) = tx_slate_id { + tx_id_string = tx_slate_id.to_string(); + } + let tx_vec = updater::retrieve_txs(wallet, tx_id, tx_slate_id, &parent_key_id)?; if tx_vec.len() != 1 { - return Err(ErrorKind::TransactionDoesntExist(tx_id))?; + return Err(ErrorKind::TransactionDoesntExist(tx_id_string))?; } let tx = tx_vec[0].clone(); if tx.tx_type != TxLogEntryType::TxSent && tx.tx_type != TxLogEntryType::TxReceived { - return Err(ErrorKind::TransactionNotCancellable(tx_id))?; + return Err(ErrorKind::TransactionNotCancellable(tx_id_string))?; } if tx.confirmed == true { - return Err(ErrorKind::TransactionNotCancellable(tx_id))?; + return Err(ErrorKind::TransactionNotCancellable(tx_id_string))?; } // get outputs associated with tx - let res = updater::retrieve_outputs(wallet, false, Some(tx_id), &parent_key_id)?; + let res = updater::retrieve_outputs(wallet, false, Some(tx.id), &parent_key_id)?; let outputs = res.iter().map(|(out, _)| out).cloned().collect(); updater::cancel_tx_and_outputs(wallet, tx, outputs, parent_key_id)?; Ok(()) @@ -192,7 +200,7 @@ where { let tx_vec = updater::retrieve_txs(wallet, Some(tx_id), None, parent_key_id)?; if tx_vec.len() != 1 { - return Err(ErrorKind::TransactionDoesntExist(tx_id))?; + return Err(ErrorKind::TransactionDoesntExist(tx_id.to_string()))?; } let tx = tx_vec[0].clone(); Ok((tx.confirmed, tx.tx_hex)) From 2ab31d18a395e7dac67b693752c0e39730afc8b7 Mon Sep 17 00:00:00 2001 From: Quentin Le Sceller Date: Tue, 13 Nov 2018 11:56:48 +0100 Subject: [PATCH 3/4] Add doc --- doc/api/wallet_owner_api.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/api/wallet_owner_api.md b/doc/api/wallet_owner_api.md index fd0653767..3da387570 100644 --- a/doc/api/wallet_owner_api.md +++ b/doc/api/wallet_owner_api.md @@ -523,7 +523,8 @@ Roll back a transaction and all associated outputs with a given transaction id T * **URL** - /v1/wallet/owner/cancel_tx?id=x + * /v1/wallet/owner/cancel_tx?id=x + * /v1/wallet/owner/cancel_tx?tx_id=x * **Method:** @@ -532,7 +533,8 @@ Roll back a transaction and all associated outputs with a given transaction id T * **URL Params** **Required:** - `id=[number]` + * `id=[number]` the transaction id + * `tx_id=[string]`the transaction slate id * **Data Params** From e923b90ad22b9593a366665f2c2749391326e2d4 Mon Sep 17 00:00:00 2001 From: Quentin Le Sceller Date: Tue, 13 Nov 2018 11:57:43 +0100 Subject: [PATCH 4/4] Fix tests --- wallet/tests/transaction.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wallet/tests/transaction.rs b/wallet/tests/transaction.rs index 2e1b372c7..f4165ddb0 100644 --- a/wallet/tests/transaction.rs +++ b/wallet/tests/transaction.rs @@ -398,14 +398,14 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { // Wallet 1 decides to roll back instead wallet::controller::owner_single_use(wallet1.clone(), |api| { // can't roll back coinbase - let res = api.cancel_tx(1); + let res = api.cancel_tx(Some(1), None); assert!(res.is_err()); let (_, txs) = api.retrieve_txs(true, None, None)?; let tx = txs .iter() .find(|t| t.tx_slate_id == Some(slate.id)) .unwrap(); - api.cancel_tx(tx.id)?; + api.cancel_tx(Some(tx.id), None)?; let (refreshed, wallet1_info) = api.retrieve_summary_info(true)?; assert!(refreshed); println!( @@ -419,7 +419,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { (wallet1_info.last_confirmed_height - cm) * reward ); // can't roll back again - let res = api.cancel_tx(tx.id); + let res = api.cancel_tx(Some(tx.id), None); assert!(res.is_err()); Ok(()) @@ -432,14 +432,14 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { .iter() .find(|t| t.tx_slate_id == Some(slate.id)) .unwrap(); - api.cancel_tx(tx.id)?; + api.cancel_tx(Some(tx.id), None)?; let (refreshed, wallet2_info) = api.retrieve_summary_info(true)?; assert!(refreshed); // check all eligible inputs should be now be spendable assert_eq!(wallet2_info.amount_currently_spendable, 0,); assert_eq!(wallet2_info.total, 0,); // can't roll back again - let res = api.cancel_tx(tx.id); + let res = api.cancel_tx(Some(tx.id), None); assert!(res.is_err()); Ok(())