Store XORed wallet seed in-mem (#200)

* experimental xor token work

* rustfmt

* test implementation of build_coinbase_t function

* rustfmt

* add separate foreign_rpc_s interface for secure functions

* rustfmt

* rustfmt

* fix http scheme to allow https as well

* add tokenized owner API, modify all functions to use token

* rustfmt

* fix for api doctests, tests passing up to api crate

* rustfmt

* controller crate compilation

* rustfmt

* controller tests passing and modified some to use masked keychains

* rustfmt

* fix wallet tests

* rustfmt

* build from github

* rustfmt
This commit is contained in:
Yeastplume
2019-08-06 12:50:41 +01:00
committed by GitHub
parent 5cdd412205
commit f8c316a351
38 changed files with 3671 additions and 1250 deletions
+84 -50
View File
@@ -22,6 +22,7 @@ use crate::impls::{create_sender, KeybaseAllChannels, SlateGetter as _, SlateRec
use crate::impls::{PathToSlate, SlatePutter};
use crate::keychain;
use crate::libwallet::{InitTxArgs, IssueInvoiceTxArgs, NodeClient, WalletInst, WalletLCProvider};
use crate::util::secp::key::SecretKey;
use crate::util::{Mutex, ZeroingString};
use crate::{controller, display};
use serde_json as json;
@@ -120,6 +121,7 @@ pub struct ListenArgs {
pub fn listen<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K>>>>,
keychain_mask: Option<SecretKey>,
config: &WalletConfig,
args: &ListenArgs,
g_args: &GlobalArgs,
@@ -132,6 +134,7 @@ where
let res = match args.method.as_str() {
"http" => controller::foreign_listener(
wallet.clone(),
keychain_mask,
&config.api_listen_addr(),
g_args.tls_conf.clone(),
),
@@ -158,6 +161,7 @@ where
pub fn owner_api<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K>>>>,
keychain_mask: Option<SecretKey>,
config: &WalletConfig,
g_args: &GlobalArgs,
) -> Result<(), Error>
@@ -168,6 +172,7 @@ where
{
let res = controller::owner_listener(
wallet,
keychain_mask,
config.owner_api_listen_addr().as_str(),
g_args.node_api_secret.clone(),
g_args.tls_conf.clone(),
@@ -186,6 +191,7 @@ pub struct AccountArgs {
pub fn account<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: AccountArgs,
) -> Result<(), Error>
where
@@ -194,8 +200,8 @@ where
K: keychain::Keychain + 'a,
{
if args.create.is_none() {
let res = controller::owner_single_use(wallet, |api| {
let acct_mappings = api.accounts()?;
let res = controller::owner_single_use(wallet, keychain_mask, |api, m| {
let acct_mappings = api.accounts(m)?;
// give logging thread a moment to catch up
thread::sleep(Duration::from_millis(200));
display::accounts(acct_mappings);
@@ -207,8 +213,8 @@ where
}
} else {
let label = args.create.unwrap();
let res = controller::owner_single_use(wallet, |api| {
api.create_account_path(&label)?;
let res = controller::owner_single_use(wallet, keychain_mask, |api, m| {
api.create_account_path(m, &label)?;
thread::sleep(Duration::from_millis(200));
info!("Account: '{}' Created!", label);
Ok(())
@@ -239,6 +245,7 @@ pub struct SendArgs {
pub fn send<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: SendArgs,
dark_scheme: bool,
) -> Result<(), Error>
@@ -247,7 +254,7 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
if args.estimate_selection_strategies {
let strategies = vec!["smallest", "all"]
.into_iter()
@@ -262,7 +269,7 @@ where
estimate_only: Some(true),
..Default::default()
};
let slate = api.init_send_tx(init_args).unwrap();
let slate = api.init_send_tx(m, init_args).unwrap();
(strategy, slate.amount, slate.fee)
})
.collect();
@@ -280,7 +287,7 @@ where
send_args: None,
..Default::default()
};
let result = api.init_send_tx(init_args);
let result = api.init_send_tx(m, init_args);
let mut slate = match result {
Ok(s) => {
info!(
@@ -300,12 +307,16 @@ where
match args.method.as_str() {
"file" => {
PathToSlate((&args.dest).into()).put_tx(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
return Ok(());
}
"self" => {
api.tx_lock_outputs(&slate, 0)?;
controller::foreign_single_use(wallet, |api| {
api.tx_lock_outputs(m, &slate, 0)?;
let km = match keychain_mask.as_ref() {
None => None,
Some(&m) => Some(m.to_owned()),
};
controller::foreign_single_use(wallet, km, |api| {
slate = api.receive_tx(&slate, Some(&args.dest), None)?;
Ok(())
})?;
@@ -313,16 +324,16 @@ where
method => {
let sender = create_sender(method, &args.dest)?;
slate = sender.send_tx(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
}
}
api.verify_slate_messages(&slate).map_err(|e| {
api.verify_slate_messages(m, &slate).map_err(|e| {
error!("Error validating participant messages: {}", e);
e
})?;
slate = api.finalize_tx(&slate)?;
let result = api.post_tx(&slate.tx, args.fluff);
slate = api.finalize_tx(m, &slate)?;
let result = api.post_tx(m, &slate.tx, args.fluff);
match result {
Ok(_) => {
info!("Tx sent ok",);
@@ -347,6 +358,7 @@ pub struct ReceiveArgs {
pub fn receive<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
g_args: &GlobalArgs,
args: ReceiveArgs,
) -> Result<(), Error>
@@ -356,7 +368,11 @@ where
K: keychain::Keychain + 'a,
{
let mut slate = PathToSlate((&args.input).into()).get_tx()?;
controller::foreign_single_use(wallet, |api| {
let km = match keychain_mask.as_ref() {
None => None,
Some(&m) => Some(m.to_owned()),
};
controller::foreign_single_use(wallet, km, |api| {
if let Err(e) = api.verify_slate_messages(&slate) {
error!("Error validating participant messages: {}", e);
return Err(e);
@@ -380,6 +396,7 @@ pub struct FinalizeArgs {
pub fn finalize<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: FinalizeArgs,
) -> Result<(), Error>
where
@@ -408,7 +425,11 @@ where
};
if is_invoice {
controller::foreign_single_use(wallet.clone(), |api| {
let km = match keychain_mask.as_ref() {
None => None,
Some(&m) => Some(m.to_owned()),
};
controller::foreign_single_use(wallet.clone(), km, |api| {
if let Err(e) = api.verify_slate_messages(&slate) {
error!("Error validating participant messages: {}", e);
return Err(e);
@@ -417,18 +438,18 @@ where
Ok(())
})?;
} else {
controller::owner_single_use(wallet.clone(), |api| {
if let Err(e) = api.verify_slate_messages(&slate) {
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
if let Err(e) = api.verify_slate_messages(m, &slate) {
error!("Error validating participant messages: {}", e);
return Err(e);
}
slate = api.finalize_tx(&mut slate)?;
slate = api.finalize_tx(m, &mut slate)?;
Ok(())
})?;
}
controller::owner_single_use(wallet.clone(), |api| {
let result = api.post_tx(&slate.tx, args.fluff);
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let result = api.post_tx(m, &slate.tx, args.fluff);
match result {
Ok(_) => {
info!("Transaction sent successfully, check the wallet again for confirmation.");
@@ -454,6 +475,7 @@ pub struct IssueInvoiceArgs {
pub fn issue_invoice_tx<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: IssueInvoiceArgs,
) -> Result<(), Error>
where
@@ -461,8 +483,8 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
let slate = api.issue_invoice_tx(args.issue_args)?;
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let slate = api.issue_invoice_tx(m, args.issue_args)?;
let mut tx_file = File::create(args.dest.clone())?;
tx_file.write_all(json::to_string(&slate).unwrap().as_bytes())?;
tx_file.sync_all()?;
@@ -486,6 +508,7 @@ pub struct ProcessInvoiceArgs {
/// Process invoice
pub fn process_invoice<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: ProcessInvoiceArgs,
dark_scheme: bool,
) -> Result<(), Error>
@@ -495,7 +518,7 @@ where
K: keychain::Keychain + 'a,
{
let slate = PathToSlate((&args.input).into()).get_tx()?;
controller::owner_single_use(wallet.clone(), |api| {
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
if args.estimate_selection_strategies {
let strategies = vec!["smallest", "all"]
.into_iter()
@@ -510,7 +533,7 @@ where
estimate_only: Some(true),
..Default::default()
};
let slate = api.init_send_tx(init_args).unwrap();
let slate = api.init_send_tx(m, init_args).unwrap();
(strategy, slate.amount, slate.fee)
})
.collect();
@@ -527,11 +550,11 @@ where
send_args: None,
..Default::default()
};
if let Err(e) = api.verify_slate_messages(&slate) {
if let Err(e) = api.verify_slate_messages(m, &slate) {
error!("Error validating participant messages: {}", e);
return Err(e);
}
let result = api.process_invoice_tx(&slate, init_args);
let result = api.process_invoice_tx(m, &slate, init_args);
let mut slate = match result {
Ok(s) => {
info!(
@@ -552,11 +575,15 @@ where
"file" => {
let slate_putter = PathToSlate((&args.dest).into());
slate_putter.put_tx(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
}
"self" => {
api.tx_lock_outputs(&slate, 0)?;
controller::foreign_single_use(wallet, |api| {
api.tx_lock_outputs(m, &slate, 0)?;
let km = match keychain_mask.as_ref() {
None => None,
Some(&m) => Some(m.to_owned()),
};
controller::foreign_single_use(wallet, km, |api| {
slate = api.finalize_invoice_tx(&slate)?;
Ok(())
})?;
@@ -564,7 +591,7 @@ where
method => {
let sender = create_sender(method, &args.dest)?;
slate = sender.send_tx(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
}
}
}
@@ -579,6 +606,7 @@ pub struct InfoArgs {
pub fn info<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
g_args: &GlobalArgs,
args: InfoArgs,
dark_scheme: bool,
@@ -588,9 +616,9 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let (validated, wallet_info) =
api.retrieve_summary_info(true, args.minimum_confirmations)?;
api.retrieve_summary_info(m, true, args.minimum_confirmations)?;
display::info(&g_args.account, &wallet_info, validated, dark_scheme);
Ok(())
})?;
@@ -599,6 +627,7 @@ where
pub fn outputs<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
g_args: &GlobalArgs,
dark_scheme: bool,
) -> Result<(), Error>
@@ -607,9 +636,9 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
let res = api.node_height()?;
let (validated, outputs) = api.retrieve_outputs(g_args.show_spent, true, None)?;
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let res = api.node_height(m)?;
let (validated, outputs) = api.retrieve_outputs(m, g_args.show_spent, true, None)?;
display::outputs(&g_args.account, res.height, validated, outputs, dark_scheme)?;
Ok(())
})?;
@@ -624,6 +653,7 @@ pub struct TxsArgs {
pub fn txs<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
g_args: &GlobalArgs,
args: TxsArgs,
dark_scheme: bool,
@@ -633,9 +663,9 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
let res = api.node_height()?;
let (validated, txs) = api.retrieve_txs(true, args.id, args.tx_slate_id)?;
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let res = api.node_height(m)?;
let (validated, txs) = api.retrieve_txs(m, true, args.id, args.tx_slate_id)?;
let include_status = !args.id.is_some() && !args.tx_slate_id.is_some();
display::txs(
&g_args.account,
@@ -662,7 +692,7 @@ where
};
if id.is_some() {
let (_, outputs) = api.retrieve_outputs(true, false, id)?;
let (_, outputs) = api.retrieve_outputs(m, true, false, id)?;
display::outputs(&g_args.account, res.height, validated, outputs, dark_scheme)?;
// should only be one here, but just in case
for tx in txs {
@@ -684,6 +714,7 @@ pub struct RepostArgs {
pub fn repost<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: RepostArgs,
) -> Result<(), Error>
where
@@ -691,9 +722,9 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
let (_, txs) = api.retrieve_txs(true, Some(args.id), None)?;
let stored_tx = api.get_stored_tx(&txs[0])?;
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let (_, txs) = api.retrieve_txs(m, true, Some(args.id), None)?;
let stored_tx = api.get_stored_tx(m, &txs[0])?;
if stored_tx.is_none() {
error!(
"Transaction with id {} does not have transaction data. Not reposting.",
@@ -710,7 +741,7 @@ where
);
return Ok(());
}
api.post_tx(&stored_tx.unwrap(), args.fluff)?;
api.post_tx(m, &stored_tx.unwrap(), args.fluff)?;
info!("Reposted transaction at {}", args.id);
return Ok(());
}
@@ -735,6 +766,7 @@ pub struct CancelArgs {
pub fn cancel<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: CancelArgs,
) -> Result<(), Error>
where
@@ -742,8 +774,8 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
let result = api.cancel_tx(args.tx_id, args.tx_slate_id);
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let result = api.cancel_tx(m, args.tx_id, args.tx_slate_id);
match result {
Ok(_) => {
info!("Transaction {} Cancelled", args.tx_id_string);
@@ -760,14 +792,15 @@ where
pub fn restore<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
) -> Result<(), Error>
where
L: WalletLCProvider<'a, C, K>,
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
let result = api.restore();
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
let result = api.restore(m);
match result {
Ok(_) => {
warn!("Wallet restore complete",);
@@ -790,6 +823,7 @@ pub struct CheckArgs {
pub fn check_repair<'a, L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
args: CheckArgs,
) -> Result<(), Error>
where
@@ -797,10 +831,10 @@ where
C: NodeClient + 'a,
K: keychain::Keychain + 'a,
{
controller::owner_single_use(wallet.clone(), |api| {
controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| {
warn!("Starting wallet check...",);
warn!("Updating all wallet outputs, please wait ...",);
let result = api.check_repair(args.delete_unconfirmed);
let result = api.check_repair(m, args.delete_unconfirmed);
match result {
Ok(_) => {
warn!("Wallet check complete",);
+30 -9
View File
@@ -20,6 +20,7 @@ use crate::libwallet::{
Error, ErrorKind, NodeClient, NodeVersionInfo, Slate, WalletInst, WalletLCProvider,
CURRENT_SLATE_VERSION, GRIN_BLOCK_HEADER_VERSION,
};
use crate::util::secp::key::SecretKey;
use crate::util::{to_base64, Mutex};
use failure::ResultExt;
use futures::future::{err, ok};
@@ -73,23 +74,25 @@ fn check_middleware(
/// Instantiate wallet Owner API for a single-use (command line) call
/// Return a function containing a loaded API context to call
pub fn owner_single_use<'a, L, F, C, K>(
lc_provider: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<&SecretKey>,
f: F,
) -> Result<(), Error>
where
L: WalletLCProvider<'a, C, K>,
F: FnOnce(&mut Owner<'a, L, C, K>) -> Result<(), Error>,
F: FnOnce(&mut Owner<'a, L, C, K>, Option<&SecretKey>) -> Result<(), Error>,
C: NodeClient + 'a,
K: Keychain + 'a,
{
f(&mut Owner::new(lc_provider))?;
f(&mut Owner::new(wallet), keychain_mask)?;
Ok(())
}
/// Instantiate wallet Foreign API for a single-use (command line) call
/// Return a function containing a loaded API context to call
pub fn foreign_single_use<'a, L, F, C, K>(
lc_provider: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<SecretKey>,
f: F,
) -> Result<(), Error>
where
@@ -98,14 +101,21 @@ where
C: NodeClient + 'a,
K: Keychain + 'a,
{
f(&mut Foreign::new(lc_provider, Some(check_middleware)))?;
f(&mut Foreign::new(
wallet,
keychain_mask,
Some(check_middleware),
))?;
Ok(())
}
/// Listener version, providing same API but listening for requests on a
/// port and wrapping the calls
/// Note keychain mask is only provided here in case the foreign listener is also being used
/// in the same wallet instance
pub fn owner_listener<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
keychain_mask: Option<SecretKey>,
addr: &str,
api_secret: Option<String>,
tls_config: Option<TLSConfig>,
@@ -136,7 +146,7 @@ where
// If so configured, add the foreign API to the same port
if owner_api_include_foreign.unwrap_or(false) {
warn!("Starting HTTP Foreign API on Owner server at {}.", addr);
let foreign_api_handler_v2 = ForeignAPIHandlerV2::new(wallet);
let foreign_api_handler_v2 = ForeignAPIHandlerV2::new(wallet, keychain_mask);
router
.add_route("/v2/foreign", Arc::new(foreign_api_handler_v2))
.map_err(|_| ErrorKind::GenericError("Router failed to add route".to_string()))?;
@@ -160,6 +170,7 @@ where
/// port and wrapping the calls
pub fn foreign_listener<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
keychain_mask: Option<SecretKey>,
addr: &str,
tls_config: Option<TLSConfig>,
) -> Result<(), Error>
@@ -168,7 +179,7 @@ where
C: NodeClient + 'static,
K: Keychain + 'static,
{
let api_handler_v2 = ForeignAPIHandlerV2::new(wallet);
let api_handler_v2 = ForeignAPIHandlerV2::new(wallet, keychain_mask);
let mut router = Router::new();
@@ -275,6 +286,8 @@ where
{
/// Wallet instance
pub wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
/// Keychain mask
pub keychain_mask: Option<SecretKey>,
}
impl<L, C, K> ForeignAPIHandlerV2<L, C, K>
@@ -286,8 +299,12 @@ where
/// Create a new foreign API handler for GET methods
pub fn new(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
keychain_mask: Option<SecretKey>,
) -> ForeignAPIHandlerV2<L, C, K> {
ForeignAPIHandlerV2 { wallet }
ForeignAPIHandlerV2 {
wallet,
keychain_mask,
}
}
fn call_api(
@@ -309,7 +326,11 @@ where
}
fn handle_post_request(&self, req: Request<Body>) -> WalletResponseFuture {
let api = Foreign::new(self.wallet.clone(), Some(check_middleware));
let api = Foreign::new(
self.wallet.clone(),
self.keychain_mask.clone(),
Some(check_middleware),
);
Box::new(
self.call_api(req, api)
.and_then(|resp| ok(json_response_pretty(&resp))),
+52 -43
View File
@@ -43,20 +43,29 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
if let Err(e) = wallet_proxy.run() {
@@ -69,30 +78,30 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height
// test default accounts exist
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let accounts = api.accounts()?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let accounts = api.accounts(m)?;
assert_eq!(accounts[0].label, "default");
assert_eq!(accounts[0].path, ExtKeychain::derive_key_id(2, 0, 0, 0, 0));
Ok(())
})?;
// add some accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let new_path = api.create_account_path("account1").unwrap();
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let new_path = api.create_account_path(m, "account1").unwrap();
assert_eq!(new_path, ExtKeychain::derive_key_id(2, 1, 0, 0, 0));
let new_path = api.create_account_path("account2").unwrap();
let new_path = api.create_account_path(m, "account2").unwrap();
assert_eq!(new_path, ExtKeychain::derive_key_id(2, 2, 0, 0, 0));
let new_path = api.create_account_path("account3").unwrap();
let new_path = api.create_account_path(m, "account3").unwrap();
assert_eq!(new_path, ExtKeychain::derive_key_id(2, 3, 0, 0, 0));
// trying to add same label again should fail
let res = api.create_account_path("account1");
let res = api.create_account_path(m, "account1");
assert!(res.is_err());
Ok(())
})?;
// add account to wallet 2
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let new_path = api.create_account_path("listener_account").unwrap();
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let new_path = api.create_account_path(m, "listener_account").unwrap();
assert_eq!(new_path, ExtKeychain::derive_key_id(2, 1, 0, 0, 0));
Ok(())
})?;
@@ -109,24 +118,24 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("account1")?;
assert_eq!(w.parent_key_id(), ExtKeychain::derive_key_id(2, 1, 0, 0, 0));
}
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 7, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 7, false);
{
wallet_inst!(wallet1, w);
w.set_parent_key_id_by_name("account2")?;
assert_eq!(w.parent_key_id(), ExtKeychain::derive_key_id(2, 2, 0, 0, 0));
}
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false);
// 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)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, 12);
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, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
assert_eq!(txs.len(), 5);
Ok(())
})?;
@@ -137,17 +146,17 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
let w = lc.wallet_inst()?;
w.set_parent_key_id_by_name("account1")?;
}
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
// check last confirmed height on this account is different from above (should be 0)
let (_, wallet1_info) = api.retrieve_summary_info(false, 1)?;
let (_, wallet1_info) = api.retrieve_summary_info(m, false, 1)?;
assert_eq!(wallet1_info.last_confirmed_height, 0);
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, 12);
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, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
assert_eq!(txs.len(), 7);
Ok(())
})?;
@@ -157,16 +166,16 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
wallet_inst!(wallet1, w);
w.set_parent_key_id_by_name("default")?;
}
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, wallet1_info) = api.retrieve_summary_info(false, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, false, 1)?;
assert_eq!(wallet1_info.last_confirmed_height, 0);
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, 12);
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, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
assert_eq!(txs.len(), 0);
Ok(())
})?;
@@ -177,7 +186,7 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("account1")?;
}
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let args = InitTxArgs {
src_acct_name: None,
amount: reward,
@@ -187,19 +196,19 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let mut slate = api.init_send_tx(args)?;
let mut slate = api.init_send_tx(m, args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate)?;
api.tx_lock_outputs(&slate, 0)?;
slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?;
api.tx_lock_outputs(m, &slate, 0)?;
slate = api.finalize_tx(m, &slate)?;
api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, 13);
let (_, txs) = api.retrieve_txs(true, None, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
assert_eq!(txs.len(), 9);
Ok(())
})?;
@@ -209,23 +218,23 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
wallet_inst!(wallet1, w);
w.set_parent_key_id_by_name("account2")?;
}
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, wallet1_info) = api.retrieve_summary_info(false, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, false, 1)?;
assert_eq!(wallet1_info.last_confirmed_height, 12);
let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?;
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert_eq!(wallet1_info.last_confirmed_height, 13);
let (_, txs) = api.retrieve_txs(true, None, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
println!("{:?}", txs);
assert_eq!(txs.len(), 5);
Ok(())
})?;
// wallet 2 should only have this tx on the listener account
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.last_confirmed_height, 13);
let (_, txs) = api.retrieve_txs(true, None, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
assert_eq!(txs.len(), 1);
Ok(())
})?;
@@ -234,16 +243,16 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
wallet_inst!(wallet2, w);
w.set_parent_key_id_by_name("default")?;
}
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (_, wallet2_info) = api.retrieve_summary_info(false, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (_, wallet2_info) = api.retrieve_summary_info(m, false, 1)?;
assert_eq!(wallet2_info.last_confirmed_height, 0);
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.last_confirmed_height, 13);
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, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
assert_eq!(txs.len(), 0);
Ok(())
})?;
+327 -142
View File
@@ -35,14 +35,14 @@ mod common;
use common::{create_wallet_proxy, setup};
macro_rules! send_to_dest {
($a:expr, $b:expr, $c:expr, $d:expr) => {
test_framework::send_to_dest($a, $b, $c, $d, false)
($a:expr, $m: expr, $b:expr, $c:expr, $d:expr) => {
test_framework::send_to_dest($a, $m, $b, $c, $d, false)
};
}
macro_rules! wallet_info {
($a:expr) => {
test_framework::wallet_info($a)
($a:expr, $m:expr) => {
test_framework::wallet_info($a, $m)
};
}
@@ -59,19 +59,25 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -85,34 +91,35 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
let cm = global::coinbase_maturity() as u64; // assume all testing precedes soft fork height
// add some accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.create_account_path("account_1")?;
api.create_account_path("account_2")?;
api.create_account_path("account_3")?;
api.set_active_account("account_1")?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.create_account_path(m, "account_1")?;
api.create_account_path(m, "account_2")?;
api.create_account_path(m, "account_3")?;
api.set_active_account(m, "account_1")?;
Ok(())
})?;
// add account to wallet 2
wallet::controller::owner_single_use(wallet2.clone(), |api| {
api.create_account_path("account_1")?;
api.set_active_account("account_1")?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
api.create_account_path(m, "account_1")?;
api.set_active_account(m, "account_1")?;
Ok(())
})?;
// Do some mining
let bh = 20u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let _ =
test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false);
// Sanity check contents
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward);
assert_eq!(wallet1_info.amount_currently_spendable, (bh - cm) * reward);
// check tx log as well
let (_, txs) = api.retrieve_txs(true, None, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
let (c, _) = libwallet::TxLogEntry::sum_confirmed(&txs);
assert_eq!(wallet1_info.total, c);
assert_eq!(txs.len(), bh as usize);
@@ -121,8 +128,8 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
// Accidentally delete some outputs
let mut w1_outputs_commits = vec![];
wallet::controller::owner_single_use(wallet1.clone(), |api| {
w1_outputs_commits = api.retrieve_outputs(false, true, None)?.1;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
w1_outputs_commits = api.retrieve_outputs(m, false, true, None)?.1;
Ok(())
})?;
let w1_outputs: Vec<libwallet::OutputData> =
@@ -130,7 +137,7 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
{
wallet_inst!(wallet1, w);
{
let mut batch = w.batch()?;
let mut batch = w.batch(mask1)?;
batch.delete(&w1_outputs[4].key_id, &None)?;
batch.delete(&w1_outputs[10].key_id, &None)?;
let mut accidental_spent = w1_outputs[13].clone();
@@ -141,30 +148,30 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
}
// check we have a problem now
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?;
let (_, txs) = api.retrieve_txs(true, None, None)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
let (c, _) = libwallet::TxLogEntry::sum_confirmed(&txs);
assert!(wallet1_info.total != c);
Ok(())
})?;
// this should restore our missing outputs
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.check_repair(true)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.check_repair(m, true)?;
Ok(())
})?;
// check our outputs match again
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.total, bh * reward);
Ok(())
})?;
// perform a transaction, but don't let it finish
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
// send to send
let args = InitTxArgs {
src_acct_name: None,
@@ -175,30 +182,30 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let slate = api.init_send_tx(args)?;
let slate = api.init_send_tx(m, args)?;
// output tx file
let send_file = format!("{}/part_tx_1.tx", test_dir);
PathToSlate(send_file.into()).put_tx(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
Ok(())
})?;
// check we're all locked
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_info.amount_currently_spendable == 0);
Ok(())
})?;
// unlock/restore
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.check_repair(true)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.check_repair(m, true)?;
Ok(())
})?;
// check spendable amount again
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert_eq!(wallet1_info.amount_currently_spendable, (bh - cm) * reward);
Ok(())
})?;
@@ -221,94 +228,134 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// Create a new wallet test client, and set its queues to communicate with the
// proxy
create_wallet_and_add!(m_client, miner, test_dir, "miner", None, &mut wallet_proxy);
create_wallet_and_add!(
m_client,
miner,
miner_mask_i,
test_dir,
"miner",
None,
&mut wallet_proxy,
false
);
let miner_mask = (&miner_mask_i).as_ref();
// non-mining recipient wallets
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// we'll restore into here
create_wallet_and_add!(
client3,
wallet3,
mask3_i,
test_dir,
"wallet3",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask3 = (&mask3_i).as_ref();
// also restore into here
create_wallet_and_add!(
client4,
wallet4,
mask4_i,
test_dir,
"wallet4",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask4 = (&mask4_i).as_ref();
// Simulate a recover from seed without restore into here
create_wallet_and_add!(
client5,
wallet5,
mask5_i,
test_dir,
"wallet5",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
//simulate a recover from seed without restore into here
let mask5 = (&mask5_i).as_ref();
create_wallet_and_add!(
client6,
wallet6,
mask6_i,
test_dir,
"wallet6",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask6 = (&mask6_i).as_ref();
create_wallet_and_add!(
client7,
wallet7,
mask7_i,
test_dir,
"wallet7",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask7 = (&mask7_i).as_ref();
create_wallet_and_add!(
client8,
wallet8,
mask8_i,
test_dir,
"wallet8",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask8 = (&mask8_i).as_ref();
create_wallet_and_add!(
client9,
wallet9,
mask9_i,
test_dir,
"wallet9",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask9 = (&mask9_i).as_ref();
create_wallet_and_add!(
client10,
wallet10,
mask10_i,
test_dir,
"wallet10",
seed_phrase,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask10 = (&mask10_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -324,38 +371,80 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// Do some mining
let mut bh = 20u64;
let base_amount = consensus::GRIN_BASE;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), bh as usize, false);
let _ = test_framework::award_blocks_to_wallet(
&chain,
miner.clone(),
miner_mask,
bh as usize,
false,
);
// send some funds to wallets 1
send_to_dest!(miner.clone(), m_client.clone(), "wallet1", base_amount * 1)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet1", base_amount * 2)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet1", base_amount * 3)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet1",
base_amount * 1
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet1",
base_amount * 2
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet1",
base_amount * 3
)?;
bh += 3;
// 0) Check repair when all is okay should leave wallet contents alone
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.check_repair(true)?;
let info = wallet_info!(wallet1.clone())?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.check_repair(m, true)?;
let info = wallet_info!(wallet1.clone(), m)?;
assert_eq!(info.amount_currently_spendable, base_amount * 6);
assert_eq!(info.total, base_amount * 6);
Ok(())
})?;
// send some funds to wallet 2
send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 4)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 5)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 6)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet2",
base_amount * 4
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet2",
base_amount * 5
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet2",
base_amount * 6
)?;
bh += 3;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false);
bh += cm as u64;
// confirm balances
let info = wallet_info!(wallet1.clone())?;
let info = wallet_info!(wallet1.clone(), mask1)?;
assert_eq!(info.amount_currently_spendable, base_amount * 6);
assert_eq!(info.total, base_amount * 6);
let info = wallet_info!(wallet2.clone())?;
let info = wallet_info!(wallet2.clone(), mask2)?;
assert_eq!(info.amount_currently_spendable, base_amount * 15);
assert_eq!(info.total, base_amount * 15);
@@ -363,14 +452,14 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// seed + BIP32 path.
// 1) a full restore should recover all of them:
wallet::controller::owner_single_use(wallet3.clone(), |api| {
api.restore()?;
wallet::controller::owner_single_use(wallet3.clone(), mask3, |api, m| {
api.restore(m)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet3.clone(), |api| {
let info = wallet_info!(wallet3.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet3.clone(), mask3, |api, m| {
let info = wallet_info!(wallet3.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 6);
assert_eq!(info.amount_currently_spendable, base_amount * 21);
assert_eq!(info.total, base_amount * 21);
@@ -378,14 +467,14 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
})?;
// 2) check_repair should recover them into a single wallet
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.check_repair(true)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.check_repair(m, true)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let info = wallet_info!(wallet1.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let info = wallet_info!(wallet1.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 6);
assert_eq!(info.amount_currently_spendable, base_amount * 21);
Ok(())
@@ -393,30 +482,48 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// 3) If I recover from seed and start using the wallet without restoring,
// check_repair should restore the older outputs
send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 7)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 8)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 9)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet4",
base_amount * 7
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet4",
base_amount * 8
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet4",
base_amount * 9
)?;
bh += 3;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false);
bh += cm as u64;
wallet::controller::owner_single_use(wallet4.clone(), |api| {
let info = wallet_info!(wallet4.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet4.clone(), mask4, |api, m| {
let info = wallet_info!(wallet4.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 3);
assert_eq!(info.amount_currently_spendable, base_amount * 24);
Ok(())
})?;
wallet::controller::owner_single_use(wallet5.clone(), |api| {
api.restore()?;
wallet::controller::owner_single_use(wallet5.clone(), mask5, |api, m| {
api.restore(m)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet5.clone(), |api| {
let info = wallet_info!(wallet5.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet5.clone(), mask5, |api, m| {
let info = wallet_info!(wallet5.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 9);
assert_eq!(info.amount_currently_spendable, base_amount * (45));
Ok(())
@@ -424,30 +531,54 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// 4) If I recover from seed and start using the wallet without restoring,
// check_repair should restore the older outputs
send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 10)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 11)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 12)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet6",
base_amount * 10
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet6",
base_amount * 11
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet6",
base_amount * 12
)?;
bh += 3;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm as usize, false);
let _ = test_framework::award_blocks_to_wallet(
&chain,
miner.clone(),
miner_mask,
cm as usize,
false,
);
bh += cm as u64;
wallet::controller::owner_single_use(wallet6.clone(), |api| {
let info = wallet_info!(wallet6.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet6.clone(), mask6, |api, m| {
let info = wallet_info!(wallet6.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 3);
assert_eq!(info.amount_currently_spendable, base_amount * 33);
Ok(())
})?;
wallet::controller::owner_single_use(wallet6.clone(), |api| {
api.check_repair(true)?;
wallet::controller::owner_single_use(wallet6.clone(), mask6, |api, m| {
api.check_repair(m, true)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet6.clone(), |api| {
let info = wallet_info!(wallet6.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet6.clone(), mask6, |api, m| {
let info = wallet_info!(wallet6.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 12);
assert_eq!(info.amount_currently_spendable, base_amount * (78));
Ok(())
@@ -456,49 +587,85 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// 5) Start using same seed with a different account, amounts should
// be distinct and restore should return funds from other account
send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 13)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 14)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 15)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet7",
base_amount * 13
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet7",
base_amount * 14
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet7",
base_amount * 15
)?;
bh += 3;
// mix it up a bit
wallet::controller::owner_single_use(wallet7.clone(), |api| {
api.create_account_path("account_1")?;
api.set_active_account("account_1")?;
wallet::controller::owner_single_use(wallet7.clone(), mask7, |api, m| {
api.create_account_path(m, "account_1")?;
api.set_active_account(m, "account_1")?;
Ok(())
})?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 1)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 2)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 3)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet7",
base_amount * 1
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet7",
base_amount * 2
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet7",
base_amount * 3
)?;
bh += 3;
// check balances
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false);
bh += cm as u64;
wallet::controller::owner_single_use(wallet7.clone(), |api| {
let info = wallet_info!(wallet7.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet7.clone(), mask7, |api, m| {
let info = wallet_info!(wallet7.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 3);
assert_eq!(info.amount_currently_spendable, base_amount * 6);
api.set_active_account("default")?;
let info = wallet_info!(wallet7.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
api.set_active_account(m, "default")?;
let info = wallet_info!(wallet7.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 3);
assert_eq!(info.amount_currently_spendable, base_amount * 42);
Ok(())
})?;
wallet::controller::owner_single_use(wallet8.clone(), |api| {
api.restore()?;
let info = wallet_info!(wallet8.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet8.clone(), mask8, |api, m| {
api.restore(m)?;
let info = wallet_info!(wallet8.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 15);
assert_eq!(info.amount_currently_spendable, base_amount * 120);
api.set_active_account("account_1")?;
let info = wallet_info!(wallet8.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
api.set_active_account(m, "account_1")?;
let info = wallet_info!(wallet8.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 3);
assert_eq!(info.amount_currently_spendable, base_amount * 6);
Ok(())
@@ -508,51 +675,69 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er
// ids on account 2 as well, check_repair should get all outputs created
// to now into 2 accounts
wallet::controller::owner_single_use(wallet9.clone(), |api| {
api.create_account_path("account_1")?;
api.set_active_account("account_1")?;
wallet::controller::owner_single_use(wallet9.clone(), mask9, |api, m| {
api.create_account_path(m, "account_1")?;
api.set_active_account(m, "account_1")?;
Ok(())
})?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet9", base_amount * 4)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet9", base_amount * 5)?;
send_to_dest!(miner.clone(), m_client.clone(), "wallet9", base_amount * 6)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet9",
base_amount * 4
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet9",
base_amount * 5
)?;
send_to_dest!(
miner.clone(),
miner_mask,
m_client.clone(),
"wallet9",
base_amount * 6
)?;
bh += 3;
let _bh = bh;
wallet::controller::owner_single_use(wallet9.clone(), |api| {
let info = wallet_info!(wallet9.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet9.clone(), mask9, |api, m| {
let info = wallet_info!(wallet9.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 3);
assert_eq!(info.amount_currently_spendable, base_amount * 15);
api.check_repair(true)?;
let info = wallet_info!(wallet9.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
api.check_repair(m, true)?;
let info = wallet_info!(wallet9.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 6);
assert_eq!(info.amount_currently_spendable, base_amount * 21);
api.set_active_account("default")?;
let info = wallet_info!(wallet9.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
api.set_active_account(m, "default")?;
let info = wallet_info!(wallet9.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 15);
assert_eq!(info.amount_currently_spendable, base_amount * 120);
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false);
// 7) Ensure check_repair creates missing accounts
wallet::controller::owner_single_use(wallet10.clone(), |api| {
api.check_repair(true)?;
api.set_active_account("account_1")?;
let info = wallet_info!(wallet10.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
wallet::controller::owner_single_use(wallet10.clone(), mask10, |api, m| {
api.check_repair(m, true)?;
api.set_active_account(m, "account_1")?;
let info = wallet_info!(wallet10.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 6);
assert_eq!(info.amount_currently_spendable, base_amount * 21);
api.set_active_account("default")?;
let info = wallet_info!(wallet10.clone())?;
let outputs = api.retrieve_outputs(true, false, None)?.1;
api.set_active_account(m, "default")?;
let info = wallet_info!(wallet10.clone(), m)?;
let outputs = api.retrieve_outputs(m, true, false, None)?.1;
assert_eq!(outputs.len(), 15);
assert_eq!(info.amount_currently_spendable, base_amount * 120);
Ok(())
+58 -29
View File
@@ -28,6 +28,7 @@ use impls::test_framework::{LocalWalletClient, WalletProxy};
use impls::{DefaultLCProvider, DefaultWalletImpl};
use std::fs;
use std::sync::Arc;
use util::secp::key::SecretKey;
use util::{Mutex, ZeroingString};
#[macro_export]
@@ -41,20 +42,36 @@ macro_rules! wallet_inst {
#[macro_export]
macro_rules! create_wallet_and_add {
($client:ident, $wallet: ident, $test_dir: expr, $name: expr, $seed_phrase: expr, $proxy: expr) => {
($client:ident, $wallet: ident, $mask: ident, $test_dir: expr, $name: expr, $seed_phrase: expr, $proxy: expr, $create_mask: expr) => {
let $client = LocalWalletClient::new($name, $proxy.tx.clone());
let $wallet =
common::create_local_wallet($test_dir, $name, $seed_phrase.clone(), $client.clone());
$proxy.add_wallet($name, $client.get_send_instance(), $wallet.clone());
let ($wallet, $mask) = common::create_local_wallet(
$test_dir,
$name,
$seed_phrase.clone(),
$client.clone(),
$create_mask,
);
$proxy.add_wallet(
$name,
$client.get_send_instance(),
$wallet.clone(),
$mask.clone(),
);
};
}
#[macro_export]
macro_rules! open_wallet_and_add {
($client:ident, $wallet: ident, $test_dir: expr, $name: expr, $proxy: expr) => {
($client:ident, $wallet: ident, $mask: ident, $test_dir: expr, $name: expr, $proxy: expr, $create_mask: expr) => {
let $client = LocalWalletClient::new($name, $proxy.tx.clone());
let $wallet = common::open_local_wallet($test_dir, $name, $client.clone());
$proxy.add_wallet($name, $client.get_send_instance(), $wallet.clone());
let ($wallet, $mask) =
common::open_local_wallet($test_dir, $name, $client.clone(), $create_mask);
$proxy.add_wallet(
$name,
$client.get_send_instance(),
$wallet.clone(),
$mask.clone(),
);
};
}
pub fn clean_output_dir(test_dir: &str) {
@@ -79,18 +96,22 @@ pub fn create_local_wallet(
name: &str,
mnemonic: Option<ZeroingString>,
client: LocalWalletClient,
) -> Arc<
Mutex<
Box<
WalletInst<
'static,
DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>,
LocalWalletClient,
ExtKeychain,
create_mask: bool,
) -> (
Arc<
Mutex<
Box<
WalletInst<
'static,
DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>,
LocalWalletClient,
ExtKeychain,
>,
>,
>,
>,
> {
Option<SecretKey>,
) {
let mut wallet = Box::new(DefaultWalletImpl::<LocalWalletClient>::new(client).unwrap())
as Box<
WalletInst<
@@ -103,26 +124,32 @@ pub fn create_local_wallet(
lc.set_wallet_directory(&format!("{}/{}", test_dir, name));
lc.create_wallet(None, mnemonic, 32, ZeroingString::from(""))
.unwrap();
lc.open_wallet(None, ZeroingString::from("")).unwrap();
Arc::new(Mutex::new(wallet))
let mask = lc
.open_wallet(None, ZeroingString::from(""), create_mask, false)
.unwrap();
(Arc::new(Mutex::new(wallet)), mask)
}
pub fn open_local_wallet(
test_dir: &str,
name: &str,
client: LocalWalletClient,
) -> Arc<
Mutex<
Box<
WalletInst<
'static,
DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>,
LocalWalletClient,
ExtKeychain,
create_mask: bool,
) -> (
Arc<
Mutex<
Box<
WalletInst<
'static,
DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>,
LocalWalletClient,
ExtKeychain,
>,
>,
>,
>,
> {
Option<SecretKey>,
) {
let mut wallet = Box::new(DefaultWalletImpl::<LocalWalletClient>::new(client).unwrap())
as Box<
WalletInst<
@@ -133,6 +160,8 @@ pub fn open_local_wallet(
>;
let lc = wallet.lc_provider().unwrap();
lc.set_wallet_directory(&format!("{}/{}", test_dir, name));
lc.open_wallet(None, ZeroingString::from("")).unwrap();
Arc::new(Mutex::new(wallet))
let mask = lc
.open_wallet(None, ZeroingString::from(""), create_mask, false)
.unwrap();
(Arc::new(Mutex::new(wallet)), mask)
}
+37 -30
View File
@@ -46,19 +46,25 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -71,16 +77,16 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
let reward = core::consensus::REWARD;
// add some accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.create_account_path("mining")?;
api.create_account_path("listener")?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.create_account_path(m, "mining")?;
api.create_account_path(m, "listener")?;
Ok(())
})?;
// add some accounts
wallet::controller::owner_single_use(wallet2.clone(), |api| {
api.create_account_path("account1")?;
api.create_account_path("account2")?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
api.create_account_path(m, "account1")?;
api.create_account_path(m, "account2")?;
Ok(())
})?;
@@ -90,7 +96,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
w.set_parent_key_id_by_name("mining")?;
}
let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let _ =
test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false);
let send_file = format!("{}/part_tx_1.tx", test_dir);
let receive_file = format!("{}/part_tx_2.tx", test_dir);
@@ -99,8 +106,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
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)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward);
@@ -115,10 +122,10 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
message: Some(message.to_owned()),
..Default::default()
};
let mut slate = api.init_send_tx(args)?;
let mut slate = api.init_send_tx(m, args)?;
// output tx file
PathToSlate((&send_file).into()).put_tx(&mut slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
Ok(())
})?;
@@ -133,37 +140,37 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
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());
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.verify_slate_messages(m, &slate)?;
assert!(api.verify_slate_messages(m, &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| {
wallet::controller::foreign_single_use(wallet2.clone(), mask2_i.clone(), |api| {
slate = api.receive_tx(&slate, None, Some(sender2_message.clone()))?;
PathToSlate((&receive_file).into()).put_tx(&slate)?;
Ok(())
})?;
// wallet 1 finalises and posts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let mut slate = PathToSlate(receive_file.into()).get_tx()?;
api.verify_slate_messages(&slate)?;
slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?;
api.verify_slate_messages(m, &slate)?;
slate = api.finalize_tx(m, &slate)?;
api.post_tx(m, &slate.tx, false)?;
bh += 1;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
// Check total in mining account
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward - reward * 2);
@@ -171,8 +178,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
})?;
// Check total in 'wallet 2' account
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.last_confirmed_height, bh);
assert_eq!(wallet2_info.total, 2 * reward);
@@ -180,8 +187,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
})?;
// Check messages, all participants should have both
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, tx) = api.retrieve_txs(true, None, Some(slate.id))?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, tx) = api.retrieve_txs(m, true, None, Some(slate.id))?;
assert_eq!(
tx[0].clone().messages.unwrap().messages[0].message,
Some(message.to_owned())
@@ -196,8 +203,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro
Ok(())
})?;
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (_, tx) = api.retrieve_txs(true, None, Some(slate.id))?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (_, tx) = api.retrieve_txs(m, true, None, Some(slate.id))?;
assert_eq!(
tx[0].clone().messages.unwrap().messages[0].message,
Some(message.to_owned())
+41 -29
View File
@@ -41,19 +41,25 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
true
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
true
);
let mask2 = (&mask2_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -66,9 +72,9 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
let reward = core::consensus::REWARD;
// add some accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.create_account_path("mining")?;
api.create_account_path("listener")?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.create_account_path(m, "mining")?;
api.create_account_path(m, "listener")?;
Ok(())
})?;
@@ -78,11 +84,17 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("mining")?;
}
let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let _ = test_framework::award_blocks_to_wallet(
&chain,
wallet1.clone(),
mask1,
bh as usize,
false,
);
// Sanity check wallet 1 contents
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward);
@@ -91,17 +103,17 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
let mut slate = Slate::blank(2);
wallet::controller::owner_single_use(wallet2.clone(), |api| {
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
// Wallet 2 inititates an invoice transaction, requesting payment
let args = IssueInvoiceTxArgs {
amount: reward * 2,
..Default::default()
};
slate = api.issue_invoice_tx(args)?;
slate = api.issue_invoice_tx(m, args)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
// Wallet 1 receives the invoice transaction
let args = InitTxArgs {
src_acct_name: None,
@@ -112,32 +124,32 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
slate = api.process_invoice_tx(&slate, args)?;
api.tx_lock_outputs(&slate, 0)?;
slate = api.process_invoice_tx(m, &slate, args)?;
api.tx_lock_outputs(m, &slate, 0)?;
Ok(())
})?;
// wallet 2 finalizes and posts
wallet::controller::foreign_single_use(wallet2.clone(), |api| {
wallet::controller::foreign_single_use(wallet2.clone(), mask2_i.clone(), |api| {
// Wallet 2 receives the invoice transaction
slate = api.finalize_invoice_tx(&slate)?;
Ok(())
})?;
// wallet 1 posts so wallet 2 doesn't get the mined amount
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.post_tx(&slate.tx, false)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
bh += 1;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
// Check transaction log for wallet 2
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (_, wallet2_info) = api.retrieve_summary_info(true, 1)?;
let (refreshed, txs) = api.retrieve_txs(true, None, None)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (_, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
assert!(txs.len() == 1);
println!(
@@ -151,9 +163,9 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
// Check transaction log for wallet 1, ensure only 1 entry
// exists
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?;
let (refreshed, txs) = api.retrieve_txs(true, None, None)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
assert_eq!(txs.len() as u64, bh + 1);
println!(
@@ -164,13 +176,13 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
})?;
// Test self-sending
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
// Wallet 1 inititates an invoice transaction, requesting payment
let args = IssueInvoiceTxArgs {
amount: reward * 2,
..Default::default()
};
slate = api.issue_invoice_tx(args)?;
slate = api.issue_invoice_tx(m, args)?;
// Wallet 1 receives the invoice transaction
let args = InitTxArgs {
src_acct_name: None,
@@ -181,19 +193,19 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
slate = api.process_invoice_tx(&slate, args)?;
api.tx_lock_outputs(&slate, 0)?;
slate = api.process_invoice_tx(m, &slate, args)?;
api.tx_lock_outputs(m, &slate, 0)?;
Ok(())
})?;
// wallet 1 finalizes and posts
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
wallet::controller::foreign_single_use(wallet1.clone(), mask1_i.clone(), |api| {
// Wallet 2 receives the invoice transaction
slate = api.finalize_invoice_tx(&slate)?;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
//bh += 3;
// let logging finish
+47 -40
View File
@@ -43,19 +43,25 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -68,16 +74,16 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
let reward = core::consensus::REWARD;
// add some accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.create_account_path("mining")?;
api.create_account_path("listener")?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.create_account_path(m, "mining")?;
api.create_account_path(m, "listener")?;
Ok(())
})?;
// add some accounts
wallet::controller::owner_single_use(wallet2.clone(), |api| {
api.create_account_path("account1")?;
api.create_account_path("account2")?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
api.create_account_path(m, "account1")?;
api.create_account_path(m, "account2")?;
Ok(())
})?;
@@ -87,7 +93,8 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
w.set_parent_key_id_by_name("mining")?;
}
let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let _ =
test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false);
let send_file = format!("{}/part_tx_1.tx", test_dir);
let receive_file = format!("{}/part_tx_2.tx", test_dir);
@@ -95,8 +102,8 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
let mut slate = Slate::blank(2);
// 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)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward);
@@ -110,13 +117,13 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
selection_strategy_is_use_all: true,
..Default::default()
};
let slate = api.init_send_tx(args)?;
let slate = api.init_send_tx(m, args)?;
PathToSlate((&send_file).into()).put_tx(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
api.tx_lock_outputs(m, &slate, 0)?;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
// wallet 1 receives file to different account, completes
@@ -125,7 +132,7 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
w.set_parent_key_id_by_name("listener")?;
}
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
wallet::controller::foreign_single_use(wallet1.clone(), mask1_i.clone(), |api| {
slate = PathToSlate((&send_file).into()).get_tx()?;
slate = api.receive_tx(&slate, None, None)?;
PathToSlate((&receive_file).into()).put_tx(&slate)?;
@@ -139,27 +146,27 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
}
// wallet 1 finalize
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
slate = PathToSlate((&receive_file).into()).get_tx()?;
slate = api.finalize_tx(&slate)?;
slate = api.finalize_tx(m, &slate)?;
Ok(())
})?;
// Now repost from cached
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, txs) = api.retrieve_txs(true, None, Some(slate.id))?;
let stored_tx = api.get_stored_tx(&txs[0])?;
api.post_tx(&stored_tx.unwrap(), false)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, txs) = api.retrieve_txs(m, true, None, Some(slate.id))?;
let stored_tx = api.get_stored_tx(m, &txs[0])?;
api.post_tx(m, &stored_tx.unwrap(), false)?;
bh += 1;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
// update/test contents of both accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward - reward * 2);
@@ -171,8 +178,8 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
w.set_parent_key_id_by_name("listener")?;
}
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.last_confirmed_height, bh);
assert_eq!(wallet2_info.total, 2 * reward);
@@ -192,7 +199,7 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
let mut slate = Slate::blank(2);
let amount = 60_000_000_000;
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -203,39 +210,39 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&mut slate)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &mut slate)?;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
// Now repost from cached
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (_, txs) = api.retrieve_txs(true, None, Some(slate.id))?;
let stored_tx = api.get_stored_tx(&txs[0])?;
api.post_tx(&stored_tx.unwrap(), false)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, txs) = api.retrieve_txs(m, true, None, Some(slate.id))?;
let stored_tx = api.get_stored_tx(m, &txs[0])?;
api.post_tx(m, &stored_tx.unwrap(), false)?;
bh += 1;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
//
// update/test contents of both accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward - reward * 4);
Ok(())
})?;
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.last_confirmed_height, bh);
assert_eq!(wallet2_info.total, 2 * amount);
+72 -52
View File
@@ -41,10 +41,12 @@ fn restore_wallet(base_dir: &'static str, wallet_dir: &str) -> Result<(), libwal
create_wallet_and_add!(
client,
wallet,
mask,
base_dir,
&dest_wallet_name,
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
// close created wallet
let mut w_lock = wallet.lock();
@@ -59,10 +61,13 @@ fn restore_wallet(base_dir: &'static str, wallet_dir: &str) -> Result<(), libwal
open_wallet_and_add!(
client,
wallet,
mask_i,
&base_dir,
&dest_wallet_name,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask = (&mask_i).as_ref();
// Set the wallet proxy listener running
let wp_running = wallet_proxy.running.clone();
@@ -73,9 +78,9 @@ fn restore_wallet(base_dir: &'static str, wallet_dir: &str) -> Result<(), libwal
});
// perform the restore and update wallet info
wallet::controller::owner_single_use(wallet.clone(), |api| {
let _ = api.restore()?;
let _ = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet.clone(), mask, |api, m| {
let _ = api.restore(m)?;
let _ = api.retrieve_summary_info(m, true, 1)?;
Ok(())
})?;
@@ -96,17 +101,23 @@ fn compare_wallet_restore(
open_wallet_and_add!(
client,
wallet_source,
source_mask_i,
&base_dir,
&wallet_dir,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let source_mask = (&source_mask_i).as_ref();
open_wallet_and_add!(
client,
wallet_dest,
dest_mask_i,
&base_dir,
&restore_name,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let dest_mask = (&dest_mask_i).as_ref();
{
wallet_inst!(wallet_source, w);
@@ -136,17 +147,17 @@ fn compare_wallet_restore(
let mut dest_accts: Option<Vec<AcctPathMapping>> = None;
// 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)?.1);
src_txs = Some(api.retrieve_txs(true, None, None)?.1);
src_accts = Some(api.accounts()?);
wallet::controller::owner_single_use(wallet_source.clone(), source_mask, |api, m| {
src_info = Some(api.retrieve_summary_info(m, true, 1)?.1);
src_txs = Some(api.retrieve_txs(m, true, None, None)?.1);
src_accts = Some(api.accounts(m)?);
Ok(())
})?;
wallet::controller::owner_single_use(wallet_dest.clone(), |api| {
dest_info = Some(api.retrieve_summary_info(true, 1)?.1);
dest_txs = Some(api.retrieve_txs(true, None, None)?.1);
dest_accts = Some(api.accounts()?);
wallet::controller::owner_single_use(wallet_dest.clone(), dest_mask, |api, m| {
dest_info = Some(api.retrieve_summary_info(m, true, 1)?.1);
dest_txs = Some(api.retrieve_txs(m, true, None, None)?.1);
dest_accts = Some(api.accounts(m)?);
Ok(())
})?;
@@ -194,24 +205,30 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// wallet 2 will use another account
wallet::controller::owner_single_use(wallet2.clone(), |api| {
api.create_account_path("account1")?;
api.create_account_path("account2")?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
api.create_account_path(m, "account1")?;
api.create_account_path(m, "account2")?;
Ok(())
})?;
@@ -225,11 +242,14 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client3,
wallet3,
mask3_i,
test_dir,
"wallet3",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask3 = (&mask3_i).as_ref();
// Set the wallet proxy listener running
let wp_running = wallet_proxy.running.clone();
@@ -240,13 +260,13 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
});
// mine a few blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false);
// assert wallet contents
// and a single use api for a send command
let amount = 60_000_000_000;
let mut slate = Slate::blank(1);
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -257,19 +277,19 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
sender_api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
// Send some to wallet 3
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -280,19 +300,19 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client1.send_tx_slate_direct("wallet3", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
sender_api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet3.clone(), 10, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet3.clone(), mask3, 10, false);
// Wallet3 to wallet 2
wallet::controller::owner_single_use(wallet3.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet3.clone(), mask3, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -303,11 +323,11 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
sender_api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
@@ -318,10 +338,10 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
}
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 2, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 2, false);
// Wallet3 to wallet 2 again (to another account)
wallet::controller::owner_single_use(wallet3.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet3.clone(), mask3, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -332,28 +352,28 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
sender_api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false);
// update everyone
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let _ = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let _ = api.retrieve_summary_info(m, true, 1)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let _ = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let _ = api.retrieve_summary_info(m, true, 1)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet3.clone(), |api| {
let _ = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet3.clone(), mask3, |api, m| {
let _ = api.retrieve_summary_info(m, true, 1)?;
Ok(())
})?;
+21 -17
View File
@@ -41,11 +41,14 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
true
);
let mask1 = (&mask1_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -58,9 +61,9 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
let reward = core::consensus::REWARD;
// add some accounts
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.create_account_path("mining")?;
api.create_account_path("listener")?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.create_account_path(m, "mining")?;
api.create_account_path(m, "listener")?;
Ok(())
})?;
@@ -70,11 +73,12 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("mining")?;
}
let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let _ =
test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false);
// 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)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward);
@@ -88,25 +92,25 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
selection_strategy_is_use_all: true,
..Default::default()
};
let mut slate = api.init_send_tx(args)?;
api.tx_lock_outputs(&slate, 0)?;
let mut slate = api.init_send_tx(m, args)?;
api.tx_lock_outputs(m, &slate, 0)?;
// Send directly to self
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
wallet::controller::foreign_single_use(wallet1.clone(), mask1_i.clone(), |api| {
slate = api.receive_tx(&slate, Some("listener"), None)?;
Ok(())
})?;
slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?; // mines a block
slate = api.finalize_tx(m, &slate)?;
api.post_tx(m, &slate.tx, false)?; // mines a block
bh += 1;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
bh += 3;
// Check total in mining account
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, bh * reward - reward * 2);
@@ -118,8 +122,8 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
wallet_inst!(wallet1, w);
w.set_parent_key_id_by_name("listener")?;
}
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet1_refreshed);
assert_eq!(wallet1_info.last_confirmed_height, bh);
assert_eq!(wallet1_info.total, 2 * reward);
+83 -69
View File
@@ -42,19 +42,27 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
true
);
let mask1 = (&mask1_i).as_ref();
println!("Mask1: {:?}", mask1);
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
println!("Mask2: {:?}", mask2);
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -67,11 +75,11 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
let reward = core::consensus::REWARD;
let cm = global::coinbase_maturity();
// mine a few blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false);
// Check wallet 1 contents are as expected
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
debug!(
"Wallet 1 Info Pre-Transaction, after {} blocks: {:?}",
wallet1_info.last_confirmed_height, wallet1_info
@@ -89,7 +97,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
// and a single use api for a send command
let amount = 60_000_000_000;
let mut slate = Slate::blank(1);
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -100,15 +108,15 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
// Check we are creating a tx with the expected lock_height of 0.
// We will check this produces a Plain kernel later.
assert_eq!(0, slate.lock_height);
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
// Check we have a single kernel and that it is a Plain kernel (no lock_height).
assert_eq!(slate.tx.kernels().len(), 1);
@@ -125,9 +133,9 @@ fn basic_transaction_api(test_dir: &'static 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, 1)?;
let (refreshed, txs) = api.retrieve_txs(true, None, None)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
let fee = core::libtx::tx_fee(
wallet1_info.last_confirmed_height as usize - cm as usize,
@@ -148,8 +156,8 @@ fn basic_transaction_api(test_dir: &'static 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, None)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (refreshed, txs) = api.retrieve_txs(m, 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));
@@ -164,14 +172,14 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
})?;
// post transaction
wallet::controller::owner_single_use(wallet1.clone(), |api| {
api.post_tx(&slate.tx, false)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
api.post_tx(m, &slate.tx, false)?;
Ok(())
})?;
// Check wallet 1 contents are as expected
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
debug!(
"Wallet 1 Info Post Transaction, after {} blocks: {:?}",
wallet1_info.last_confirmed_height, wallet1_info
@@ -195,7 +203,7 @@ fn basic_transaction_api(test_dir: &'static 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, None)?;
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id));
assert!(tx.is_some());
@@ -207,11 +215,11 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
})?;
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
// refresh wallets and retrieve info/tests for each wallet after maturity
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
debug!("Wallet 1 Info: {:?}", wallet1_info);
assert!(wallet1_refreshed);
assert_eq!(
@@ -225,13 +233,13 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
Ok(())
})?;
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.amount_currently_spendable, amount);
// check tx log entry is confirmed
let (refreshed, txs) = api.retrieve_txs(true, None, None)?;
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id));
assert!(tx.is_some());
@@ -242,7 +250,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
})?;
// Estimate fee and locked amount for a transaction
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
let init_args = InitTxArgs {
src_acct_name: None,
amount: amount * 2,
@@ -253,7 +261,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
estimate_only: Some(true),
..Default::default()
};
let est = sender_api.init_send_tx(init_args)?;
let est = sender_api.init_send_tx(m, init_args)?;
assert_eq!(est.amount, 600_000_000_000);
assert_eq!(est.fee, 4_000_000);
@@ -267,7 +275,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
estimate_only: Some(true),
..Default::default()
};
let est = sender_api.init_send_tx(init_args)?;
let est = sender_api.init_send_tx(m, init_args)?;
assert_eq!(est.amount, 180_000_000_000);
assert_eq!(est.fee, 6_000_000);
@@ -276,7 +284,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
// Send another transaction, but don't post to chain immediately and use
// the stored transaction instead
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -287,25 +295,25 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
selection_strategy_is_use_all: true,
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
Ok(())
})?;
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
let (refreshed, _wallet1_info) = sender_api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
let (refreshed, _wallet1_info) = sender_api.retrieve_summary_info(m, true, 1)?;
assert!(refreshed);
let (_, txs) = sender_api.retrieve_txs(true, None, None)?;
let (_, txs) = sender_api.retrieve_txs(m, true, None, None)?;
// find the transaction
let tx = txs
.iter()
.find(|t| t.tx_slate_id == Some(slate.id))
.unwrap();
let stored_tx = sender_api.get_stored_tx(&tx)?;
sender_api.post_tx(&stored_tx.unwrap(), false)?;
let (_, wallet1_info) = sender_api.retrieve_summary_info(true, 1)?;
let stored_tx = sender_api.get_stored_tx(m, &tx)?;
sender_api.post_tx(m, &stored_tx.unwrap(), false)?;
let (_, wallet1_info) = sender_api.retrieve_summary_info(m, true, 1)?;
// should be mined now
assert_eq!(
wallet1_info.total,
@@ -315,16 +323,16 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error>
})?;
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
// check wallet2 has stored transaction
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(wallet2_refreshed);
assert_eq!(wallet2_info.amount_currently_spendable, amount * 3);
// check tx log entry is confirmed
let (refreshed, txs) = api.retrieve_txs(true, None, None)?;
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id));
assert!(tx.is_some());
@@ -350,19 +358,25 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> {
create_wallet_and_add!(
client1,
wallet1,
mask1_i,
test_dir,
"wallet1",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask1 = (&mask1_i).as_ref();
create_wallet_and_add!(
client2,
wallet2,
mask2_i,
test_dir,
"wallet2",
None,
&mut wallet_proxy
&mut wallet_proxy,
false
);
let mask2 = (&mask2_i).as_ref();
// Set the wallet proxy listener running
thread::spawn(move || {
@@ -375,11 +389,11 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> {
let reward = core::consensus::REWARD;
let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height
// mine a few blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false);
let amount = 30_000_000_000;
let mut slate = Slate::blank(1);
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| {
// note this will increment the block count as part of the transaction "Posting"
let args = InitTxArgs {
src_acct_name: None,
@@ -391,29 +405,29 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> {
..Default::default()
};
let slate_i = sender_api.init_send_tx(args)?;
let slate_i = sender_api.init_send_tx(m, args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.tx_lock_outputs(m, &slate, 0)?;
slate = sender_api.finalize_tx(m, &slate)?;
Ok(())
})?;
// Check transaction log for wallet 1
wallet::controller::owner_single_use(wallet1.clone(), |api| {
let (refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
let (refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
println!(
"last confirmed height: {}",
wallet1_info.last_confirmed_height
);
assert!(refreshed);
let (_, txs) = api.retrieve_txs(true, None, None)?;
let (_, txs) = api.retrieve_txs(m, 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());
let mut locked_count = 0;
let mut unconfirmed_count = 0;
// get the tx entry, check outputs are as expected
let (_, output_mappings) = api.retrieve_outputs(true, false, Some(tx.unwrap().id))?;
let (_, output_mappings) = api.retrieve_outputs(m, true, false, Some(tx.unwrap().id))?;
for m in output_mappings.clone() {
if m.output.status == OutputStatus::Locked {
locked_count = locked_count + 1;
@@ -430,14 +444,14 @@ fn tx_rollback(test_dir: &'static 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, None)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?;
assert!(refreshed);
let mut unconfirmed_count = 0;
let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id));
assert!(tx.is_some());
// get the tx entry, check outputs are as expected
let (_, outputs) = api.retrieve_outputs(true, false, Some(tx.unwrap().id))?;
let (_, outputs) = api.retrieve_outputs(m, true, false, Some(tx.unwrap().id))?;
for m in outputs.clone() {
if m.output.status == OutputStatus::Unconfirmed {
unconfirmed_count = unconfirmed_count + 1;
@@ -445,7 +459,7 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> {
}
assert_eq!(outputs.len(), 1);
assert_eq!(unconfirmed_count, 1);
let (refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
let (refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(refreshed);
assert_eq!(wallet2_info.amount_currently_spendable, 0,);
assert_eq!(wallet2_info.amount_awaiting_finalization, amount);
@@ -454,20 +468,20 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> {
// wallet 1 is bold and doesn't ever post the transaction
// mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false);
// Wallet 1 decides to roll back instead
wallet::controller::owner_single_use(wallet1.clone(), |api| {
wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| {
// can't roll back coinbase
let res = api.cancel_tx(Some(1), None);
let res = api.cancel_tx(m, Some(1), None);
assert!(res.is_err());
let (_, txs) = api.retrieve_txs(true, None, None)?;
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
let tx = txs
.iter()
.find(|t| t.tx_slate_id == Some(slate.id))
.unwrap();
api.cancel_tx(Some(tx.id), None)?;
let (refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?;
api.cancel_tx(m, Some(tx.id), None)?;
let (refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
assert!(refreshed);
println!(
"last confirmed height: {}",
@@ -480,27 +494,27 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> {
(wallet1_info.last_confirmed_height - cm) * reward
);
// can't roll back again
let res = api.cancel_tx(Some(tx.id), None);
let res = api.cancel_tx(m, Some(tx.id), None);
assert!(res.is_err());
Ok(())
})?;
// Wallet 2 rolls back
wallet::controller::owner_single_use(wallet2.clone(), |api| {
let (_, txs) = api.retrieve_txs(true, None, None)?;
wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| {
let (_, txs) = api.retrieve_txs(m, true, None, None)?;
let tx = txs
.iter()
.find(|t| t.tx_slate_id == Some(slate.id))
.unwrap();
api.cancel_tx(Some(tx.id), None)?;
let (refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?;
api.cancel_tx(m, Some(tx.id), None)?;
let (refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?;
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(Some(tx.id), None);
let res = api.cancel_tx(m, Some(tx.id), None);
assert!(res.is_err());
Ok(())