Optional Tor Send/Listen Functionality (#226)

* udpate for beta release

* initial tor explorations

* rustfmt

* basic tor tx send working

* rustfmt

* add tor proxy info to config file

* rustfmt

* add utilities to output tor hidden service configuration files

* output tor config as part of listener startup

* rustfmt

* fully automate config and startup of tor process

* rustfmt

* remove unnecessary process kill commands from listener

* rustfmt

* assume defaults for tor sending config if section doesn't exist in grin-wallet.toml

* rustfmt

* ignore tor dev test

* update default paths output by config, compilation + confirmed working on windows

* rustfmt

* fix on osx/unix

* add timeout to tor connector, remove unwrap in client

* allow specifiying tor address without 'http://[].onion' on the command line

* fix api test

* rustfmt

* update address derivation path as per spec

* rustfmt

* move tor init to separate function

* rustfmt

* re-ignore tor dev test

* listen on tor by default if tor available

* rustfmt

* test fix

* remove explicit send via tor flag, and assume tor if address fits

* rustfmt
This commit is contained in:
Yeastplume
2019-10-14 20:24:09 +01:00
committed by GitHub
parent c60301946f
commit b4eeb50c66
34 changed files with 2311 additions and 153 deletions
+35 -32
View File
@@ -17,14 +17,14 @@
use futures::{stream, Stream};
use crate::api::LocatedTxKernel;
use crate::api::{self, LocatedTxKernel};
use crate::core::core::TxKernel;
use crate::libwallet::{NodeClient, NodeVersionInfo, TxWrapper};
use semver::Version;
use std::collections::HashMap;
use tokio::runtime::Runtime;
use crate::api;
use crate::client_utils::Client;
use crate::libwallet;
use crate::util::secp::pedersen;
use crate::util::{self, to_hex};
@@ -73,25 +73,25 @@ impl NodeClient for HTTPNodeClient {
return Some(v.clone());
}
let url = format!("{}/v1/version", self.node_url());
let mut retval =
match api::client::get::<NodeVersionInfo>(url.as_str(), self.node_api_secret()) {
Ok(n) => n,
Err(e) => {
// If node isn't available, allow offline functions
// unfortunately have to parse string due to error structure
let err_string = format!("{}", e);
if err_string.contains("404") {
return Some(NodeVersionInfo {
node_version: "1.0.0".into(),
block_header_version: 1,
verified: Some(false),
});
} else {
error!("Unable to contact Node to get version info: {}", e);
return None;
}
let client = Client::new();
let mut retval = match client.get::<NodeVersionInfo>(url.as_str(), self.node_api_secret()) {
Ok(n) => n,
Err(e) => {
// If node isn't available, allow offline functions
// unfortunately have to parse string due to error structure
let err_string = format!("{}", e);
if err_string.contains("404") {
return Some(NodeVersionInfo {
node_version: "1.0.0".into(),
block_header_version: 1,
verified: Some(false),
});
} else {
error!("Unable to contact Node to get version info: {}", e);
return None;
}
};
}
};
retval.verified = Some(true);
self.node_version_info = Some(retval.clone());
Some(retval)
@@ -106,7 +106,8 @@ impl NodeClient for HTTPNodeClient {
} else {
url = format!("{}/v1/pool/push_tx", dest);
}
let res = api::client::post_no_ret(url.as_str(), self.node_api_secret(), tx);
let client = Client::new();
let res = client.post_no_ret(url.as_str(), self.node_api_secret(), tx);
if let Err(e) = res {
let report = format!("Posting transaction to node: {}", e);
error!("Post TX Error: {}", e);
@@ -119,7 +120,8 @@ impl NodeClient for HTTPNodeClient {
fn get_chain_height(&self) -> Result<u64, libwallet::Error> {
let addr = self.node_url();
let url = format!("{}/v1/chain", addr);
let res = api::client::get::<api::Tip>(url.as_str(), self.node_api_secret());
let client = Client::new();
let res = client.get::<api::Tip>(url.as_str(), self.node_api_secret());
match res {
Err(e) => {
let report = format!("Getting chain height from node: {}", e);
@@ -171,10 +173,10 @@ impl NodeClient for HTTPNodeClient {
to_hex(excess.0.to_vec()),
query
);
let res: Option<LocatedTxKernel> = api::client::get(url.as_str(), self.node_api_secret())
.map_err(|e| {
libwallet::ErrorKind::ClientCallback(format!("Kernel lookup: {}", e))
})?;
let client = Client::new();
let res: Option<LocatedTxKernel> = client
.get(url.as_str(), self.node_api_secret())
.map_err(|e| libwallet::ErrorKind::ClientCallback(format!("Kernel lookup: {}", e)))?;
Ok(res.map(|k| (k.tx_kernel, k.height, k.mmr_index)))
}
@@ -196,12 +198,11 @@ impl NodeClient for HTTPNodeClient {
let mut api_outputs: HashMap<pedersen::Commitment, (String, u64, u64)> = HashMap::new();
let mut tasks = Vec::new();
let client = Client::new();
for query_chunk in query_params.chunks(200) {
let url = format!("{}/v1/chain/outputs/byids?{}", addr, query_chunk.join("&"),);
tasks.push(api::client::get_async::<Vec<api::Output>>(
url.as_str(),
self.node_api_secret(),
));
tasks.push(client.get_async::<Vec<api::Output>>(url.as_str(), self.node_api_secret()));
}
let task = stream::futures_unordered(tasks).collect();
@@ -247,7 +248,9 @@ impl NodeClient for HTTPNodeClient {
let mut api_outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64, u64)> =
Vec::new();
match api::client::get::<api::OutputListing>(url.as_str(), self.node_api_secret()) {
let client = Client::new();
match client.get::<api::OutputListing>(url.as_str(), self.node_api_secret()) {
Ok(o) => {
for out in o.outputs {
let is_coinbase = match out.output_type {
@@ -299,7 +302,7 @@ pub fn create_coinbase(dest: &str, block_fees: &BlockFees) -> Result<CbData, Err
/// Makes a single request to the wallet API to create a new coinbase output.
fn single_create_coinbase(url: &str, block_fees: &BlockFees) -> Result<CbData, Error> {
let res = api::client::post(url, None, block_fees).context(ErrorKind::GenericError(
let res = Client::post(url, None, block_fees).context(ErrorKind::GenericError(
"Posting create coinbase".to_string(),
))?;
Ok(res)