Remove callbacks from transaction API functions (#22)

* remove callbacks from transaction creation

* rustfmt

* add missing functions to owner api rpc

* comment fix
This commit is contained in:
Yeastplume 2019-03-14 15:05:13 +00:00 committed by GitHub
parent baa5e46d7d
commit 8cca9821bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 300 additions and 180 deletions

View file

@ -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(())

View file

@ -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<String>,
target_slate_version: Option<u16>,
) -> Result<(Slate, OutputLockFn<W, C, K>), Error> {
) -> Result<Slate, Error> {
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<W, C, K>,
) -> 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(())
}

View file

@ -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<String>,
amount: u64,
minimum_confirmations: u64,
max_outputs: usize,
num_change_outputs: usize,
selection_strategy_is_use_all: bool,
message: Option<String>,
target_slate_version: Option<u16>,
) -> Result<Slate, ErrorKind>;
/**
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<String>,
amount: u64,
minimum_confirmations: u64,
max_outputs: usize,
num_change_outputs: usize,
selection_strategy_is_use_all: bool,
message: Option<String>,
target_slate_version: Option<u16>,
) -> Result<Slate, ErrorKind> {
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<String>,
@ -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<u32>, tx_slate_id: Option<Uuid>) -> Result<(), ErrorKind> {
Owner::cancel_tx(self, tx_id, tx_slate_id).map_err(|e| e.kind())
}

View file

@ -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<T: ?Sized, C, K>(
change_outputs: usize,
selection_strategy_is_use_all: bool,
parent_key_id: Identifier,
) -> Result<(Context, OutputLockFn<T, C, K>), Error>
) -> Result<Context, Error>
where
T: WalletBackend<C, K>,
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<Identifier, Option<String>> = 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<C>, _: PhantomData<K>| {
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<T: ?Sized, C, K>(
wallet: &mut T,
slate: &Slate,
context: &Context,
) -> Result<(), Error>
where
T: WalletBackend<C, K>,
C: NodeClient,
K: Keychain,
{
let mut output_commits: HashMap<Identifier, (Option<String>, 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<T: ?Sized, C, K>(
wallet: &mut T,
slate: &mut Slate,
parent_key_id: Identifier,
) -> Result<(Identifier, Context, OutputLockFn<T, C, K>), Error>
) -> Result<(Identifier, Context), Error>
where
T: WalletBackend<C, K>,
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<C>, _: PhantomData<K>| {
// 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

View file

@ -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<T: ?Sized, C, K>(
parent_key_id: &Identifier,
participant_id: usize,
message: Option<String>,
) -> Result<(Context, OutputLockFn<T, C, K>), Error>
) -> Result<Context, Error>
where
T: WalletBackend<C, K>,
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<T: ?Sized, C, K>(
parent_key_id: &Identifier,
participant_id: usize,
message: Option<String>,
) -> Result<(Context, OutputLockFn<T, C, K>), Error>
) -> Result<Context, Error>
where
T: WalletBackend<C, K>,
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

View file

@ -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<T, C, K> =
Box<dyn FnMut(&mut T, &Transaction, PhantomData<C>, PhantomData<K>) -> Result<(), Error>>;
/// Combined trait to allow dynamic wallet dispatch
pub trait WalletInst<C, K>: WalletBackend<C, K> + 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<u64>)>,
/// store my outputs + amounts between invocations
/// Id, mmr_index (if known), amount
pub output_ids: Vec<(Identifier, Option<u64>, u64)>,
/// store my inputs
pub input_ids: Vec<(Identifier, Option<u64>)>,
/// Id, mmr_index (if known), amount
pub input_ids: Vec<(Identifier, Option<u64>, 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<u64>) {
self.output_ids.push((output_id.clone(), mmr_index.clone()));
pub fn add_output(&mut self, output_id: &Identifier, mmr_index: &Option<u64>, 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<u64>)> {
pub fn get_outputs(&self) -> Vec<(Identifier, Option<u64>, 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<u64>) {
self.input_ids.push((input_id.clone(), mmr_index.clone()));
pub fn add_input(&mut self, input_id: &Identifier, mmr_index: &Option<u64>, 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<u64>)> {
pub fn get_inputs(&self) -> Vec<(Identifier, Option<u64>, u64)> {
self.input_ids.clone()
}

View file

@ -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(),

View file

@ -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);

View file

@ -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)?;
}

View file

@ -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(())

View file

@ -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(())

View file

@ -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(())
})?;

View file

@ -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(())
})?;

View file

@ -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(())
})?;

View file

@ -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(())

View file

@ -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)?;

View file

@ -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(())
})?;