diff --git a/api/src/foreign.rs b/api/src/foreign.rs index bb36f171..4c08ba60 100644 --- a/api/src/foreign.rs +++ b/api/src/foreign.rs @@ -119,9 +119,7 @@ where None => None, }; - let (_, mut create_fn) = - tx::add_output_to_slate(&mut *w, slate, &parent_key_id, 1, message)?; - create_fn(&mut *w, &slate.tx, PhantomData, PhantomData)?; + tx::add_output_to_slate(&mut *w, slate, &parent_key_id, 1, message)?; tx::update_message(&mut *w, slate)?; w.close()?; Ok(()) diff --git a/api/src/owner.rs b/api/src/owner.rs index 9a1a0959..ddc30cce 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -35,11 +35,10 @@ use crate::core::core::hash::Hashed; use crate::core::core::Transaction; use crate::core::ser; use crate::keychain::{Identifier, Keychain}; -use crate::libwallet::internal::{keys, tx, updater}; +use crate::libwallet::internal::{keys, selection, tx, updater}; use crate::libwallet::slate::Slate; use crate::libwallet::types::{ - AcctPathMapping, NodeClient, OutputData, OutputLockFn, TxLogEntry, TxWrapper, WalletBackend, - WalletInfo, + AcctPathMapping, NodeClient, OutputData, TxLogEntry, TxWrapper, WalletBackend, WalletInfo, }; use crate::libwallet::{Error, ErrorKind}; use crate::util; @@ -625,7 +624,7 @@ where selection_strategy_is_use_all: bool, message: Option, target_slate_version: Option, - ) -> Result<(Slate, OutputLockFn), Error> { + ) -> Result { let mut w = self.wallet.lock(); w.open_with_credentials()?; let parent_key_id = match src_acct_name { @@ -649,7 +648,7 @@ where let mut slate = tx::new_tx_slate(&mut *w, amount, 2)?; - let (context, lock_fn) = tx::add_inputs_to_slate( + let context = tx::add_inputs_to_slate( &mut *w, &mut slate, minimum_confirmations, @@ -674,7 +673,7 @@ where if let Some(v) = target_slate_version { slate.version_info.orig_version = v; } - Ok((slate, lock_fn)) + Ok(slate) } /// Estimates the amount to be locked and fee for the transaction without creating one @@ -746,14 +745,14 @@ where } /// Lock outputs associated with a given slate/transaction - pub fn tx_lock_outputs( - &self, - slate: &Slate, - mut lock_fn: OutputLockFn, - ) -> Result<(), Error> { + /// and create any outputs needed + pub fn tx_lock_outputs(&self, slate: &Slate) -> Result<(), Error> { let mut w = self.wallet.lock(); w.open_with_credentials()?; - lock_fn(&mut *w, &slate.tx, PhantomData, PhantomData)?; + let context = w.get_private_context(slate.id.as_bytes())?; + w.open_with_credentials()?; + selection::lock_tx_context(&mut *w, slate, &context)?; + w.close()?; Ok(()) } diff --git a/api/src/owner_rpc.rs b/api/src/owner_rpc.rs index 075526ba..b7757e24 100644 --- a/api/src/owner_rpc.rs +++ b/api/src/owner_rpc.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! JSON-RPC Stub generation for the Foreign API +//! JSON-RPC Stub generation for the Owner API use uuid::Uuid; @@ -202,6 +202,42 @@ pub trait OwnerRpc { minimum_confirmations: u64, ) -> Result<(bool, WalletInfo), ErrorKind>; + /** + Networked version of [Owner::estimate_initiate_tx](struct.Owner.html#method.initiate_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "initiate_tx", + "params": [null, 0, 0, 10, 0, false, "my message", null], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + + fn initiate_tx( + &self, + src_acct_name: Option, + amount: u64, + minimum_confirmations: u64, + max_outputs: usize, + num_change_outputs: usize, + selection_strategy_is_use_all: bool, + message: Option, + target_slate_version: Option, + ) -> Result; + /** Networked version of [Owner::estimate_initiate_tx](struct.Owner.html#method.estimate_initiate_tx). @@ -236,6 +272,53 @@ pub trait OwnerRpc { selection_strategy_is_use_all: bool, ) -> Result<(/* total */ u64, /* fee */ u64), ErrorKind>; + /** + Networked version of [Owner::tx_lock_outputs](struct.Owner.html#method.tx_lock_outputs). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + { + "jsonrpc": "2.0", + "method": "tx_lock_outputs", + "params": [{ + "version_info": { + "version": 2, + "orig_version": 2, + "min_compat_version": 0 + }, + "amount": 0, + "fee": 0, + "height": 0, + "id": "414bad48-3386-4fa7-8483-72384c886ba3", + "lock_height": 0, + "num_participants": 2, + "participant_data": [], + "tx": { + "body": { + "inputs": [], + "kernels": [], + "outputs": [] + }, + "offset": "0000000000000000000000000000000000000000000000000000000000000000" + } + }], + "id": 1 + }, + { + "jsonrpc": "2.0", + "result": { + "Err": { + "CallbackImpl": "Error opening wallet" + } + }, + "id": 1 + } + # ); + ``` + */ + fn tx_lock_outputs(&self, slate: Slate) -> Result<(), ErrorKind>; + /** Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx). @@ -555,6 +638,31 @@ where .map_err(|e| e.kind()) } + fn initiate_tx( + &self, + src_acct_name: Option, + amount: u64, + minimum_confirmations: u64, + max_outputs: usize, + num_change_outputs: usize, + selection_strategy_is_use_all: bool, + message: Option, + target_slate_version: Option, + ) -> Result { + Owner::initiate_tx( + self, + src_acct_name.as_ref().map(String::as_str), + amount, + minimum_confirmations, + max_outputs, + num_change_outputs, + selection_strategy_is_use_all, + message, + target_slate_version, + ) + .map_err(|e| e.kind()) + } + fn estimate_initiate_tx( &self, src_acct_name: Option, @@ -581,6 +689,10 @@ where Ok(slate) } + fn tx_lock_outputs(&self, mut slate: Slate) -> Result<(), ErrorKind> { + Owner::tx_lock_outputs(self, &mut slate).map_err(|e| e.kind()) + } + fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind> { Owner::cancel_tx(self, tx_id, tx_slate_id).map_err(|e| e.kind()) } diff --git a/libwallet/src/internal/selection.rs b/libwallet/src/internal/selection.rs index c41578f0..2e49dd20 100644 --- a/libwallet/src/internal/selection.rs +++ b/libwallet/src/internal/selection.rs @@ -14,7 +14,7 @@ //! Selection of inputs for building transactions -use crate::core::core::{amount_to_hr_string, Transaction}; +use crate::core::core::amount_to_hr_string; use crate::core::libtx::{build, tx_fee}; use crate::error::{Error, ErrorKind}; use crate::internal::keys; @@ -22,7 +22,6 @@ use crate::keychain::{Identifier, Keychain}; use crate::slate::Slate; use crate::types::*; use std::collections::HashMap; -use std::marker::PhantomData; /// Initialize a transaction on the sender side, returns a corresponding /// libwallet transaction slate with the appropriate inputs selected, @@ -37,7 +36,7 @@ pub fn build_send_tx( change_outputs: usize, selection_strategy_is_use_all: bool, parent_key_id: Identifier, -) -> Result<(Context, OutputLockFn), Error> +) -> Result where T: WalletBackend, C: NodeClient, @@ -64,87 +63,104 @@ where let mut context = Context::new( wallet.keychain().secp(), blinding.secret_key(&keychain.secp()).unwrap(), + &parent_key_id, ); + context.fee = fee; + // Store our private identifiers for each input for input in inputs { - context.add_input(&input.key_id, &input.mmr_index); + context.add_input(&input.key_id, &input.mmr_index, input.value); } let mut commits: HashMap> = HashMap::new(); // Store change output(s) and cached commits for (change_amount, id, mmr_index) in &change_amounts_derivations { - context.add_output(&id, &mmr_index); + context.add_output(&id, &mmr_index, *change_amount); commits.insert( id.clone(), wallet.calc_commit_for_cache(*change_amount, &id)?, ); } - let lock_inputs_in = context.get_inputs().clone(); - let _lock_outputs = context.get_outputs().clone(); - let messages_in = Some(slate.participant_messages()); - let slate_id_in = slate.id.clone(); - let height_in = slate.height; + Ok(context) +} - // Return a closure to acquire wallet lock and lock the coins being spent - // so we avoid accidental double spend attempt. - let update_sender_wallet_fn = - move |wallet: &mut T, tx: &Transaction, _: PhantomData, _: PhantomData| { - let tx_entry = { - // These ensure the closure remains FnMut - let lock_inputs = lock_inputs_in.clone(); - let messages = messages_in.clone(); - let slate_id = slate_id_in.clone(); - let height = height_in.clone(); - let mut batch = wallet.batch()?; - let log_id = batch.next_tx_log_id(&parent_key_id)?; - let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxSent, log_id); - t.tx_slate_id = Some(slate_id.clone()); - let filename = format!("{}.grintx", slate_id); - t.stored_tx = Some(filename); - t.fee = Some(fee); - let mut amount_debited = 0; - t.num_inputs = lock_inputs.len(); - for id in lock_inputs { - let mut coin = batch.get(&id.0, &id.1).unwrap(); - coin.tx_log_entry = Some(log_id); - amount_debited = amount_debited + coin.value; - batch.lock_output(&mut coin)?; - } +/// Locks all corresponding outputs in the context, creates +/// change outputs and tx log entry +pub fn lock_tx_context( + wallet: &mut T, + slate: &Slate, + context: &Context, +) -> Result<(), Error> +where + T: WalletBackend, + C: NodeClient, + K: Keychain, +{ + let mut output_commits: HashMap, u64)> = HashMap::new(); + // Store cached commits before locking wallet + for (id, _, change_amount) in &context.get_outputs() { + output_commits.insert( + id.clone(), + ( + wallet.calc_commit_for_cache(*change_amount, &id)?, + *change_amount, + ), + ); + } - t.amount_debited = amount_debited; - t.messages = messages; + let tx_entry = { + let lock_inputs = context.get_inputs().clone(); + let messages = Some(slate.participant_messages()); + let slate_id = slate.id; + let height = slate.height; + let parent_key_id = context.parent_key_id.clone(); + let mut batch = wallet.batch()?; + let log_id = batch.next_tx_log_id(&parent_key_id)?; + let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxSent, log_id); + t.tx_slate_id = Some(slate_id.clone()); + let filename = format!("{}.grintx", slate_id); + t.stored_tx = Some(filename); + t.fee = Some(slate.fee); + let mut amount_debited = 0; + t.num_inputs = lock_inputs.len(); + for id in lock_inputs { + let mut coin = batch.get(&id.0, &id.1).unwrap(); + coin.tx_log_entry = Some(log_id); + amount_debited = amount_debited + coin.value; + batch.lock_output(&mut coin)?; + } - // write the output representing our change - for (change_amount, id, _) in &change_amounts_derivations { - t.num_outputs += 1; - t.amount_credited += change_amount; - let commit = commits.get(&id).unwrap().clone(); - batch.save(OutputData { - root_key_id: parent_key_id.clone(), - key_id: id.clone(), - n_child: id.to_path().last_path_index(), - commit: commit, - mmr_index: None, - value: change_amount.clone(), - status: OutputStatus::Unconfirmed, - height: height, - lock_height: 0, - is_coinbase: false, - tx_log_entry: Some(log_id), - })?; - } - batch.save_tx_log_entry(t.clone(), &parent_key_id)?; - batch.commit()?; - t - }; - wallet.store_tx(&format!("{}", tx_entry.tx_slate_id.unwrap()), tx)?; - Ok(()) - }; + t.amount_debited = amount_debited; + t.messages = messages; - Ok((context, Box::new(update_sender_wallet_fn))) + // write the output representing our change + for (id, _, _) in &context.get_outputs() { + t.num_outputs += 1; + let (commit, change_amount) = output_commits.get(&id).unwrap().clone(); + t.amount_credited += change_amount; + batch.save(OutputData { + root_key_id: parent_key_id.clone(), + key_id: id.clone(), + n_child: id.to_path().last_path_index(), + commit: commit, + mmr_index: None, + value: change_amount.clone(), + status: OutputStatus::Unconfirmed, + height: height, + lock_height: 0, + is_coinbase: false, + tx_log_entry: Some(log_id), + })?; + } + batch.save_tx_log_entry(t.clone(), &parent_key_id)?; + batch.commit()?; + t + }; + wallet.store_tx(&format!("{}", tx_entry.tx_slate_id.unwrap()), &slate.tx)?; + Ok(()) } /// Creates a new output in the wallet for the recipient, @@ -155,7 +171,7 @@ pub fn build_recipient_output( wallet: &mut T, slate: &mut Slate, parent_key_id: Identifier, -) -> Result<(Identifier, Context, OutputLockFn), Error> +) -> Result<(Identifier, Context), Error> where T: WalletBackend, C: NodeClient, @@ -179,45 +195,36 @@ where blinding .secret_key(wallet.keychain().clone().secp()) .unwrap(), + &parent_key_id, ); - context.add_output(&key_id, &None); - let messages_in = Some(slate.participant_messages()); + context.add_output(&key_id, &None, amount); + let messages = Some(slate.participant_messages()); + let commit = wallet.calc_commit_for_cache(amount, &key_id_inner)?; + let mut batch = wallet.batch()?; + let log_id = batch.next_tx_log_id(&parent_key_id)?; + let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxReceived, log_id); + t.tx_slate_id = Some(slate_id); + t.amount_credited = amount; + t.num_outputs = 1; + t.messages = messages; + batch.save(OutputData { + root_key_id: parent_key_id.clone(), + key_id: key_id_inner.clone(), + mmr_index: None, + n_child: key_id_inner.to_path().last_path_index(), + commit: commit, + value: amount, + status: OutputStatus::Unconfirmed, + height: height, + lock_height: 0, + is_coinbase: false, + tx_log_entry: Some(log_id), + })?; + batch.save_tx_log_entry(t, &parent_key_id)?; + batch.commit()?; - // Create closure that adds the output to recipient's wallet - // (up to the caller to decide when to do) - let wallet_add_fn = - move |wallet: &mut T, _tx: &Transaction, _: PhantomData, _: PhantomData| { - // Ensure closure remains FnMut - let messages = messages_in.clone(); - let commit = wallet.calc_commit_for_cache(amount, &key_id_inner)?; - let mut batch = wallet.batch()?; - let log_id = batch.next_tx_log_id(&parent_key_id)?; - let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxReceived, log_id); - t.tx_slate_id = Some(slate_id); - t.amount_credited = amount; - t.num_outputs = 1; - t.messages = messages; - batch.save(OutputData { - root_key_id: parent_key_id.clone(), - key_id: key_id_inner.clone(), - mmr_index: None, - n_child: key_id_inner.to_path().last_path_index(), - commit: commit, - value: amount, - status: OutputStatus::Unconfirmed, - height: height, - lock_height: 0, - is_coinbase: false, - tx_log_entry: Some(log_id), - })?; - batch.save_tx_log_entry(t, &parent_key_id)?; - batch.commit()?; - //TODO: Check whether we want to call this - //wallet.store_tx(&format!("{}", t.tx_slate_id.unwrap()), tx)?; - Ok(()) - }; - Ok((key_id, context, Box::new(wallet_add_fn))) + Ok((key_id, context)) } /// Builds a transaction to send to someone from the HD seed associated with the diff --git a/libwallet/src/internal/tx.rs b/libwallet/src/internal/tx.rs index 5ce9eac2..3577e758 100644 --- a/libwallet/src/internal/tx.rs +++ b/libwallet/src/internal/tx.rs @@ -19,7 +19,7 @@ use uuid::Uuid; use crate::internal::{selection, updater}; use crate::keychain::{Identifier, Keychain}; use crate::slate::Slate; -use crate::types::{Context, NodeClient, OutputLockFn, TxLogEntryType, WalletBackend}; +use crate::types::{Context, NodeClient, TxLogEntryType, WalletBackend}; use crate::{Error, ErrorKind}; /// Creates a new slate for a transaction, can be called by anyone involved in @@ -99,7 +99,7 @@ pub fn add_inputs_to_slate( parent_key_id: &Identifier, participant_id: usize, message: Option, -) -> Result<(Context, OutputLockFn), Error> +) -> Result where T: WalletBackend, C: NodeClient, @@ -115,7 +115,7 @@ where // according to plan // This function is just a big helper to do all of that, in theory // this process can be split up in any way - let (mut context, sender_lock_fn) = selection::build_send_tx( + let mut context = selection::build_send_tx( wallet, slate, minimum_confirmations, @@ -136,7 +136,7 @@ where message, )?; - Ok((context, sender_lock_fn)) + Ok(context) } /// Add outputs to the slate, becoming the recipient @@ -146,15 +146,14 @@ pub fn add_output_to_slate( parent_key_id: &Identifier, participant_id: usize, message: Option, -) -> Result<(Context, OutputLockFn), Error> +) -> Result where T: WalletBackend, C: NodeClient, K: Keychain, { // create an output using the amount in the slate - let (_, mut context, create_fn) = - selection::build_recipient_output(wallet, slate, parent_key_id.clone())?; + let (_, mut context) = selection::build_recipient_output(wallet, slate, parent_key_id.clone())?; // fill public keys let _ = slate.fill_round_1( @@ -173,7 +172,7 @@ where participant_id, )?; - Ok((context, create_fn)) + Ok(context) } /// Complete a transaction as the sender diff --git a/libwallet/src/types.rs b/libwallet/src/types.rs index 5c55e5f8..87d5fbfa 100644 --- a/libwallet/src/types.rs +++ b/libwallet/src/types.rs @@ -30,13 +30,8 @@ use serde; use serde_json; use std::collections::HashMap; use std::fmt; -use std::marker::PhantomData; use uuid::Uuid; -/// Lock function type -pub type OutputLockFn = - Box, PhantomData) -> Result<(), Error>>; - /// Combined trait to allow dynamic wallet dispatch pub trait WalletInst: WalletBackend + Send + Sync + 'static where @@ -377,23 +372,28 @@ impl fmt::Display for OutputStatus { #[derive(Serialize, Deserialize, Clone, Debug)] /// Holds the context for a single aggsig transaction pub struct Context { + /// Parent key id + pub parent_key_id: Identifier, /// Secret key (of which public is shared) pub sec_key: SecretKey, /// Secret nonce (of which public is shared) /// (basically a SecretKey) pub sec_nonce: SecretKey, - /// store my outputs between invocations - pub output_ids: Vec<(Identifier, Option)>, + /// store my outputs + amounts between invocations + /// Id, mmr_index (if known), amount + pub output_ids: Vec<(Identifier, Option, u64)>, /// store my inputs - pub input_ids: Vec<(Identifier, Option)>, + /// Id, mmr_index (if known), amount + pub input_ids: Vec<(Identifier, Option, u64)>, /// store the calculated fee pub fee: u64, } impl Context { /// Create a new context with defaults - pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey) -> Context { + pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey, parent_key_id: &Identifier) -> Context { Context { + parent_key_id: parent_key_id.clone(), sec_key: sec_key, sec_nonce: aggsig::create_secnonce(secp).unwrap(), input_ids: vec![], @@ -406,23 +406,25 @@ impl Context { impl Context { /// Tracks an output contributing to my excess value (if it needs to /// be kept between invocations - pub fn add_output(&mut self, output_id: &Identifier, mmr_index: &Option) { - self.output_ids.push((output_id.clone(), mmr_index.clone())); + pub fn add_output(&mut self, output_id: &Identifier, mmr_index: &Option, amount: u64) { + self.output_ids + .push((output_id.clone(), mmr_index.clone(), amount)); } /// Returns all stored outputs - pub fn get_outputs(&self) -> Vec<(Identifier, Option)> { + pub fn get_outputs(&self) -> Vec<(Identifier, Option, u64)> { self.output_ids.clone() } /// Tracks IDs of my inputs into the transaction /// be kept between invocations - pub fn add_input(&mut self, input_id: &Identifier, mmr_index: &Option) { - self.input_ids.push((input_id.clone(), mmr_index.clone())); + pub fn add_input(&mut self, input_id: &Identifier, mmr_index: &Option, amount: u64) { + self.input_ids + .push((input_id.clone(), mmr_index.clone(), amount)); } /// Returns all stored input identifiers - pub fn get_inputs(&self) -> Vec<(Identifier, Option)> { + pub fn get_inputs(&self) -> Vec<(Identifier, Option, u64)> { self.input_ids.clone() } diff --git a/libwallet/tests/libwallet.rs b/libwallet/tests/libwallet.rs index d126c223..6ded2667 100644 --- a/libwallet/tests/libwallet.rs +++ b/libwallet/tests/libwallet.rs @@ -14,7 +14,7 @@ //! core::libtx specific tests use self::core::core::transaction; use self::core::libtx::{aggsig, proof}; -use self::keychain::{BlindSum, BlindingFactor, ExtKeychain, Keychain}; +use self::keychain::{BlindSum, BlindingFactor, ExtKeychain, ExtKeychainPath, Keychain}; use self::util::secp; use self::util::secp::key::{PublicKey, SecretKey}; use grin_core as core; @@ -29,6 +29,7 @@ fn kernel_sig_msg() -> secp::Message { #[test] fn aggsig_sender_receiver_interaction() { + let parent = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier(); let sender_keychain = ExtKeychain::from_random_seed(true).unwrap(); let receiver_keychain = ExtKeychain::from_random_seed(true).unwrap(); @@ -71,7 +72,7 @@ fn aggsig_sender_receiver_interaction() { let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); - s_cx = Context::new(&keychain.secp(), blind); + s_cx = Context::new(&keychain.secp(), blind, &parent); s_cx.get_public_keys(&keychain.secp()) }; @@ -85,9 +86,9 @@ fn aggsig_sender_receiver_interaction() { // let blind = blind_sum.secret_key(&keychain.secp())?; let blind = keychain.derive_key(0, &key_id).unwrap(); - rx_cx = Context::new(&keychain.secp(), blind); + rx_cx = Context::new(&keychain.secp(), blind, &parent); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); - rx_cx.add_output(&key_id, &None); + rx_cx.add_output(&key_id, &None, 0); pub_nonce_sum = PublicKey::from_combination( keychain.secp(), @@ -233,6 +234,7 @@ fn aggsig_sender_receiver_interaction() { #[test] fn aggsig_sender_receiver_interaction_offset() { + let parent = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier(); let sender_keychain = ExtKeychain::from_random_seed(true).unwrap(); let receiver_keychain = ExtKeychain::from_random_seed(true).unwrap(); @@ -288,7 +290,7 @@ fn aggsig_sender_receiver_interaction_offset() { let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); - s_cx = Context::new(&keychain.secp(), blind); + s_cx = Context::new(&keychain.secp(), blind, &parent); s_cx.get_public_keys(&keychain.secp()) }; @@ -301,9 +303,9 @@ fn aggsig_sender_receiver_interaction_offset() { let blind = keychain.derive_key(0, &key_id).unwrap(); - rx_cx = Context::new(&keychain.secp(), blind); + rx_cx = Context::new(&keychain.secp(), blind, &parent); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); - rx_cx.add_output(&key_id, &None); + rx_cx.add_output(&key_id, &None, 0); pub_nonce_sum = PublicKey::from_combination( keychain.secp(), diff --git a/refwallet/src/command.rs b/refwallet/src/command.rs index 4b92d186..c899cad9 100644 --- a/refwallet/src/command.rs +++ b/refwallet/src/command.rs @@ -244,7 +244,7 @@ pub fn send( args.message.clone(), args.target_slate_version, ); - let (mut slate, lock_fn) = match result { + let mut slate = match result { Ok(s) => { info!( "Tx created: {} grin to {} (strategy '{}')", @@ -268,7 +268,7 @@ pub fn send( }; if adapter.supports_sync() { slate = adapter.send_tx_sync(&args.dest, &slate)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; if args.method == "self" { controller::foreign_single_use(wallet, |api| { api.receive_tx(&mut slate, Some(&args.dest), None)?; @@ -282,7 +282,7 @@ pub fn send( api.finalize_tx(&mut slate)?; } else { adapter.send_tx_async(&args.dest, &slate)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; } if adapter.supports_sync() { let result = api.post_tx(&slate.tx, args.fluff); diff --git a/refwallet/src/controller.rs b/refwallet/src/controller.rs index 83aae396..31a131ce 100644 --- a/refwallet/src/controller.rs +++ b/refwallet/src/controller.rs @@ -331,7 +331,7 @@ where args.message, args.target_slate_version, ); - let (mut slate, lock_fn) = match result { + let mut slate = match result { Ok(s) => { info!( "Tx created: {} grin to {} (strategy '{}')", @@ -371,7 +371,7 @@ where ))?; } } - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; if args.method != "file" { api.finalize_tx(&mut slate)?; } diff --git a/refwallet/src/test_framework/mod.rs b/refwallet/src/test_framework/mod.rs index a07efbd4..35e596ba 100644 --- a/refwallet/src/test_framework/mod.rs +++ b/refwallet/src/test_framework/mod.rs @@ -194,7 +194,7 @@ where C: NodeClient, K: keychain::Keychain, { - let (slate_i, lock_fn) = api.initiate_tx( + let slate_i = api.initiate_tx( None, // account amount, // amount 2, // minimum confirmations @@ -204,7 +204,7 @@ where None, None, )?; let mut slate = client.send_tx_slate_direct(dest, &slate_i)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; api.finalize_tx(&mut slate)?; api.post_tx(&slate.tx, false)?; // mines a block Ok(()) diff --git a/refwallet/tests/accounts.rs b/refwallet/tests/accounts.rs index 7d92ec78..049bf928 100644 --- a/refwallet/tests/accounts.rs +++ b/refwallet/tests/accounts.rs @@ -177,7 +177,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { } wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (mut slate, lock_fn) = api.initiate_tx( + let mut slate = api.initiate_tx( None, reward, // amount 2, // minimum confirmations 500, // max outputs @@ -186,7 +186,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; api.finalize_tx(&mut slate)?; api.post_tx(&slate.tx, false)?; Ok(()) diff --git a/refwallet/tests/check.rs b/refwallet/tests/check.rs index 952a7616..95bbffa4 100644 --- a/refwallet/tests/check.rs +++ b/refwallet/tests/check.rs @@ -155,7 +155,7 @@ fn check_repair_impl(test_dir: &str) -> Result<(), libwallet::Error> { // perform a transaction, but don't let it finish wallet::controller::owner_single_use(wallet1.clone(), |api| { // send to send - let (mut slate, lock_fn) = api.initiate_tx( + let mut slate = api.initiate_tx( None, reward * 2, // amount cm, // minimum confirmations @@ -169,7 +169,7 @@ fn check_repair_impl(test_dir: &str) -> Result<(), libwallet::Error> { let file_adapter = FileWalletCommAdapter::new(); let send_file = format!("{}/part_tx_1.tx", test_dir); file_adapter.send_tx_async(&send_file, &mut slate)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; Ok(()) })?; diff --git a/refwallet/tests/file.rs b/refwallet/tests/file.rs index e1fe0b10..579bf153 100644 --- a/refwallet/tests/file.rs +++ b/refwallet/tests/file.rs @@ -103,7 +103,7 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); // send to send - let (mut slate, lock_fn) = api.initiate_tx( + let mut slate = api.initiate_tx( Some("mining"), reward * 2, // amount 2, // minimum confirmations @@ -116,7 +116,7 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { // output tx file let file_adapter = FileWalletCommAdapter::new(); file_adapter.send_tx_async(&send_file, &mut slate)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; Ok(()) })?; diff --git a/refwallet/tests/repost.rs b/refwallet/tests/repost.rs index 5023ff2f..22b6bbf3 100644 --- a/refwallet/tests/repost.rs +++ b/refwallet/tests/repost.rs @@ -101,7 +101,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); // send to send - let (mut slate, lock_fn) = api.initiate_tx( + let mut slate = api.initiate_tx( Some("mining"), reward * 2, // amount 2, // minimum confirmations @@ -114,7 +114,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { // output tx file let file_adapter = FileWalletCommAdapter::new(); file_adapter.send_tx_async(&send_file, &mut slate)?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; Ok(()) })?; @@ -198,7 +198,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount * 2, // amount 2, // minimum confirmations @@ -209,7 +209,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; Ok(()) })?; diff --git a/refwallet/tests/restore.rs b/refwallet/tests/restore.rs index aea0ed7b..ab2371cd 100644 --- a/refwallet/tests/restore.rs +++ b/refwallet/tests/restore.rs @@ -235,7 +235,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { let mut slate = Slate::blank(1); wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount, // amount 2, // minimum confirmations 500, // max outputs @@ -244,7 +244,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; sender_api.post_tx(&slate.tx, false)?; Ok(()) @@ -256,7 +256,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { // Send some to wallet 3 wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount * 2, // amount 2, // minimum confirmations @@ -267,7 +267,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { None, )?; slate = client1.send_tx_slate_direct("wallet3", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; sender_api.post_tx(&slate.tx, false)?; Ok(()) @@ -279,7 +279,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { // Wallet3 to wallet 2 wallet::controller::owner_single_use(wallet3.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount * 3, // amount 2, // minimum confirmations @@ -290,7 +290,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { None, )?; slate = client3.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; sender_api.post_tx(&slate.tx, false)?; Ok(()) @@ -308,7 +308,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { // Wallet3 to wallet 2 again (to another account) wallet::controller::owner_single_use(wallet3.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount * 3, // amount 2, // minimum confirmations @@ -319,7 +319,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> { None, )?; slate = client3.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; sender_api.post_tx(&slate.tx, false)?; Ok(()) diff --git a/refwallet/tests/self_send.rs b/refwallet/tests/self_send.rs index 98e0aa3d..9a1840d9 100644 --- a/refwallet/tests/self_send.rs +++ b/refwallet/tests/self_send.rs @@ -84,7 +84,7 @@ fn self_send_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); // send to send - let (mut slate, lock_fn) = api.initiate_tx( + let mut slate = api.initiate_tx( Some("mining"), reward * 2, // amount 2, // minimum confirmations @@ -94,7 +94,7 @@ fn self_send_test_impl(test_dir: &str) -> Result<(), libwallet::Error> { None, None, )?; - api.tx_lock_outputs(&slate, lock_fn)?; + api.tx_lock_outputs(&slate)?; // Send directly to self wallet::controller::foreign_single_use(wallet1.clone(), |api| { api.receive_tx(&mut slate, Some("listener"), None)?; diff --git a/refwallet/tests/transaction.rs b/refwallet/tests/transaction.rs index ee972092..3b2fa561 100644 --- a/refwallet/tests/transaction.rs +++ b/refwallet/tests/transaction.rs @@ -97,7 +97,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { let mut slate = Slate::blank(1); wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount, // amount 2, // minimum confirmations 500, // max outputs @@ -106,7 +106,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; Ok(()) })?; @@ -129,6 +129,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { assert!(!tx.confirmed); assert!(tx.confirmation_ts.is_none()); assert_eq!(tx.amount_debited - tx.amount_credited, fee + amount); + println!("tx: {:?}", tx); assert_eq!(Some(fee), tx.fee); Ok(()) })?; @@ -258,7 +259,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { // the stored transaction instead wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount * 2, // amount 2, // minimum confirmations @@ -269,7 +270,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> { None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; Ok(()) })?; @@ -357,7 +358,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { let mut slate = Slate::blank(1); wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { // note this will increment the block count as part of the transaction "Posting" - let (slate_i, lock_fn) = sender_api.initiate_tx( + let slate_i = sender_api.initiate_tx( None, amount, // amount 2, // minimum confirmations 500, // max outputs @@ -366,7 +367,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> { None, None, )?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, lock_fn)?; + sender_api.tx_lock_outputs(&slate)?; sender_api.finalize_tx(&mut slate)?; Ok(()) })?;