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:
Yeastplume
2019-07-29 13:25:03 +01:00
committed by GitHub
parent 7b6d597d39
commit c40e8a915b
54 changed files with 2405 additions and 1942 deletions
+55 -58
View File
@@ -17,11 +17,10 @@
use crate::api::{self, ApiServer, BasicAuthMiddleware, ResponseFuture, Router, TLSConfig};
use crate::keychain::Keychain;
use crate::libwallet::{
Error, ErrorKind, NodeClient, NodeVersionInfo, Slate, WalletBackend, CURRENT_SLATE_VERSION,
GRIN_BLOCK_HEADER_VERSION,
Error, ErrorKind, NodeClient, NodeVersionInfo, Slate, WalletInst, WalletLCProvider,
CURRENT_SLATE_VERSION, GRIN_BLOCK_HEADER_VERSION,
};
use crate::util::to_base64;
use crate::util::Mutex;
use crate::util::{to_base64, Mutex};
use failure::ResultExt;
use futures::future::{err, ok};
use futures::{Future, Stream};
@@ -29,7 +28,6 @@ use hyper::header::HeaderValue;
use hyper::{Body, Request, Response, StatusCode};
use serde::{Deserialize, Serialize};
use serde_json;
use std::marker::PhantomData;
use std::net::SocketAddr;
use std::sync::Arc;
@@ -74,41 +72,47 @@ 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<F, T: ?Sized, C, K>(wallet: Arc<Mutex<T>>, f: F) -> Result<(), Error>
pub fn owner_single_use<'a, L, F, C, K>(
lc_provider: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
f: F,
) -> Result<(), Error>
where
T: WalletBackend<C, K>,
F: FnOnce(&mut Owner<T, C, K>) -> Result<(), Error>,
C: NodeClient,
K: Keychain,
L: WalletLCProvider<'a, C, K>,
F: FnOnce(&mut Owner<'a, L, C, K>) -> Result<(), Error>,
C: NodeClient + 'a,
K: Keychain + 'a,
{
f(&mut Owner::new(wallet.clone()))?;
f(&mut Owner::new(lc_provider))?;
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<F, T: ?Sized, C, K>(wallet: Arc<Mutex<T>>, f: F) -> Result<(), Error>
pub fn foreign_single_use<'a, L, F, C, K>(
lc_provider: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
f: F,
) -> Result<(), Error>
where
T: WalletBackend<C, K>,
F: FnOnce(&mut Foreign<T, C, K>) -> Result<(), Error>,
C: NodeClient,
K: Keychain,
L: WalletLCProvider<'a, C, K>,
F: FnOnce(&mut Foreign<'a, L, C, K>) -> Result<(), Error>,
C: NodeClient + 'a,
K: Keychain + 'a,
{
f(&mut Foreign::new(wallet.clone(), Some(check_middleware)))?;
f(&mut Foreign::new(lc_provider, Some(check_middleware)))?;
Ok(())
}
/// Listener version, providing same API but listening for requests on a
/// port and wrapping the calls
pub fn owner_listener<T: ?Sized, C, K>(
wallet: Arc<Mutex<T>>,
pub fn owner_listener<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
addr: &str,
api_secret: Option<String>,
tls_config: Option<TLSConfig>,
owner_api_include_foreign: Option<bool>,
) -> Result<(), Error>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{
@@ -131,21 +135,22 @@ where
// If so configured, add the foreign API to the same port
if owner_api_include_foreign.unwrap_or(false) {
info!("Starting HTTP Foreign API on Owner server at {}.", addr);
let foreign_api_handler_v2 = ForeignAPIHandlerV2::new(wallet.clone());
warn!("Starting HTTP Foreign API on Owner server at {}.", addr);
let foreign_api_handler_v2 = ForeignAPIHandlerV2::new(wallet);
router
.add_route("/v2/foreign", Arc::new(foreign_api_handler_v2))
.map_err(|_| ErrorKind::GenericError("Router failed to add route".to_string()))?;
}
let mut apis = ApiServer::new();
info!("Starting HTTP Owner API server at {}.", addr);
warn!("Starting HTTP Owner API server at {}.", addr);
let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address");
let api_thread =
apis.start(socket_addr, router, tls_config)
.context(ErrorKind::GenericError(
"API thread failed to start".to_string(),
))?;
warn!("HTTP Owner listener started.");
api_thread
.join()
.map_err(|e| ErrorKind::GenericError(format!("API thread panicked :{:?}", e)).into())
@@ -153,13 +158,13 @@ where
/// Listener version, providing same API but listening for requests on a
/// port and wrapping the calls
pub fn foreign_listener<T: ?Sized, C, K>(
wallet: Arc<Mutex<T>>,
pub fn foreign_listener<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
addr: &str,
tls_config: Option<TLSConfig>,
) -> Result<(), Error>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{
@@ -189,37 +194,33 @@ where
type WalletResponseFuture = Box<dyn Future<Item = Response<Body>, Error = Error> + Send>;
/// V2 API Handler/Wrapper for owner functions
pub struct OwnerAPIHandlerV2<T: ?Sized, C, K>
pub struct OwnerAPIHandlerV2<L, C, K>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{
/// Wallet instance
pub wallet: Arc<Mutex<T>>,
phantom: PhantomData<K>,
phantom_c: PhantomData<C>,
pub wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
}
impl<T: ?Sized, C, K> OwnerAPIHandlerV2<T, C, K>
impl<L, C, K> OwnerAPIHandlerV2<L, C, K>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K>,
C: NodeClient + 'static,
K: Keychain + 'static,
{
/// Create a new owner API handler for GET methods
pub fn new(wallet: Arc<Mutex<T>>) -> OwnerAPIHandlerV2<T, C, K> {
OwnerAPIHandlerV2 {
wallet,
phantom: PhantomData,
phantom_c: PhantomData,
}
pub fn new(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
) -> OwnerAPIHandlerV2<L, C, K> {
OwnerAPIHandlerV2 { wallet }
}
fn call_api(
&self,
req: Request<Body>,
api: Owner<T, C, K>,
api: Owner<'static, L, C, K>,
) -> Box<dyn Future<Item = serde_json::Value, Error = Error> + Send> {
Box::new(parse_body(req).and_then(move |val: serde_json::Value| {
let owner_api = &api as &dyn OwnerRpc;
@@ -243,9 +244,9 @@ where
}
}
impl<T: ?Sized, C, K> api::Handler for OwnerAPIHandlerV2<T, C, K>
impl<L, C, K> api::Handler for OwnerAPIHandlerV2<L, C, K>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{
@@ -266,37 +267,33 @@ where
}
/// V2 API Handler/Wrapper for foreign functions
pub struct ForeignAPIHandlerV2<T: ?Sized, C, K>
pub struct ForeignAPIHandlerV2<L, C, K>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{
/// Wallet instance
pub wallet: Arc<Mutex<T>>,
phantom: PhantomData<K>,
phantom_c: PhantomData<C>,
pub wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
}
impl<T: ?Sized, C, K> ForeignAPIHandlerV2<T, C, K>
impl<L, C, K> ForeignAPIHandlerV2<L, C, K>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{
/// Create a new foreign API handler for GET methods
pub fn new(wallet: Arc<Mutex<T>>) -> ForeignAPIHandlerV2<T, C, K> {
ForeignAPIHandlerV2 {
wallet,
phantom: PhantomData,
phantom_c: PhantomData,
}
pub fn new(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
) -> ForeignAPIHandlerV2<L, C, K> {
ForeignAPIHandlerV2 { wallet }
}
fn call_api(
&self,
req: Request<Body>,
api: Foreign<T, C, K>,
api: Foreign<'static, L, C, K>,
) -> Box<dyn Future<Item = serde_json::Value, Error = Error> + Send> {
Box::new(parse_body(req).and_then(move |val: serde_json::Value| {
let foreign_api = &api as &dyn ForeignRpc;
@@ -320,9 +317,9 @@ where
}
}
impl<T: ?Sized, C, K> api::Handler for ForeignAPIHandlerV2<T, C, K>
impl<L, C, K> api::Handler for ForeignAPIHandlerV2<L, C, K>
where
T: WalletBackend<C, K> + Send + Sync + 'static,
L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'static,
K: Keychain + 'static,
{