diff --git a/doc/wallet/usage.md b/doc/wallet/usage.md
index 37482b33e..768f0ae3d 100644
--- a/doc/wallet/usage.md
+++ b/doc/wallet/usage.md
@@ -268,6 +268,15 @@ Other flags here are:
[host]$ grin wallet send -f -d "http://192.168.0.10:13415" 60.00
```
+* `-g` 'Message' - You can specify an optional message to include alongside your transaction data. This message is purely for informational
+purposes between all transacting participants, and is not included in transaction data sent to the chain. Each participant message includes
+a signature that can be verified with the participant's public key. A message can also be specified by the recipient during a `grin wallet receive`
+command.
+
+```sh
+[host]$ grin wallet send -f -d "http://192.168.0.10:13415" -g "This is from Dave" 60.00
+```
+
### outputs
Simply displays all the the outputs in your wallet: e.g:
@@ -322,7 +331,6 @@ Transaction Log - Account 'default' - Block Height: 49
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6 Received Tx 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
->>>>>>> master
To see the inputs/outputs associated with a particular transaction, use the `-i` switch providing the Id of the given transaction, e.g:
diff --git a/servers/tests/framework/mod.rs b/servers/tests/framework/mod.rs
index b01e6eb8d..43ebb3527 100644
--- a/servers/tests/framework/mod.rs
+++ b/servers/tests/framework/mod.rs
@@ -352,6 +352,7 @@ impl LocalServerContainer {
max_outputs,
change_outputs,
selection_strategy == "all",
+ None,
)?;
slate = client_w.send_tx_sync(dest, &slate)?;
api.finalize_tx(&mut slate)?;
diff --git a/servers/tests/simulnet.rs b/servers/tests/simulnet.rs
index a7c9a757d..444f2ddf6 100644
--- a/servers/tests/simulnet.rs
+++ b/servers/tests/simulnet.rs
@@ -969,6 +969,7 @@ fn replicate_tx_fluff_failure() {
500, // max outputs
1000, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1_w.send_tx_sync(dest, &slate)?;
api.finalize_tx(&mut slate)?;
diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs
index 7329d18be..d2b633be2 100644
--- a/src/bin/cmd/wallet.rs
+++ b/src/bin/cmd/wallet.rs
@@ -355,6 +355,10 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
e
))
})?;
+ let message = match send_args.is_present("message") {
+ true => Some(send_args.value_of("message").unwrap().to_owned()),
+ false => None,
+ };
let minimum_confirmations: u64 = send_args
.value_of("minimum_confirmations")
.ok_or_else(|| {
@@ -417,6 +421,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
max_outputs,
change_outputs,
selection_strategy == "all",
+ message,
);
let (mut slate, lock_fn) = match result {
Ok(s) => {
@@ -453,11 +458,15 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
slate = adapter.send_tx_sync(dest, &slate)?;
if method == "self" {
controller::foreign_single_use(wallet, |api| {
- api.receive_tx(&mut slate, Some(dest))?;
+ api.receive_tx(&mut slate, Some(dest), None)?;
Ok(())
})?;
}
api.tx_lock_outputs(&slate, lock_fn)?;
+ if let Err(e) = api.verify_slate_messages(&slate) {
+ error!("Error validating participant messages: {}", e);
+ return Err(e);
+ }
api.finalize_tx(&mut slate)?;
} else {
adapter.send_tx_async(dest, &slate)?;
@@ -481,6 +490,10 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
}
("receive", Some(send_args)) => {
let mut receive_result: Result<(), grin_wallet::libwallet::Error> = Ok(());
+ let message = match send_args.is_present("message") {
+ true => Some(send_args.value_of("message").unwrap().to_owned()),
+ false => None,
+ };
let tx_file = send_args.value_of("input").ok_or_else(|| {
ErrorKind::GenericError("Transaction file required".to_string())
})?;
@@ -492,7 +505,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
let adapter = FileWalletCommAdapter::new();
let mut slate = adapter.receive_tx_async(tx_file)?;
controller::foreign_single_use(wallet, |api| {
- api.receive_tx(&mut slate, Some(account))?;
+ api.receive_tx(&mut slate, Some(account), message)?;
Ok(())
})?;
let send_tx = format!("{}.response", tx_file);
@@ -515,6 +528,10 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
}
let adapter = FileWalletCommAdapter::new();
let mut slate = adapter.receive_tx_async(tx_file)?;
+ if let Err(e) = api.verify_slate_messages(&slate) {
+ error!("Error validating participant messages: {}", e);
+ return Err(e);
+ }
let _ = api.finalize_tx(&mut slate).expect("Finalize failed");
let result = api.post_tx(&slate.tx, fluff);
diff --git a/src/bin/grin.rs b/src/bin/grin.rs
index e1272a8b3..dd141a551 100644
--- a/src/bin/grin.rs
+++ b/src/bin/grin.rs
@@ -246,15 +246,25 @@ fn real_main() -> i32 {
.arg(Arg::with_name("fluff")
.help("Fluff the transaction (ignore Dandelion relay protocol)")
.short("f")
- .long("fluff")))
+ .long("fluff"))
+ .arg(Arg::with_name("message")
+ .help("Optional participant message to include")
+ .short("g")
+ .long("message")
+ .takes_value(true))
.arg(Arg::with_name("stored_tx")
.help("If present, use the previously stored Unconfirmed transaction with given id.")
.short("t")
.long("stored_tx")
- .takes_value(true))
+ .takes_value(true)))
.subcommand(SubCommand::with_name("receive")
.about("Processes a transaction file to accept a transfer from a sender.")
+ .arg(Arg::with_name("message")
+ .help("Optional participant message to include")
+ .short("g")
+ .long("message")
+ .takes_value(true))
.arg(Arg::with_name("input")
.help("Partial transaction to process, expects the sender's transaction file.")
.short("i")
diff --git a/wallet/src/controller.rs b/wallet/src/controller.rs
index 363966342..d6a4f8d84 100644
--- a/wallet/src/controller.rs
+++ b/wallet/src/controller.rs
@@ -171,7 +171,7 @@ where
}
}
- fn retrieve_outputs(
+ pub fn retrieve_outputs(
&self,
req: &Request
,
api: APIOwner,
@@ -195,7 +195,7 @@ where
api.retrieve_outputs(show_spent, update_from_node, id)
}
- fn retrieve_txs(
+ pub fn retrieve_txs(
&self,
req: &Request,
api: APIOwner,
@@ -222,7 +222,7 @@ where
api.retrieve_txs(update_from_node, tx_id, tx_slate_id)
}
- fn retrieve_stored_tx(
+ pub fn retrieve_stored_tx(
&self,
req: &Request,
api: APIOwner,
@@ -251,7 +251,7 @@ where
}
}
- fn retrieve_summary_info(
+ pub fn retrieve_summary_info(
&self,
req: &Request,
mut api: APIOwner,
@@ -269,7 +269,7 @@ where
api.retrieve_summary_info(update_from_node, minimum_confirmations)
}
- fn node_height(
+ pub fn node_height(
&self,
_req: &Request,
mut api: APIOwner,
@@ -297,7 +297,7 @@ where
})
}
- fn issue_send_tx(
+ pub fn issue_send_tx(
&self,
req: Request,
mut api: APIOwner,
@@ -310,6 +310,7 @@ where
args.max_outputs,
args.num_change_outputs,
args.selection_strategy_is_use_all,
+ args.message,
);
let (mut slate, lock_fn) = match result {
Ok(s) => {
@@ -353,7 +354,7 @@ where
}))
}
- fn finalize_tx(
+ pub fn finalize_tx(
&self,
req: Request,
mut api: APIOwner,
@@ -369,7 +370,7 @@ where
)
}
- fn cancel_tx(
+ pub fn cancel_tx(
&self,
req: Request,
mut api: APIOwner,
@@ -414,7 +415,7 @@ where
}
}
- fn post_tx(
+ pub fn post_tx(
&self,
req: Request,
api: APIOwner,
@@ -548,7 +549,8 @@ where
mut api: APIForeign,
) -> Box + Send> {
Box::new(parse_body(req).and_then(
- move |mut slate| match api.receive_tx(&mut slate, None) {
+ //TODO: No way to insert a message from the params
+ move |mut slate| match api.receive_tx(&mut slate, None, None) {
Ok(_) => ok(slate.clone()),
Err(e) => {
error!("receive_tx: failed with error: {}", e);
diff --git a/wallet/src/libtx/aggsig.rs b/wallet/src/libtx/aggsig.rs
index f00bc6ee6..e87b920bd 100644
--- a/wallet/src/libtx/aggsig.rs
+++ b/wallet/src/libtx/aggsig.rs
@@ -420,6 +420,28 @@ pub fn verify_completed_sig(
Ok(())
}
+/// Adds signatures
+pub fn add_signatures(
+ secp: &Secp256k1,
+ part_sigs: Vec<&Signature>,
+ nonce_sum: &PublicKey,
+) -> Result {
+ // Add public nonces kR*G + kS*G
+ let sig = aggsig::add_signatures_single(&secp, part_sigs, &nonce_sum)?;
+ Ok(sig)
+}
+
+/// Just a simple sig, creates its own nonce, etc
+pub fn sign_single(
+ secp: &Secp256k1,
+ msg: &Message,
+ skey: &SecretKey,
+ pubkey_sum: Option<&PublicKey>,
+) -> Result {
+ let sig = aggsig::sign_single(secp, &msg, skey, None, None, None, pubkey_sum, None)?;
+ Ok(sig)
+}
+
/// Verifies an aggsig signature
pub fn verify_single(
secp: &Secp256k1,
@@ -435,17 +457,6 @@ pub fn verify_single(
)
}
-/// Adds signatures
-pub fn add_signatures(
- secp: &Secp256k1,
- part_sigs: Vec<&Signature>,
- nonce_sum: &PublicKey,
-) -> Result {
- // Add public nonces kR*G + kS*G
- let sig = aggsig::add_signatures_single(&secp, part_sigs, &nonce_sum)?;
- Ok(sig)
-}
-
/// Just a simple sig, creates its own nonce, etc
pub fn sign_with_blinding(
secp: &Secp256k1,
diff --git a/wallet/src/libtx/slate.rs b/wallet/src/libtx/slate.rs
index 6dc5c4095..d5c6f147a 100644
--- a/wallet/src/libtx/slate.rs
+++ b/wallet/src/libtx/slate.rs
@@ -32,6 +32,8 @@ use util::secp::key::{PublicKey, SecretKey};
use util::secp::Signature;
use util::RwLock;
+use blake2::blake2b::blake2b;
+
/// Public data for each participant in the slate
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -44,6 +46,10 @@ pub struct ParticipantData {
pub public_nonce: PublicKey,
/// Public partial signature
pub part_sig: Option,
+ /// A message for other participants
+ pub message: Option,
+ /// Signature, created with private key corresponding to 'public_blind_excess'
+ pub message_sig: Option,
}
impl ParticipantData {
@@ -133,6 +139,7 @@ impl Slate {
sec_key: &mut SecretKey,
sec_nonce: &SecretKey,
participant_id: usize,
+ message: Option,
) -> Result<(), Error>
where
K: Keychain,
@@ -141,7 +148,14 @@ impl Slate {
if self.tx.offset == BlindingFactor::zero() {
self.generate_offset(keychain, sec_key)?;
}
- self.add_participant_info(keychain, &sec_key, &sec_nonce, participant_id, None)?;
+ self.add_participant_info(
+ keychain,
+ &sec_key,
+ &sec_nonce,
+ participant_id,
+ None,
+ message,
+ )?;
Ok(())
}
@@ -234,6 +248,7 @@ impl Slate {
sec_nonce: &SecretKey,
id: usize,
part_sig: Option,
+ message: Option,
) -> Result<(), Error>
where
K: Keychain,
@@ -241,11 +256,24 @@ impl Slate {
// Add our public key and nonce to the slate
let pub_key = PublicKey::from_secret_key(keychain.secp(), &sec_key)?;
let pub_nonce = PublicKey::from_secret_key(keychain.secp(), &sec_nonce)?;
+ // Sign the provided message
+ let message_sig = {
+ if let Some(m) = message.clone() {
+ let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &m.as_bytes()[..]);
+ let m = secp::Message::from_slice(&hashed.as_bytes())?;
+ let res = aggsig::sign_single(&keychain.secp(), &m, &sec_key, None)?;
+ Some(res)
+ } else {
+ None
+ }
+ };
self.participant_data.push(ParticipantData {
id: id as u64,
public_blind_excess: pub_key,
public_nonce: pub_nonce,
part_sig: part_sig,
+ message: message,
+ message_sig: message_sig,
});
Ok(())
@@ -321,6 +349,30 @@ impl Slate {
Ok(())
}
+ /// Verifies any messages in the slate's participant data match their signatures
+ pub fn verify_messages(&self, secp: &secp::Secp256k1) -> Result<(), Error> {
+ for p in self.participant_data.iter() {
+ if let Some(m) = p.message.clone() {
+ let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &m.as_bytes()[..]);
+ let m = secp::Message::from_slice(&hashed.as_bytes())?;
+ if !aggsig::verify_single(
+ secp,
+ &p.message_sig.as_ref().unwrap(),
+ &m,
+ None,
+ &p.public_blind_excess,
+ None,
+ false,
+ ) {
+ return Err(ErrorKind::Signature(
+ "Optional participant messages do not match signatures".to_owned(),
+ ))?;
+ }
+ }
+ }
+ Ok(())
+ }
+
/// This should be callable by either the sender or receiver
/// once phase 3 is done
///
diff --git a/wallet/src/libwallet/api.rs b/wallet/src/libwallet/api.rs
index 8e839157f..94775b059 100644
--- a/wallet/src/libwallet/api.rs
+++ b/wallet/src/libwallet/api.rs
@@ -462,6 +462,7 @@ where
max_outputs: usize,
num_change_outputs: usize,
selection_strategy_is_use_all: bool,
+ message: Option,
) -> Result<(Slate, impl FnOnce(&mut W, &str) -> Result<(), Error>), Error> {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
@@ -485,6 +486,7 @@ where
selection_strategy_is_use_all,
&parent_key_id,
false,
+ message,
)?;
// Save the aggsig context in our DB for when we
@@ -577,6 +579,13 @@ where
}
}
+ /// Verifies all messages in the slate match their public keys
+ pub fn verify_slate_messages(&mut self, slate: &Slate) -> Result<(), Error> {
+ let mut w = self.wallet.lock();
+ slate.verify_messages(w.keychain().secp())?;
+ Ok(())
+ }
+
/// Attempt to restore contents of wallet
pub fn restore(&mut self) -> Result<(), Error> {
let mut w = self.wallet.lock();
@@ -660,6 +669,7 @@ where
&mut self,
slate: &mut Slate,
dest_acct_name: Option<&str>,
+ message: Option,
) -> Result<(), Error> {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
@@ -673,7 +683,7 @@ where
}
None => w.parent_key_id(),
};
- let res = tx::receive_tx(&mut *w, slate, &parent_key_id, false);
+ let res = tx::receive_tx(&mut *w, slate, &parent_key_id, false, message);
w.close()?;
if let Err(e) = res {
diff --git a/wallet/src/libwallet/internal/tx.rs b/wallet/src/libwallet/internal/tx.rs
index deae53479..329ef0612 100644
--- a/wallet/src/libwallet/internal/tx.rs
+++ b/wallet/src/libwallet/internal/tx.rs
@@ -31,6 +31,7 @@ pub fn receive_tx(
slate: &mut Slate,
parent_key_id: &Identifier,
is_self: bool,
+ message: Option,
) -> Result<(), Error>
where
T: WalletBackend,
@@ -51,6 +52,7 @@ where
&mut context.sec_key,
&context.sec_nonce,
1,
+ message,
)?;
// perform partial sig
@@ -73,6 +75,7 @@ pub fn create_send_tx(
selection_strategy_is_use_all: bool,
parent_key_id: &Identifier,
is_self: bool,
+ message: Option,
) -> Result<
(
Slate,
@@ -122,6 +125,7 @@ where
&mut context.sec_key,
&context.sec_nonce,
0,
+ message,
)?;
Ok((slate, context, sender_lock_fn))
diff --git a/wallet/src/libwallet/types.rs b/wallet/src/libwallet/types.rs
index aa050a34e..972865120 100644
--- a/wallet/src/libwallet/types.rs
+++ b/wallet/src/libwallet/types.rs
@@ -700,4 +700,6 @@ pub struct SendTXArgs {
pub num_change_outputs: usize,
/// whether to use all outputs (combine)
pub selection_strategy_is_use_all: bool,
+ /// Optional message, that will be signed
+ pub message: Option,
}
diff --git a/wallet/tests/accounts.rs b/wallet/tests/accounts.rs
index 40c6fce9c..a13a0a64a 100644
--- a/wallet/tests/accounts.rs
+++ b/wallet/tests/accounts.rs
@@ -190,6 +190,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet2", &slate)?;
api.tx_lock_outputs(&slate, lock_fn)?;
diff --git a/wallet/tests/common/testclient.rs b/wallet/tests/common/testclient.rs
index 9a309144d..a47d5aea1 100644
--- a/wallet/tests/common/testclient.rs
+++ b/wallet/tests/common/testclient.rs
@@ -211,7 +211,7 @@ where
let w = dest_wallet.unwrap().1.clone();
let mut slate = serde_json::from_str(&m.body).unwrap();
controller::foreign_single_use(w.clone(), |listener_api| {
- listener_api.receive_tx(&mut slate, None)?;
+ listener_api.receive_tx(&mut slate, None, None)?;
Ok(())
})?;
Ok(WalletProxyMessage {
diff --git a/wallet/tests/file.rs b/wallet/tests/file.rs
index 03c0d6eac..d07f3da29 100644
--- a/wallet/tests/file.rs
+++ b/wallet/tests/file.rs
@@ -97,6 +97,9 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
let send_file = format!("{}/part_tx_1.tx", test_dir);
let receive_file = format!("{}/part_tx_2.tx", test_dir);
+ // test optional message
+ let message = "sender test message, sender test message";
+
// Should have 5 in account1 (5 spendable), 5 in account (2 spendable)
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
@@ -106,13 +109,12 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
// send to send
let (mut slate, lock_fn) = api.initiate_tx(
Some("mining"),
- reward * 2, // amount
- 2, // minimum confirmations
- 500, // max outputs
- 1, // num change outputs
- true, // select all outputs
- //"mining",
- //"listener",
+ reward * 2, // amount
+ 2, // minimum confirmations
+ 500, // max outputs
+ 1, // num change outputs
+ true, // select all outputs
+ Some(message.to_owned()), // optional message
)?;
// output tx file
let file_adapter = FileWalletCommAdapter::new();
@@ -127,11 +129,23 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("account1")?;
}
+ let adapter = FileWalletCommAdapter::new();
+ let mut slate = adapter.receive_tx_async(&send_file)?;
+ let mut naughty_slate = slate.clone();
+ naughty_slate.participant_data[0].message = Some("I changed the message".to_owned());
+
+ // verify messages on slate match
+ wallet::controller::owner_single_use(wallet1.clone(), |api| {
+ api.verify_slate_messages(&slate)?;
+ assert!(api.verify_slate_messages(&naughty_slate).is_err());
+ Ok(())
+ })?;
+
+ let sender2_message = "And this is sender 2's message".to_owned();
+
// wallet 2 receives file, completes, sends file back
wallet::controller::foreign_single_use(wallet2.clone(), |api| {
- let adapter = FileWalletCommAdapter::new();
- let mut slate = adapter.receive_tx_async(&send_file)?;
- api.receive_tx(&mut slate, None)?;
+ api.receive_tx(&mut slate, None, Some(sender2_message))?;
adapter.send_tx_async(&receive_file, &mut slate)?;
Ok(())
})?;
@@ -140,6 +154,7 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let adapter = FileWalletCommAdapter::new();
let mut slate = adapter.receive_tx_async(&receive_file)?;
+ api.verify_slate_messages(&slate)?;
api.finalize_tx(&mut slate)?;
api.post_tx(&slate.tx, false)?;
bh += 1;
diff --git a/wallet/tests/repost.rs b/wallet/tests/repost.rs
index 0647ca0d5..152ea003f 100644
--- a/wallet/tests/repost.rs
+++ b/wallet/tests/repost.rs
@@ -112,6 +112,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
// output tx file
let file_adapter = FileWalletCommAdapter::new();
@@ -132,7 +133,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
let adapter = FileWalletCommAdapter::new();
let mut slate = adapter.receive_tx_async(&send_file)?;
- api.receive_tx(&mut slate, None)?;
+ api.receive_tx(&mut slate, None, None)?;
adapter.send_tx_async(&receive_file, &mut slate)?;
Ok(())
})?;
@@ -207,6 +208,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, lock_fn)?;
diff --git a/wallet/tests/restore.rs b/wallet/tests/restore.rs
index ea782445e..ac94a31b5 100644
--- a/wallet/tests/restore.rs
+++ b/wallet/tests/restore.rs
@@ -236,6 +236,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, lock_fn)?;
@@ -257,6 +258,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet3", &slate_i)?;
sender_api.tx_lock_outputs(&slate, lock_fn)?;
@@ -278,6 +280,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, lock_fn)?;
@@ -305,6 +308,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, lock_fn)?;
diff --git a/wallet/tests/self_send.rs b/wallet/tests/self_send.rs
index 5194fad34..1d9aec3b3 100644
--- a/wallet/tests/self_send.rs
+++ b/wallet/tests/self_send.rs
@@ -99,12 +99,11 @@ fn self_send_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
- //"mining",
- //"listener",
+ None,
)?;
// Send directly to self
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
- api.receive_tx(&mut slate, Some("listener"))?;
+ api.receive_tx(&mut slate, Some("listener"), None)?;
Ok(())
})?;
api.finalize_tx(&mut slate)?;
diff --git a/wallet/tests/transaction.rs b/wallet/tests/transaction.rs
index 30cc39f92..22ad40aaa 100644
--- a/wallet/tests/transaction.rs
+++ b/wallet/tests/transaction.rs
@@ -110,6 +110,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, lock_fn)?;
@@ -244,6 +245,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.finalize_tx(&mut slate)?;
@@ -337,6 +339,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
500, // max outputs
1, // num change outputs
true, // select all outputs
+ None,
)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.finalize_tx(&mut slate)?;