mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 15:21:39 +02:00
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release * Merge master into milestone/2.1.0 (#182) * Derive --version output dynamically from cargo package version (#174) * add --txid to the `wallet txs` command (#176) * add --txid to the `wallet txs` command * add test for `wallet txs` command with `--txid` parameter * Refactor - Split WalletCommAdapter into multiple traits (#180) * Derive --version output dynamically from cargo package version (#174) * add server auth argument to http client * Revert "add server auth argument to http client" This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee. * modify WalletCommAdapter, moving dest argument into fields on implementors, visiting havok on automated tests, at least one of which is now out of date and failing * Split WalletCommAdapter into four traits, one for each of its intended behaviors. * Remove two vestigals 1. args, a stringly typed argument to put_tx 2. NullAdapter, which is no longer used * Remove unused "params" argument from listen method. * Re-add previously existing TODO comment * Fix non-test build * completely Fix non-test build * Full Lifecycle API Support (#184) * refactoring wallet lib traits * rustfmt * rustfmt * add new files * explicit lifetime specifiers on all wallet traits * rustfmt * modify apis to use new walletinst * rustfmt * converting controller crate * rustfmt * controller crate compiling * rustfmt * compilation * rustfmt * Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl * rustfmt * full compilation, changing recovery + init to new model * rustfmt * wallet initialisation working, init command output and flow identical to v2.0.0 wallet * rustfmt * fix listener and owner api startup * rustfmt * rustfmt * move encryption test * rustfmt * fix api doctests * rustfmt * fix for most tests in controller crate * rustfmt * fix for check tests in controller crate * fix main wallet tests * rustfmt * add explicit functions to handle mnemonic recovery, fix CLI recovery workflow * rustfmt * update keybase adapter to use new wallet format * rustfmt * test fix * remove debug output
This commit is contained in:
+5
-5
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "grin_wallet_api"
|
||||
version = "2.0.1-beta.1"
|
||||
version = "2.1.0-beta.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
description = "Grin Wallet API"
|
||||
license = "Apache-2.0"
|
||||
@@ -18,10 +18,10 @@ serde_json = "1"
|
||||
easy-jsonrpc = "0.5.1"
|
||||
chrono = { version = "0.4.4", features = ["serde"] }
|
||||
|
||||
grin_wallet_libwallet = { path = "../libwallet", version = "2.0.1-beta.1" }
|
||||
grin_wallet_config = { path = "../config", version = "2.0.1-beta.1" }
|
||||
grin_wallet_impls = { path = "../impls", version = "2.0.1-beta.1" }
|
||||
grin_wallet_util = { path = "../util", version = "2.0.1-beta.1" }
|
||||
grin_wallet_libwallet = { path = "../libwallet", version = "2.1.0-beta.1" }
|
||||
grin_wallet_config = { path = "../config", version = "2.1.0-beta.1" }
|
||||
grin_wallet_impls = { path = "../impls", version = "2.1.0-beta.1" }
|
||||
grin_wallet_util = { path = "../util", version = "2.1.0-beta.1" }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1"
|
||||
|
||||
+74
-53
@@ -17,10 +17,10 @@
|
||||
use crate::keychain::Keychain;
|
||||
use crate::libwallet::api_impl::foreign;
|
||||
use crate::libwallet::{
|
||||
BlockFees, CbData, Error, NodeClient, NodeVersionInfo, Slate, VersionInfo, WalletBackend,
|
||||
BlockFees, CbData, Error, NodeClient, NodeVersionInfo, Slate, VersionInfo, WalletInst,
|
||||
WalletLCProvider,
|
||||
};
|
||||
use crate::util::Mutex;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// ForeignAPI Middleware Check callback
|
||||
@@ -55,30 +55,25 @@ pub enum ForeignCheckMiddlewareFn {
|
||||
/// its operation, then 'close' the wallet (unloading references to the keychain and master
|
||||
/// seed).
|
||||
|
||||
pub struct Foreign<W: ?Sized, C, K>
|
||||
pub struct Foreign<'a, L, C, K>
|
||||
where
|
||||
W: WalletBackend<C, K>,
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
L: WalletLCProvider<'a, C, K>,
|
||||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
||||
/// perhaps)
|
||||
pub wallet: Arc<Mutex<W>>,
|
||||
/// Wallet instance
|
||||
pub wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
|
||||
/// Flag to normalize some output during testing. Can mostly be ignored.
|
||||
pub doctest_mode: bool,
|
||||
/// phantom
|
||||
phantom: PhantomData<K>,
|
||||
/// phantom
|
||||
phantom_c: PhantomData<C>,
|
||||
/// foreign check middleware
|
||||
middleware: Option<ForeignCheckMiddleware>,
|
||||
}
|
||||
|
||||
impl<'a, W: ?Sized, C, K> Foreign<W, C, K>
|
||||
impl<'a, L, C, K> Foreign<'a, L, C, K>
|
||||
where
|
||||
W: WalletBackend<C, K>,
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
L: WalletLCProvider<'a, C, K>,
|
||||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
/// Create a new API instance with the given wallet instance. All subsequent
|
||||
/// API calls will operate on this instance of the wallet.
|
||||
@@ -110,12 +105,12 @@ where
|
||||
/// use tempfile::tempdir;
|
||||
///
|
||||
/// use std::sync::Arc;
|
||||
/// use util::Mutex;
|
||||
/// use util::{Mutex, ZeroingString};
|
||||
///
|
||||
/// use api::Foreign;
|
||||
/// use config::WalletConfig;
|
||||
/// use impls::{HTTPNodeClient, LMDBBackend};
|
||||
/// use libwallet::WalletBackend;
|
||||
/// use impls::{DefaultWalletImpl, DefaultLCProvider, HTTPNodeClient};
|
||||
/// use libwallet::WalletInst;
|
||||
///
|
||||
/// let mut wallet_config = WalletConfig::default();
|
||||
/// # let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
|
||||
@@ -128,24 +123,42 @@ where
|
||||
///
|
||||
/// // A NodeClient must first be created to handle communication between
|
||||
/// // the wallet and the node.
|
||||
///
|
||||
/// let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// Arc::new(Mutex::new(
|
||||
/// LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
|
||||
/// ));
|
||||
///
|
||||
/// // impls::DefaultWalletImpl is provided for convenience in instantiating the wallet
|
||||
/// // It contains the LMDBBackend, DefaultLCProvider (lifecycle) and ExtKeychain used
|
||||
/// // by the reference wallet implementation.
|
||||
/// // These traits can be replaced with alternative implementations if desired
|
||||
///
|
||||
/// let mut wallet = Box::new(DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap())
|
||||
/// as Box<WalletInst<'static, DefaultLCProvider<HTTPNodeClient, ExtKeychain>, HTTPNodeClient, ExtKeychain>>;
|
||||
///
|
||||
/// // Wallet LifeCycle Provider provides all functions init wallet and work with seeds, etc...
|
||||
/// let lc = wallet.lc_provider().unwrap();
|
||||
///
|
||||
/// // The top level wallet directory should be set manually (in the reference implementation,
|
||||
/// // this is provided in the WalletConfig)
|
||||
/// lc.set_wallet_directory(&wallet_config.data_file_dir);
|
||||
///
|
||||
/// // Wallet must be opened with the password (TBD)
|
||||
/// let pw = ZeroingString::from("wallet_password");
|
||||
/// lc.open_wallet(None, pw);
|
||||
///
|
||||
/// // All wallet functions operate on an Arc::Mutex to allow multithreading where needed
|
||||
/// let mut wallet = Arc::new(Mutex::new(wallet));
|
||||
///
|
||||
/// let api_foreign = Foreign::new(wallet.clone(), None);
|
||||
/// // .. perform wallet operations
|
||||
///
|
||||
/// ```
|
||||
|
||||
pub fn new(wallet_in: Arc<Mutex<W>>, middleware: Option<ForeignCheckMiddleware>) -> Self {
|
||||
pub fn new(
|
||||
wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
|
||||
middleware: Option<ForeignCheckMiddleware>,
|
||||
) -> Self {
|
||||
Foreign {
|
||||
wallet: wallet_in,
|
||||
wallet_inst,
|
||||
doctest_mode: false,
|
||||
phantom: PhantomData,
|
||||
phantom_c: PhantomData,
|
||||
middleware,
|
||||
}
|
||||
}
|
||||
@@ -168,7 +181,8 @@ where
|
||||
|
||||
pub fn check_version(&self) -> Result<VersionInfo, Error> {
|
||||
if let Some(m) = self.middleware.as_ref() {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
m(
|
||||
ForeignCheckMiddlewareFn::CheckVersion,
|
||||
w.w2n_client().get_version_info(),
|
||||
@@ -229,7 +243,8 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn build_coinbase(&self, block_fees: &BlockFees) -> Result<CbData, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
if let Some(m) = self.middleware.as_ref() {
|
||||
m(
|
||||
ForeignCheckMiddlewareFn::BuildCoinbase,
|
||||
@@ -237,10 +252,7 @@ where
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
w.open_with_credentials()?;
|
||||
let res = foreign::build_coinbase(&mut *w, block_fees, self.doctest_mode);
|
||||
w.close()?;
|
||||
res
|
||||
foreign::build_coinbase(&mut **w, block_fees, self.doctest_mode)
|
||||
}
|
||||
|
||||
/// Verifies all messages in the slate match their public keys.
|
||||
@@ -283,7 +295,8 @@ where
|
||||
|
||||
pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error> {
|
||||
if let Some(m) = self.middleware.as_ref() {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
m(
|
||||
ForeignCheckMiddlewareFn::VerifySlateMessages,
|
||||
w.w2n_client().get_version_info(),
|
||||
@@ -355,7 +368,8 @@ where
|
||||
dest_acct_name: Option<&str>,
|
||||
message: Option<String>,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
if let Some(m) = self.middleware.as_ref() {
|
||||
m(
|
||||
ForeignCheckMiddlewareFn::ReceiveTx,
|
||||
@@ -363,10 +377,7 @@ where
|
||||
Some(slate),
|
||||
)?;
|
||||
}
|
||||
w.open_with_credentials()?;
|
||||
let res = foreign::receive_tx(&mut *w, slate, dest_acct_name, message, self.doctest_mode);
|
||||
w.close()?;
|
||||
res
|
||||
foreign::receive_tx(&mut **w, slate, dest_acct_name, message, self.doctest_mode)
|
||||
}
|
||||
|
||||
/// Finalizes an invoice transaction initiated by this wallet's Owner api.
|
||||
@@ -417,7 +428,8 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn finalize_invoice_tx(&self, slate: &Slate) -> Result<Slate, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
if let Some(m) = self.middleware.as_ref() {
|
||||
m(
|
||||
ForeignCheckMiddlewareFn::FinalizeInvoiceTx,
|
||||
@@ -425,10 +437,7 @@ where
|
||||
Some(slate),
|
||||
)?;
|
||||
}
|
||||
w.open_with_credentials()?;
|
||||
let res = foreign::finalize_invoice_tx(&mut *w, slate);
|
||||
w.close()?;
|
||||
res
|
||||
foreign::finalize_invoice_tx(&mut **w, slate)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,12 +456,12 @@ macro_rules! doctest_helper_setup_doc_env_foreign {
|
||||
use tempfile::tempdir;
|
||||
|
||||
use std::sync::Arc;
|
||||
use util::Mutex;
|
||||
use util::{Mutex, ZeroingString};
|
||||
|
||||
use api::{Foreign, Owner};
|
||||
use config::WalletConfig;
|
||||
use impls::{HTTPNodeClient, LMDBBackend, WalletSeed};
|
||||
use libwallet::{BlockFees, IssueInvoiceTxArgs, Slate, WalletBackend};
|
||||
use impls::{DefaultLCProvider, DefaultWalletImpl, HTTPNodeClient};
|
||||
use libwallet::{BlockFees, IssueInvoiceTxArgs, Slate, WalletInst};
|
||||
|
||||
let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
|
||||
let dir = dir
|
||||
@@ -462,11 +471,23 @@ macro_rules! doctest_helper_setup_doc_env_foreign {
|
||||
.unwrap();
|
||||
let mut wallet_config = WalletConfig::default();
|
||||
wallet_config.data_file_dir = dir.to_owned();
|
||||
let pw = "";
|
||||
let pw = ZeroingString::from("");
|
||||
|
||||
let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
let mut $wallet: Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> = Arc::new(
|
||||
Mutex::new(LMDBBackend::new(wallet_config.clone(), pw, node_client).unwrap()),
|
||||
);
|
||||
let mut wallet = Box::new(
|
||||
DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap(),
|
||||
)
|
||||
as Box<
|
||||
WalletInst<
|
||||
'static,
|
||||
DefaultLCProvider<HTTPNodeClient, ExtKeychain>,
|
||||
HTTPNodeClient,
|
||||
ExtKeychain,
|
||||
>,
|
||||
>;
|
||||
let lc = wallet.lc_provider().unwrap();
|
||||
lc.set_wallet_directory(&wallet_config.data_file_dir);
|
||||
lc.open_wallet(None, pw);
|
||||
let mut $wallet = Arc::new(Mutex::new(wallet));
|
||||
};
|
||||
}
|
||||
|
||||
+70
-36
@@ -17,7 +17,7 @@
|
||||
use crate::keychain::Keychain;
|
||||
use crate::libwallet::{
|
||||
self, BlockFees, CbData, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
|
||||
NodeVersionInfo, Slate, VersionInfo, VersionedSlate, WalletBackend,
|
||||
NodeVersionInfo, Slate, VersionInfo, VersionedSlate, WalletLCProvider,
|
||||
};
|
||||
use crate::{Foreign, ForeignCheckMiddlewareFn};
|
||||
use easy_jsonrpc;
|
||||
@@ -515,11 +515,11 @@ pub trait ForeignRpc {
|
||||
fn finalize_invoice_tx(&self, slate: &Slate) -> Result<Slate, ErrorKind>;
|
||||
}
|
||||
|
||||
impl<W: ?Sized, C, K> ForeignRpc for Foreign<W, C, K>
|
||||
impl<'a, L, C, K> ForeignRpc for Foreign<'a, L, C, K>
|
||||
where
|
||||
W: WalletBackend<C, K>,
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
L: WalletLCProvider<'a, C, K>,
|
||||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
fn check_version(&self) -> Result<VersionInfo, ErrorKind> {
|
||||
Foreign::check_version(self).map_err(|e| e.kind())
|
||||
@@ -577,13 +577,17 @@ pub fn run_doctest_foreign(
|
||||
) -> Result<Option<serde_json::Value>, String> {
|
||||
use easy_jsonrpc::Handler;
|
||||
use grin_wallet_impls::test_framework::{self, LocalWalletClient, WalletProxy};
|
||||
use grin_wallet_libwallet::api_impl;
|
||||
use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl};
|
||||
use grin_wallet_libwallet::{api_impl, WalletInst};
|
||||
use grin_wallet_util::grin_keychain::ExtKeychain;
|
||||
|
||||
use crate::core::global;
|
||||
use crate::core::global::ChainTypes;
|
||||
use grin_wallet_util::grin_util as util;
|
||||
|
||||
use std::sync::Arc;
|
||||
use util::Mutex;
|
||||
|
||||
use std::fs;
|
||||
use std::thread;
|
||||
|
||||
@@ -591,29 +595,60 @@ pub fn run_doctest_foreign(
|
||||
let _ = fs::remove_dir_all(test_dir);
|
||||
global::set_mining_mode(ChainTypes::AutomatedTesting);
|
||||
|
||||
let mut wallet_proxy: WalletProxy<LocalWalletClient, ExtKeychain> = WalletProxy::new(test_dir);
|
||||
let mut wallet_proxy: WalletProxy<
|
||||
DefaultLCProvider<LocalWalletClient, ExtKeychain>,
|
||||
LocalWalletClient,
|
||||
ExtKeychain,
|
||||
> = WalletProxy::new(test_dir);
|
||||
let chain = wallet_proxy.chain.clone();
|
||||
|
||||
let rec_phrase_1 =
|
||||
let rec_phrase_1 = util::ZeroingString::from(
|
||||
"fat twenty mean degree forget shell check candy immense awful \
|
||||
flame next during february bulb bike sun wink theory day kiwi embrace peace lunch";
|
||||
let client1 = LocalWalletClient::new("wallet1", wallet_proxy.tx.clone());
|
||||
let wallet1 = test_framework::create_wallet(
|
||||
&format!("{}/wallet1", test_dir),
|
||||
client1.clone(),
|
||||
Some(rec_phrase_1),
|
||||
flame next during february bulb bike sun wink theory day kiwi embrace peace lunch",
|
||||
);
|
||||
let empty_string = util::ZeroingString::from("");
|
||||
let client1 = LocalWalletClient::new("wallet1", wallet_proxy.tx.clone());
|
||||
let mut wallet1 =
|
||||
Box::new(DefaultWalletImpl::<LocalWalletClient>::new(client1.clone()).unwrap())
|
||||
as Box<
|
||||
WalletInst<
|
||||
'static,
|
||||
DefaultLCProvider<LocalWalletClient, ExtKeychain>,
|
||||
LocalWalletClient,
|
||||
ExtKeychain,
|
||||
>,
|
||||
>;
|
||||
let lc = wallet1.lc_provider().unwrap();
|
||||
lc.set_wallet_directory(&format!("{}/wallet1", test_dir));
|
||||
lc.create_wallet(None, Some(rec_phrase_1), 32, empty_string.clone())
|
||||
.unwrap();
|
||||
lc.open_wallet(None, empty_string.clone()).unwrap();
|
||||
let wallet1 = Arc::new(Mutex::new(wallet1));
|
||||
|
||||
wallet_proxy.add_wallet("wallet1", client1.get_send_instance(), wallet1.clone());
|
||||
|
||||
let rec_phrase_2 =
|
||||
let rec_phrase_2 = util::ZeroingString::from(
|
||||
"hour kingdom ripple lunch razor inquiry coyote clay stamp mean \
|
||||
sell finish magic kid tiny wage stand panther inside settle feed song hole exile";
|
||||
let client2 = LocalWalletClient::new("wallet2", wallet_proxy.tx.clone());
|
||||
let wallet2 = test_framework::create_wallet(
|
||||
&format!("{}/wallet2", test_dir),
|
||||
client2.clone(),
|
||||
Some(rec_phrase_2),
|
||||
sell finish magic kid tiny wage stand panther inside settle feed song hole exile",
|
||||
);
|
||||
let client2 = LocalWalletClient::new("wallet2", wallet_proxy.tx.clone());
|
||||
let mut wallet2 =
|
||||
Box::new(DefaultWalletImpl::<LocalWalletClient>::new(client2.clone()).unwrap())
|
||||
as Box<
|
||||
WalletInst<
|
||||
'static,
|
||||
DefaultLCProvider<LocalWalletClient, ExtKeychain>,
|
||||
LocalWalletClient,
|
||||
ExtKeychain,
|
||||
>,
|
||||
>;
|
||||
let lc = wallet2.lc_provider().unwrap();
|
||||
lc.set_wallet_directory(&format!("{}/wallet2", test_dir));
|
||||
lc.create_wallet(None, Some(rec_phrase_2), 32, empty_string.clone())
|
||||
.unwrap();
|
||||
lc.open_wallet(None, empty_string.clone()).unwrap();
|
||||
let wallet2 = Arc::new(Mutex::new(wallet2));
|
||||
|
||||
wallet_proxy.add_wallet("wallet2", client2.get_send_instance(), wallet2.clone());
|
||||
|
||||
// Set the wallet proxy listener running
|
||||
@@ -627,28 +662,27 @@ pub fn run_doctest_foreign(
|
||||
for _ in 0..blocks_to_mine {
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 1 as usize, false);
|
||||
//update local outputs after each block, so transaction IDs stay consistent
|
||||
let mut w = wallet1.lock();
|
||||
w.open_with_credentials().unwrap();
|
||||
let mut w_lock = wallet1.lock();
|
||||
let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
let (wallet_refreshed, _) =
|
||||
api_impl::owner::retrieve_summary_info(&mut *w, true, 1).unwrap();
|
||||
api_impl::owner::retrieve_summary_info(&mut **w, true, 1).unwrap();
|
||||
assert!(wallet_refreshed);
|
||||
w.close().unwrap();
|
||||
}
|
||||
|
||||
if init_invoice_tx {
|
||||
let amount = 60_000_000_000;
|
||||
let mut slate = {
|
||||
let mut w = wallet2.lock();
|
||||
w.open_with_credentials().unwrap();
|
||||
let mut w_lock = wallet2.lock();
|
||||
let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
let args = IssueInvoiceTxArgs {
|
||||
amount,
|
||||
..Default::default()
|
||||
};
|
||||
api_impl::owner::issue_invoice_tx(&mut *w, args, true).unwrap()
|
||||
api_impl::owner::issue_invoice_tx(&mut **w, args, true).unwrap()
|
||||
};
|
||||
slate = {
|
||||
let mut w = wallet1.lock();
|
||||
w.open_with_credentials().unwrap();
|
||||
let mut w_lock = wallet1.lock();
|
||||
let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
let args = InitTxArgs {
|
||||
src_acct_name: None,
|
||||
amount: slate.amount,
|
||||
@@ -658,7 +692,7 @@ pub fn run_doctest_foreign(
|
||||
selection_strategy_is_use_all: true,
|
||||
..Default::default()
|
||||
};
|
||||
api_impl::owner::process_invoice_tx(&mut *w, &slate, args, true).unwrap()
|
||||
api_impl::owner::process_invoice_tx(&mut **w, &slate, args, true).unwrap()
|
||||
};
|
||||
println!("INIT INVOICE SLATE");
|
||||
// Spit out slate for input to finalize_invoice_tx
|
||||
@@ -667,8 +701,8 @@ pub fn run_doctest_foreign(
|
||||
|
||||
if init_tx {
|
||||
let amount = 60_000_000_000;
|
||||
let mut w = wallet1.lock();
|
||||
w.open_with_credentials().unwrap();
|
||||
let mut w_lock = wallet1.lock();
|
||||
let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
let args = InitTxArgs {
|
||||
src_acct_name: None,
|
||||
amount,
|
||||
@@ -678,15 +712,15 @@ pub fn run_doctest_foreign(
|
||||
selection_strategy_is_use_all: true,
|
||||
..Default::default()
|
||||
};
|
||||
let slate = api_impl::owner::init_send_tx(&mut *w, args, true).unwrap();
|
||||
let slate = api_impl::owner::init_send_tx(&mut **w, args, true).unwrap();
|
||||
println!("INIT SLATE");
|
||||
// Spit out slate for input to finalize_tx
|
||||
println!("{}", serde_json::to_string_pretty(&slate).unwrap());
|
||||
}
|
||||
|
||||
let mut api_foreign = match init_invoice_tx {
|
||||
false => Foreign::new(wallet1.clone(), Some(test_check_middleware)),
|
||||
true => Foreign::new(wallet2.clone(), Some(test_check_middleware)),
|
||||
false => Foreign::new(wallet1, Some(test_check_middleware)),
|
||||
true => Foreign::new(wallet2, Some(test_check_middleware)),
|
||||
};
|
||||
api_foreign.doctest_mode = true;
|
||||
let foreign_api = &api_foreign as &dyn ForeignRpc;
|
||||
|
||||
@@ -36,8 +36,10 @@ extern crate log;
|
||||
|
||||
mod foreign;
|
||||
mod foreign_rpc;
|
||||
|
||||
mod owner;
|
||||
mod owner_rpc;
|
||||
|
||||
pub use crate::foreign::{Foreign, ForeignCheckMiddleware, ForeignCheckMiddlewareFn};
|
||||
pub use crate::foreign_rpc::ForeignRpc;
|
||||
pub use crate::owner::Owner;
|
||||
|
||||
+118
-113
@@ -14,20 +14,20 @@
|
||||
|
||||
//! Owner API External Definition
|
||||
|
||||
use crate::util::Mutex;
|
||||
use chrono::prelude::*;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::core::core::Transaction;
|
||||
use crate::impls::{HTTPWalletCommAdapter, KeybaseWalletCommAdapter};
|
||||
use crate::impls::create_sender;
|
||||
use crate::keychain::{Identifier, Keychain};
|
||||
use crate::libwallet::api_impl::owner;
|
||||
use crate::libwallet::{
|
||||
AcctPathMapping, Error, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
|
||||
NodeHeightResult, OutputCommitMapping, Slate, TxLogEntry, WalletBackend, WalletInfo,
|
||||
NodeHeightResult, OutputCommitMapping, Slate, TxLogEntry, WalletInfo, WalletInst,
|
||||
WalletLCProvider,
|
||||
};
|
||||
use crate::util::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Main interface into all wallet API functions.
|
||||
/// Wallet APIs are split into two seperate blocks of functionality
|
||||
@@ -43,24 +43,21 @@ use crate::libwallet::{
|
||||
/// its operation, then 'close' the wallet (unloading references to the keychain and master
|
||||
/// seed).
|
||||
|
||||
pub struct Owner<W: ?Sized, C, K>
|
||||
pub struct Owner<'a, L, C, K>
|
||||
where
|
||||
W: WalletBackend<C, K>,
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
L: WalletLCProvider<'a, C, K>,
|
||||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
/// A reference-counted mutex to an implementation of the
|
||||
/// [`WalletBackend`](../grin_wallet_libwallet/types/trait.WalletBackend.html) trait.
|
||||
pub wallet: Arc<Mutex<W>>,
|
||||
/// contain all methods to manage the wallet
|
||||
pub wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
|
||||
/// Flag to normalize some output during testing. Can mostly be ignored.
|
||||
pub doctest_mode: bool,
|
||||
phantom: PhantomData<K>,
|
||||
phantom_c: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<W: ?Sized, C, K> Owner<W, C, K>
|
||||
impl<'a, L, C, K> Owner<'a, L, C, K>
|
||||
where
|
||||
W: WalletBackend<C, K>,
|
||||
L: WalletLCProvider<'a, C, K>,
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
{
|
||||
@@ -92,12 +89,12 @@ where
|
||||
/// use tempfile::tempdir;
|
||||
///
|
||||
/// use std::sync::Arc;
|
||||
/// use util::Mutex;
|
||||
/// use util::{Mutex, ZeroingString};
|
||||
///
|
||||
/// use api::Owner;
|
||||
/// use config::WalletConfig;
|
||||
/// use impls::{HTTPNodeClient, LMDBBackend};
|
||||
/// use libwallet::WalletBackend;
|
||||
/// use impls::{DefaultWalletImpl, DefaultLCProvider, HTTPNodeClient};
|
||||
/// use libwallet::WalletInst;
|
||||
///
|
||||
/// let mut wallet_config = WalletConfig::default();
|
||||
/// # let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
|
||||
@@ -110,24 +107,39 @@ where
|
||||
///
|
||||
/// // A NodeClient must first be created to handle communication between
|
||||
/// // the wallet and the node.
|
||||
///
|
||||
/// let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// Arc::new(Mutex::new(
|
||||
/// LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
|
||||
/// ));
|
||||
///
|
||||
/// // impls::DefaultWalletImpl is provided for convenience in instantiating the wallet
|
||||
/// // It contains the LMDBBackend, DefaultLCProvider (lifecycle) and ExtKeychain used
|
||||
/// // by the reference wallet implementation.
|
||||
/// // These traits can be replaced with alternative implementations if desired
|
||||
///
|
||||
/// let mut wallet = Box::new(DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap())
|
||||
/// as Box<WalletInst<'static, DefaultLCProvider<HTTPNodeClient, ExtKeychain>, HTTPNodeClient, ExtKeychain>>;
|
||||
///
|
||||
/// // Wallet LifeCycle Provider provides all functions init wallet and work with seeds, etc...
|
||||
/// let lc = wallet.lc_provider().unwrap();
|
||||
///
|
||||
/// // The top level wallet directory should be set manually (in the reference implementation,
|
||||
/// // this is provided in the WalletConfig)
|
||||
/// lc.set_wallet_directory(&wallet_config.data_file_dir);
|
||||
///
|
||||
/// // Wallet must be opened with the password (TBD)
|
||||
/// let pw = ZeroingString::from("wallet_password");
|
||||
/// lc.open_wallet(None, pw);
|
||||
///
|
||||
/// // All wallet functions operate on an Arc::Mutex to allow multithreading where needed
|
||||
/// let mut wallet = Arc::new(Mutex::new(wallet));
|
||||
///
|
||||
/// let api_owner = Owner::new(wallet.clone());
|
||||
/// // .. perform wallet operations
|
||||
///
|
||||
/// ```
|
||||
|
||||
pub fn new(wallet_in: Arc<Mutex<W>>) -> Self {
|
||||
pub fn new(wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>) -> Self {
|
||||
Owner {
|
||||
wallet: wallet_in,
|
||||
wallet_inst,
|
||||
doctest_mode: false,
|
||||
phantom: PhantomData,
|
||||
phantom_c: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,8 +172,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn accounts(&self) -> Result<Vec<AcctPathMapping>, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
owner::accounts(&mut *w)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::accounts(&mut **w)
|
||||
}
|
||||
|
||||
/// Creates a new 'account', which is a mapping of a user-specified
|
||||
@@ -202,8 +215,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn create_account_path(&self, label: &str) -> Result<Identifier, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
owner::create_account_path(&mut *w, label)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::create_account_path(&mut **w, label)
|
||||
}
|
||||
|
||||
/// Sets the wallet's currently active account. This sets the
|
||||
@@ -243,8 +257,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn set_active_account(&self, label: &str) -> Result<(), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
owner::set_active_account(&mut *w, label)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::set_active_account(&mut **w, label)
|
||||
}
|
||||
|
||||
/// Returns a list of outputs from the active account in the wallet.
|
||||
@@ -295,11 +310,9 @@ where
|
||||
refresh_from_node: bool,
|
||||
tx_id: Option<u32>,
|
||||
) -> Result<(bool, Vec<OutputCommitMapping>), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::retrieve_outputs(&mut *w, include_spent, refresh_from_node, tx_id);
|
||||
w.close()?;
|
||||
res
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::retrieve_outputs(&mut **w, include_spent, refresh_from_node, tx_id)
|
||||
}
|
||||
|
||||
/// Returns a list of [Transaction Log Entries](../grin_wallet_libwallet/types/struct.TxLogEntry.html)
|
||||
@@ -348,9 +361,9 @@ where
|
||||
tx_id: Option<u32>,
|
||||
tx_slate_id: Option<Uuid>,
|
||||
) -> Result<(bool, Vec<TxLogEntry>), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let mut res = owner::retrieve_txs(&mut *w, refresh_from_node, tx_id, tx_slate_id)?;
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
let mut res = owner::retrieve_txs(&mut **w, refresh_from_node, tx_id, tx_slate_id)?;
|
||||
if self.doctest_mode {
|
||||
res.1 = res
|
||||
.1
|
||||
@@ -362,7 +375,6 @@ where
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
w.close()?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -406,11 +418,9 @@ where
|
||||
refresh_from_node: bool,
|
||||
minimum_confirmations: u64,
|
||||
) -> Result<(bool, WalletInfo), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::retrieve_summary_info(&mut *w, refresh_from_node, minimum_confirmations);
|
||||
w.close()?;
|
||||
res
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::retrieve_summary_info(&mut **w, refresh_from_node, minimum_confirmations)
|
||||
}
|
||||
|
||||
/// Initiates a new transaction as the sender, creating a new
|
||||
@@ -489,30 +499,27 @@ where
|
||||
pub fn init_send_tx(&self, args: InitTxArgs) -> Result<Slate, Error> {
|
||||
let send_args = args.send_args.clone();
|
||||
let mut slate = {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let slate = owner::init_send_tx(&mut *w, args, self.doctest_mode)?;
|
||||
w.close()?;
|
||||
slate
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::init_send_tx(&mut **w, args, self.doctest_mode)?
|
||||
};
|
||||
// Helper functionality. If send arguments exist, attempt to send
|
||||
match send_args {
|
||||
Some(sa) => {
|
||||
//TODO: in case of keybase, the response might take 60s and leave the service hanging
|
||||
match sa.method.as_ref() {
|
||||
"http" => {
|
||||
slate = HTTPWalletCommAdapter::new().send_tx_sync(&sa.dest, &slate)?
|
||||
}
|
||||
"keybase" => {
|
||||
//TODO: in case of keybase, the response might take 60s and leave the service hanging
|
||||
slate = KeybaseWalletCommAdapter::new().send_tx_sync(&sa.dest, &slate)?;
|
||||
}
|
||||
"http" | "keybase" => {}
|
||||
_ => {
|
||||
error!("unsupported payment method: {}", sa.method);
|
||||
return Err(ErrorKind::ClientCallback(
|
||||
"unsupported payment method".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
let comm_adapter = create_sender(&sa.method, &sa.dest)
|
||||
.map_err(|e| ErrorKind::GenericError(format!("{}", e)))?;
|
||||
slate = comm_adapter.send_tx(&slate)?;
|
||||
self.tx_lock_outputs(&slate, 0)?;
|
||||
let slate = match sa.finalize {
|
||||
true => self.finalize_tx(&slate)?,
|
||||
@@ -562,11 +569,9 @@ where
|
||||
/// }
|
||||
/// ```
|
||||
pub fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result<Slate, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let slate = owner::issue_invoice_tx(&mut *w, args, self.doctest_mode)?;
|
||||
w.close()?;
|
||||
Ok(slate)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::issue_invoice_tx(&mut **w, args, self.doctest_mode)
|
||||
}
|
||||
|
||||
/// Processes an invoice tranaction created by another party, essentially
|
||||
@@ -623,11 +628,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn process_invoice_tx(&self, slate: &Slate, args: InitTxArgs) -> Result<Slate, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let slate = owner::process_invoice_tx(&mut *w, slate, args, self.doctest_mode)?;
|
||||
w.close()?;
|
||||
Ok(slate)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::process_invoice_tx(&mut **w, slate, args, self.doctest_mode)
|
||||
}
|
||||
|
||||
/// Locks the outputs associated with the inputs to the transaction in the given
|
||||
@@ -683,11 +686,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn tx_lock_outputs(&self, slate: &Slate, participant_id: usize) -> Result<(), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::tx_lock_outputs(&mut *w, slate, participant_id);
|
||||
w.close()?;
|
||||
res
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::tx_lock_outputs(&mut **w, slate, participant_id)
|
||||
}
|
||||
|
||||
/// Finalizes a transaction, after all parties
|
||||
@@ -745,12 +746,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn finalize_tx(&self, slate: &Slate) -> Result<Slate, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut slate = slate.clone();
|
||||
w.open_with_credentials()?;
|
||||
slate = owner::finalize_tx(&mut *w, &slate)?;
|
||||
w.close()?;
|
||||
Ok(slate)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::finalize_tx(&mut **w, &slate)
|
||||
}
|
||||
|
||||
/// Posts a completed transaction to the listening node for validation and inclusion in a block
|
||||
@@ -804,7 +802,8 @@ where
|
||||
|
||||
pub fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error> {
|
||||
let client = {
|
||||
let mut w = self.wallet.lock();
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
w.w2n_client().clone()
|
||||
};
|
||||
owner::post_tx(&client, tx, fluff)
|
||||
@@ -863,11 +862,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn cancel_tx(&self, tx_id: Option<u32>, tx_slate_id: Option<Uuid>) -> Result<(), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::cancel_tx(&mut *w, tx_id, tx_slate_id);
|
||||
w.close()?;
|
||||
res
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::cancel_tx(&mut **w, tx_id, tx_slate_id)
|
||||
}
|
||||
|
||||
/// Retrieves the stored transaction associated with a TxLogEntry. Can be used even after the
|
||||
@@ -903,8 +900,9 @@ where
|
||||
|
||||
// TODO: Should be accepting an id, not an entire entry struct
|
||||
pub fn get_stored_tx(&self, tx_log_entry: &TxLogEntry) -> Result<Option<Transaction>, Error> {
|
||||
let w = self.wallet.lock();
|
||||
owner::get_stored_tx(&*w, tx_log_entry)
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::get_stored_tx(&**w, tx_log_entry)
|
||||
}
|
||||
|
||||
/// Verifies all messages in the slate match their public keys.
|
||||
@@ -993,10 +991,9 @@ where
|
||||
/// }
|
||||
/// ```
|
||||
pub fn restore(&self) -> Result<(), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::restore(&mut *w);
|
||||
w.close()?;
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
let res = owner::restore(&mut **w);
|
||||
res
|
||||
}
|
||||
|
||||
@@ -1047,11 +1044,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::check_repair(&mut *w, delete_unconfirmed);
|
||||
w.close()?;
|
||||
res
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::check_repair(&mut **w, delete_unconfirmed)
|
||||
}
|
||||
|
||||
/// Retrieves the last known height known by the wallet. This is determined as follows:
|
||||
@@ -1092,11 +1087,9 @@ where
|
||||
/// ```
|
||||
|
||||
pub fn node_height(&self) -> Result<NodeHeightResult, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let res = owner::node_height(&mut *w);
|
||||
w.close()?;
|
||||
res
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
owner::node_height(&mut **w)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1115,12 +1108,12 @@ macro_rules! doctest_helper_setup_doc_env {
|
||||
use tempfile::tempdir;
|
||||
|
||||
use std::sync::Arc;
|
||||
use util::Mutex;
|
||||
use util::{Mutex, ZeroingString};
|
||||
|
||||
use api::Owner;
|
||||
use api::{Foreign, Owner};
|
||||
use config::WalletConfig;
|
||||
use impls::{HTTPNodeClient, LMDBBackend, WalletSeed};
|
||||
use libwallet::{InitTxArgs, IssueInvoiceTxArgs, Slate, WalletBackend};
|
||||
use impls::{DefaultLCProvider, DefaultWalletImpl, HTTPNodeClient};
|
||||
use libwallet::{BlockFees, InitTxArgs, IssueInvoiceTxArgs, Slate, WalletInst};
|
||||
|
||||
let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
|
||||
let dir = dir
|
||||
@@ -1130,11 +1123,23 @@ macro_rules! doctest_helper_setup_doc_env {
|
||||
.unwrap();
|
||||
let mut wallet_config = WalletConfig::default();
|
||||
wallet_config.data_file_dir = dir.to_owned();
|
||||
let pw = "";
|
||||
let pw = ZeroingString::from("");
|
||||
|
||||
let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
let mut $wallet: Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> = Arc::new(
|
||||
Mutex::new(LMDBBackend::new(wallet_config.clone(), pw, node_client).unwrap()),
|
||||
);
|
||||
let mut wallet = Box::new(
|
||||
DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap(),
|
||||
)
|
||||
as Box<
|
||||
WalletInst<
|
||||
'static,
|
||||
DefaultLCProvider<HTTPNodeClient, ExtKeychain>,
|
||||
HTTPNodeClient,
|
||||
ExtKeychain,
|
||||
>,
|
||||
>;
|
||||
let lc = wallet.lc_provider().unwrap();
|
||||
lc.set_wallet_directory(&wallet_config.data_file_dir);
|
||||
lc.open_wallet(None, pw);
|
||||
let mut $wallet = Arc::new(Mutex::new(wallet));
|
||||
};
|
||||
}
|
||||
|
||||
+68
-35
@@ -19,10 +19,12 @@ use crate::core::core::Transaction;
|
||||
use crate::keychain::{Identifier, Keychain};
|
||||
use crate::libwallet::{
|
||||
AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult,
|
||||
OutputCommitMapping, Slate, TxLogEntry, WalletBackend, WalletInfo,
|
||||
OutputCommitMapping, Slate, TxLogEntry, WalletInfo, WalletLCProvider,
|
||||
};
|
||||
use crate::util::Mutex;
|
||||
use crate::Owner;
|
||||
use easy_jsonrpc;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Public definition used to generate Owner jsonrpc api.
|
||||
/// * When running `grin-wallet owner_api` with defaults, the V2 api is available at
|
||||
@@ -1233,11 +1235,11 @@ pub trait OwnerRpc {
|
||||
fn node_height(&self) -> Result<NodeHeightResult, ErrorKind>;
|
||||
}
|
||||
|
||||
impl<W: ?Sized, C, K> OwnerRpc for Owner<W, C, K>
|
||||
impl<'a, L, C, K> OwnerRpc for Owner<'a, L, C, K>
|
||||
where
|
||||
W: WalletBackend<C, K>,
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
L: WalletLCProvider<'a, C, K>,
|
||||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
fn accounts(&self) -> Result<Vec<AcctPathMapping>, ErrorKind> {
|
||||
Owner::accounts(self).map_err(|e| e.kind())
|
||||
@@ -1338,7 +1340,8 @@ pub fn run_doctest_owner(
|
||||
) -> Result<Option<serde_json::Value>, String> {
|
||||
use easy_jsonrpc::Handler;
|
||||
use grin_wallet_impls::test_framework::{self, LocalWalletClient, WalletProxy};
|
||||
use grin_wallet_libwallet::api_impl;
|
||||
use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl};
|
||||
use grin_wallet_libwallet::{api_impl, WalletInst};
|
||||
use grin_wallet_util::grin_keychain::ExtKeychain;
|
||||
|
||||
use crate::core::global;
|
||||
@@ -1352,29 +1355,61 @@ pub fn run_doctest_owner(
|
||||
let _ = fs::remove_dir_all(test_dir);
|
||||
global::set_mining_mode(ChainTypes::AutomatedTesting);
|
||||
|
||||
let mut wallet_proxy: WalletProxy<LocalWalletClient, ExtKeychain> = WalletProxy::new(test_dir);
|
||||
let mut wallet_proxy: WalletProxy<
|
||||
DefaultLCProvider<LocalWalletClient, ExtKeychain>,
|
||||
LocalWalletClient,
|
||||
ExtKeychain,
|
||||
> = WalletProxy::new(test_dir);
|
||||
let chain = wallet_proxy.chain.clone();
|
||||
|
||||
let rec_phrase_1 =
|
||||
let rec_phrase_1 = util::ZeroingString::from(
|
||||
"fat twenty mean degree forget shell check candy immense awful \
|
||||
flame next during february bulb bike sun wink theory day kiwi embrace peace lunch";
|
||||
let client1 = LocalWalletClient::new("wallet1", wallet_proxy.tx.clone());
|
||||
let wallet1 = test_framework::create_wallet(
|
||||
&format!("{}/wallet1", test_dir),
|
||||
client1.clone(),
|
||||
Some(rec_phrase_1),
|
||||
flame next during february bulb bike sun wink theory day kiwi embrace peace lunch",
|
||||
);
|
||||
let empty_string = util::ZeroingString::from("");
|
||||
|
||||
let client1 = LocalWalletClient::new("wallet1", wallet_proxy.tx.clone());
|
||||
let mut wallet1 =
|
||||
Box::new(DefaultWalletImpl::<LocalWalletClient>::new(client1.clone()).unwrap())
|
||||
as Box<
|
||||
WalletInst<
|
||||
'static,
|
||||
DefaultLCProvider<LocalWalletClient, ExtKeychain>,
|
||||
LocalWalletClient,
|
||||
ExtKeychain,
|
||||
>,
|
||||
>;
|
||||
let lc = wallet1.lc_provider().unwrap();
|
||||
lc.set_wallet_directory(&format!("{}/wallet1", test_dir));
|
||||
lc.create_wallet(None, Some(rec_phrase_1), 32, empty_string.clone())
|
||||
.unwrap();
|
||||
lc.open_wallet(None, empty_string.clone()).unwrap();
|
||||
let wallet1 = Arc::new(Mutex::new(wallet1));
|
||||
|
||||
wallet_proxy.add_wallet("wallet1", client1.get_send_instance(), wallet1.clone());
|
||||
|
||||
let rec_phrase_2 =
|
||||
let rec_phrase_2 = util::ZeroingString::from(
|
||||
"hour kingdom ripple lunch razor inquiry coyote clay stamp mean \
|
||||
sell finish magic kid tiny wage stand panther inside settle feed song hole exile";
|
||||
let client2 = LocalWalletClient::new("wallet2", wallet_proxy.tx.clone());
|
||||
let wallet2 = test_framework::create_wallet(
|
||||
&format!("{}/wallet2", test_dir),
|
||||
client2.clone(),
|
||||
Some(rec_phrase_2),
|
||||
sell finish magic kid tiny wage stand panther inside settle feed song hole exile",
|
||||
);
|
||||
let client2 = LocalWalletClient::new("wallet2", wallet_proxy.tx.clone());
|
||||
let mut wallet2 =
|
||||
Box::new(DefaultWalletImpl::<LocalWalletClient>::new(client2.clone()).unwrap())
|
||||
as Box<
|
||||
WalletInst<
|
||||
'static,
|
||||
DefaultLCProvider<LocalWalletClient, ExtKeychain>,
|
||||
LocalWalletClient,
|
||||
ExtKeychain,
|
||||
>,
|
||||
>;
|
||||
let lc = wallet2.lc_provider().unwrap();
|
||||
lc.set_wallet_directory(&format!("{}/wallet2", test_dir));
|
||||
lc.create_wallet(None, Some(rec_phrase_2), 32, empty_string.clone())
|
||||
.unwrap();
|
||||
lc.open_wallet(None, empty_string.clone()).unwrap();
|
||||
let wallet2 = Arc::new(Mutex::new(wallet2));
|
||||
|
||||
wallet_proxy.add_wallet("wallet2", client2.get_send_instance(), wallet2.clone());
|
||||
|
||||
// Set the wallet proxy listener running
|
||||
@@ -1388,18 +1423,17 @@ pub fn run_doctest_owner(
|
||||
for _ in 0..blocks_to_mine {
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 1 as usize, false);
|
||||
//update local outputs after each block, so transaction IDs stay consistent
|
||||
let mut w = wallet1.lock();
|
||||
w.open_with_credentials().unwrap();
|
||||
let mut w_lock = wallet1.lock();
|
||||
let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
let (wallet_refreshed, _) =
|
||||
api_impl::owner::retrieve_summary_info(&mut *w, true, 1).unwrap();
|
||||
api_impl::owner::retrieve_summary_info(&mut **w, true, 1).unwrap();
|
||||
assert!(wallet_refreshed);
|
||||
w.close().unwrap();
|
||||
}
|
||||
|
||||
if perform_tx {
|
||||
let amount = 60_000_000_000;
|
||||
let mut w = wallet1.lock();
|
||||
w.open_with_credentials().unwrap();
|
||||
let mut w_lock = wallet1.lock();
|
||||
let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
let args = InitTxArgs {
|
||||
src_acct_name: None,
|
||||
amount,
|
||||
@@ -1409,27 +1443,26 @@ pub fn run_doctest_owner(
|
||||
selection_strategy_is_use_all: true,
|
||||
..Default::default()
|
||||
};
|
||||
let mut slate = api_impl::owner::init_send_tx(&mut *w, args, true).unwrap();
|
||||
let mut slate = api_impl::owner::init_send_tx(&mut **w, args, true).unwrap();
|
||||
println!("INITIAL SLATE");
|
||||
println!("{}", serde_json::to_string_pretty(&slate).unwrap());
|
||||
{
|
||||
let mut w2 = wallet2.lock();
|
||||
w2.open_with_credentials().unwrap();
|
||||
slate = api_impl::foreign::receive_tx(&mut *w2, &slate, None, None, true).unwrap();
|
||||
let mut w_lock = wallet2.lock();
|
||||
let w2 = w_lock.lc_provider().unwrap().wallet_inst().unwrap();
|
||||
slate = api_impl::foreign::receive_tx(&mut **w2, &slate, None, None, true).unwrap();
|
||||
w2.close().unwrap();
|
||||
}
|
||||
// Spit out slate for input to finalize_tx
|
||||
if lock_tx {
|
||||
api_impl::owner::tx_lock_outputs(&mut *w, &slate, 0).unwrap();
|
||||
api_impl::owner::tx_lock_outputs(&mut **w, &slate, 0).unwrap();
|
||||
}
|
||||
println!("RECEIPIENT SLATE");
|
||||
println!("{}", serde_json::to_string_pretty(&slate).unwrap());
|
||||
if finalize_tx {
|
||||
slate = api_impl::owner::finalize_tx(&mut *w, &slate).unwrap();
|
||||
slate = api_impl::owner::finalize_tx(&mut **w, &slate).unwrap();
|
||||
error!("FINALIZED TX SLATE");
|
||||
println!("{}", serde_json::to_string_pretty(&slate).unwrap());
|
||||
}
|
||||
w.close().unwrap();
|
||||
}
|
||||
|
||||
if perform_tx && lock_tx && finalize_tx {
|
||||
@@ -1437,7 +1470,7 @@ pub fn run_doctest_owner(
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3 as usize, false);
|
||||
}
|
||||
|
||||
let mut api_owner = Owner::new(wallet1.clone());
|
||||
let mut api_owner = Owner::new(wallet1);
|
||||
api_owner.doctest_mode = true;
|
||||
let owner_api = &api_owner as &dyn OwnerRpc;
|
||||
Ok(owner_api.handle_request(request).as_option())
|
||||
|
||||
Reference in New Issue
Block a user