Replace failure with thiserror (#654)

* updated util and libwallet with thiserror

* update impl crate to thiserror

* api crate converted to thiserror

* update of controller crate to thiserror

* update final bin + tests to thiserror

* update unused import

* remove failure derive

* reset import of grin to master

* update cargo lock

* update from master
This commit is contained in:
Yeastplume
2022-07-28 10:21:45 +01:00
committed by GitHub
parent 67f0e2b0e0
commit 64cab53b1b
63 changed files with 1066 additions and 1586 deletions
+1 -2
View File
@@ -11,8 +11,7 @@ edition = "2018"
[dependencies]
blake2-rfc = "0.2"
failure = "0.1"
failure_derive = "0.1"
thiserror = "1"
futures = "0.3"
rand = "0.6"
serde = "1"
+5 -6
View File
@@ -16,7 +16,7 @@
use std::fs::File;
use std::io::{Read, Write};
use crate::libwallet::{Error, ErrorKind, Slate, SlateVersion, VersionedBinSlate, VersionedSlate};
use crate::libwallet::{Error, Slate, SlateVersion, VersionedBinSlate, VersionedSlate};
use crate::{SlateGetter, SlatePutter};
use grin_wallet_util::byte_ser;
use std::convert::TryFrom;
@@ -39,13 +39,12 @@ impl SlatePutter for PathToSlate {
// TODO:
let out_slate = VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?;
if as_bin {
let bin_slate =
VersionedBinSlate::try_from(out_slate).map_err(|_| ErrorKind::SlateSer)?;
pub_tx.write_all(&byte_ser::to_bytes(&bin_slate).map_err(|_| ErrorKind::SlateSer)?)?;
let bin_slate = VersionedBinSlate::try_from(out_slate).map_err(|_| Error::SlateSer)?;
pub_tx.write_all(&byte_ser::to_bytes(&bin_slate).map_err(|_| Error::SlateSer)?)?;
} else {
pub_tx.write_all(
serde_json::to_string_pretty(&out_slate)
.map_err(|_| ErrorKind::SlateSer)?
.map_err(|_| Error::SlateSer)?
.as_bytes(),
)?;
}
@@ -68,7 +67,7 @@ impl SlateGetter for PathToSlate {
}
// Otherwise try json
let content = String::from_utf8(data).map_err(|_| ErrorKind::SlateSer)?;
let content = String::from_utf8(data).map_err(|_| Error::SlateSer)?;
Ok((Slate::deserialize_upgrade(&content)?, false))
}
}
+25 -25
View File
@@ -13,9 +13,9 @@
// limitations under the License.
/// HTTP Wallet 'plugin' implementation
use crate::client_utils::{Client, ClientError, ClientErrorKind};
use crate::client_utils::{Client, ClientError};
use crate::libwallet::slate_versions::{SlateVersion, VersionedSlate};
use crate::libwallet::{Error, ErrorKind, Slate};
use crate::libwallet::{Error, Slate};
use crate::tor::bridge::TorBridge;
use crate::tor::proxy::TorProxy;
use crate::SlateSender;
@@ -97,19 +97,19 @@ impl HttpSlateSender {
let mut hm_tor_bridge: HashMap<String, String> = HashMap::new();
if self.bridge.bridge_line.is_some() {
let bridge_struct = TorBridge::try_from(self.bridge.clone())
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
hm_tor_bridge = bridge_struct
.to_hashmap()
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
}
let mut hm_tor_proxy: HashMap<String, String> = HashMap::new();
if self.proxy.transport.is_some() || self.proxy.allowed_port.is_some() {
let proxy = TorProxy::try_from(self.proxy.clone())
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
hm_tor_proxy = proxy
.to_hashmap()
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
}
tor_config::output_tor_sender_config(
@@ -118,14 +118,14 @@ impl HttpSlateSender {
hm_tor_bridge,
hm_tor_proxy,
)
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e)))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
// Start TOR process
tor.torrc_path(&format!("{}/torrc", &tor_dir))
.working_dir(&tor_dir)
.timeout(20)
.completion_percent(100)
.launch()
.map_err(|e| ErrorKind::TorProcess(format!("{:?}", e)))?;
.map_err(|e| Error::TorProcess(format!("{:?}", e)))?;
self.process = Some(Arc::new(tor));
}
Ok(())
@@ -151,7 +151,7 @@ impl HttpSlateSender {
.to_string();
error!("{}", report);
}
ErrorKind::ClientCallback(report)
Error::ClientCallback(report)
})?;
let res: Value = serde_json::from_str(&res).unwrap();
@@ -162,7 +162,7 @@ impl HttpSlateSender {
res["error"]["code"], res["error"]["message"]
);
error!("{}", report);
return Err(ErrorKind::ClientCallback(report).into());
return Err(Error::ClientCallback(report));
}
let resp_value = res["result"]["Ok"].clone();
@@ -176,7 +176,7 @@ impl HttpSlateSender {
if foreign_api_version < 2 {
let report = "Other wallet reports unrecognized API format.".to_string();
error!("{}", report);
return Err(ErrorKind::ClientCallback(report).into());
return Err(Error::ClientCallback(report));
}
if supported_slate_versions.contains(&"V4".to_owned()) {
@@ -185,7 +185,7 @@ impl HttpSlateSender {
let report = "Unable to negotiate slate format with other wallet.".to_string();
error!("{}", report);
Err(ErrorKind::ClientCallback(report).into())
Err(Error::ClientCallback(report))
}
fn post<IN>(
@@ -197,15 +197,15 @@ impl HttpSlateSender {
where
IN: Serialize,
{
let client =
if !self.use_socks {
Client::new()
} else {
Client::with_socks_proxy(self.socks_proxy_addr.ok_or_else(|| {
ClientErrorKind::Internal("No socks proxy address set".into())
})?)
}
.map_err(|_| ClientErrorKind::Internal("Unable to create http client".into()))?;
let client = if !self.use_socks {
Client::new()
} else {
Client::with_socks_proxy(
self.socks_proxy_addr
.ok_or_else(|| ClientError::Internal("No socks proxy address set".into()))?,
)
}
.map_err(|_| ClientError::Internal("Unable to create http client".into()))?;
let req = client.create_post_request(url, api_secret, &input)?;
let res = client.send_request(req)?;
Ok(res)
@@ -254,7 +254,7 @@ impl SlateSender for HttpSlateSender {
"Sending transaction slate to other wallet (is recipient listening?): {}",
e
);
ErrorKind::ClientCallback(report)
Error::ClientCallback(report)
})?;
let res: Value = serde_json::from_str(&res).unwrap();
@@ -265,7 +265,7 @@ impl SlateSender for HttpSlateSender {
res["error"]["code"], res["error"]["message"]
);
error!("{}", report);
return Err(ErrorKind::ClientCallback(report).into());
return Err(Error::ClientCallback(report));
}
let slate_value = res["result"]["Ok"].clone();
@@ -274,7 +274,7 @@ impl SlateSender for HttpSlateSender {
let slate = Slate::deserialize_upgrade(&serde_json::to_string(&slate_value).unwrap())
.map_err(|e| {
error!("Error deserializing response slate: {}", e);
ErrorKind::SlateDeser
Error::SlateDeser
})?;
Ok(slate)
@@ -287,6 +287,6 @@ pub struct SchemeNotHttp;
impl Into<Error> for SchemeNotHttp {
fn into(self) -> Error {
let err_str = "url scheme must be http".to_string();
ErrorKind::GenericError(err_str).into()
Error::GenericError(err_str)
}
}
+4 -4
View File
@@ -17,7 +17,7 @@ use std::fs::{metadata, File};
use std::io::{Read, Write};
use std::path::PathBuf;
use crate::libwallet::{slatepack, Error, ErrorKind, Slate, Slatepack, SlatepackBin, Slatepacker};
use crate::libwallet::{slatepack, Error, Slate, Slatepack, SlatepackBin, Slatepacker};
use crate::{SlateGetter, SlatePutter};
use grin_wallet_util::byte_ser;
@@ -48,7 +48,7 @@ impl<'a> PathToSlatepack<'a> {
"Data is invalid length: {} | min: {}, max: {} |",
len, min_len, max_len
);
return Err(ErrorKind::SlatepackDeser(msg).into());
return Err(Error::SlatepackDeser(msg));
}
let mut pub_tx_f = File::open(&self.pathbuf)?;
let mut data = Vec::new();
@@ -73,13 +73,13 @@ impl<'a> SlatePutter for PathToSlatepack<'a> {
} else {
pub_tx.write_all(
&byte_ser::to_bytes(&SlatepackBin(slatepack))
.map_err(|_| ErrorKind::SlatepackSer)?,
.map_err(|_| Error::SlatepackSer)?,
)?;
}
} else {
pub_tx.write_all(
serde_json::to_string_pretty(&slatepack)
.map_err(|_| ErrorKind::SlateSer)?
.map_err(|_| Error::SlateSer)?
.as_bytes(),
)?;
}
+5 -5
View File
@@ -31,8 +31,8 @@ use crate::store::{self, option_to_not_found, to_key, to_key_u64};
use crate::core::core::Transaction;
use crate::core::ser;
use crate::libwallet::{
AcctPathMapping, Context, Error, ErrorKind, NodeClient, OutputData, ScannedBlockInfo,
TxLogEntry, WalletBackend, WalletInitStatus, WalletOutputBatch,
AcctPathMapping, Context, Error, NodeClient, OutputData, ScannedBlockInfo, TxLogEntry,
WalletBackend, WalletInitStatus, WalletOutputBatch,
};
use crate::util::secp::constants::SECRET_KEY_SIZE;
use crate::util::secp::key::SecretKey;
@@ -238,11 +238,11 @@ where
hasher.update(&root_key.0[..]);
if *self.master_checksum != Some(hasher.finalize()) {
error!("Supplied keychain mask is invalid");
return Err(ErrorKind::InvalidKeychainMask.into());
return Err(Error::InvalidKeychainMask);
}
Ok(k_masked)
}
None => Err(ErrorKind::KeychainDoesntExist.into()),
None => Err(Error::KeychainDoesntExist),
}
}
@@ -281,7 +281,7 @@ where
self.set_parent_key_id(a.path);
Ok(())
} else {
Err(ErrorKind::UnknownAccountLabel(label).into())
Err(Error::UnknownAccountLabel(label))
}
}
+16 -63
View File
@@ -15,13 +15,11 @@
//! High level JSON/HTTP client API
use crate::util::to_base64;
use failure::{Backtrace, Context, Fail, ResultExt};
use lazy_static::lazy_static;
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_TYPE, USER_AGENT};
use reqwest::{ClientBuilder, Method, Proxy, RequestBuilder};
use serde::{Deserialize, Serialize};
use serde_json;
use std::fmt::{self, Display};
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
use std::time::Duration;
@@ -42,62 +40,20 @@ lazy_static! {
));
}
/// Errors that can be returned by an ApiEndpoint implementation.
#[derive(Debug)]
pub struct Error {
inner: Context<ErrorKind>,
}
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
pub enum ErrorKind {
#[fail(display = "Internal error: {}", _0)]
#[derive(Clone, Eq, thiserror::Error, PartialEq, Debug)]
pub enum Error {
#[error("Internal error: {0}")]
Internal(String),
#[fail(display = "Bad arguments: {}", _0)]
#[error("Bad arguments: {0}")]
_Argument(String),
#[fail(display = "Not found.")]
#[error("Not found.")]
_NotFound,
#[fail(display = "Request error: {}", _0)]
#[error("Request error: {0}")]
RequestError(String),
#[fail(display = "ResponseError error: {}", _0)]
#[error("ResponseError error: {0}")]
ResponseError(String),
}
impl Fail for Error {
fn cause(&self) -> Option<&dyn Fail> {
self.inner.cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl Error {
pub fn _kind(&self) -> &ErrorKind {
self.inner.get_context()
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error {
inner: Context::new(kind),
}
}
}
impl From<Context<ErrorKind>> for Error {
fn from(inner: Context<ErrorKind>) -> Error {
Error { inner: inner }
}
}
#[derive(Clone)]
pub struct Client {
client: reqwest::Client,
@@ -126,13 +82,13 @@ impl Client {
if let Some(s) = socks_proxy_addr {
let proxy = Proxy::all(&format!("socks5h://{}:{}", s.ip(), s.port()))
.map_err(|e| ErrorKind::Internal(format!("Unable to create proxy: {}", e)))?;
.map_err(|e| Error::Internal(format!("Unable to create proxy: {}", e)))?;
builder = builder.proxy(proxy);
}
let client = builder
.build()
.map_err(|e| ErrorKind::Internal(format!("Unable to build client: {}", e)))?;
.map_err(|e| Error::Internal(format!("Unable to build client: {}", e)))?;
Ok(Client { client })
}
@@ -273,9 +229,8 @@ impl Client {
where
IN: Serialize,
{
let json = serde_json::to_string(input).context(ErrorKind::Internal(
"Could not serialize data to JSON".to_owned(),
))?;
let json = serde_json::to_string(input)
.map_err(|_| Error::Internal("Could not serialize data to JSON".to_owned()))?;
self.build_request(url, Method::POST, api_secret, Some(json))
}
@@ -284,10 +239,8 @@ impl Client {
for<'de> T: Deserialize<'de>,
{
let data = self.send_request(req)?;
serde_json::from_str(&data).map_err(|e| {
e.context(ErrorKind::ResponseError("Cannot parse response".to_owned()))
.into()
})
serde_json::from_str(&data)
.map_err(|_| Error::ResponseError("Cannot parse response".to_owned()))
}
async fn handle_request_async<T>(&self, req: RequestBuilder) -> Result<T, Error>
@@ -296,7 +249,7 @@ impl Client {
{
let data = self.send_request_async(req).await?;
let ser = serde_json::from_str(&data)
.map_err(|e| e.context(ErrorKind::ResponseError("Cannot parse response".to_owned())))?;
.map_err(|_| Error::ResponseError("Cannot parse response".to_owned()))?;
Ok(ser)
}
@@ -304,11 +257,11 @@ impl Client {
let resp = req
.send()
.await
.map_err(|e| ErrorKind::RequestError(format!("Cannot make request: {}", e)))?;
.map_err(|e| Error::RequestError(format!("Cannot make request: {}", e)))?;
let text = resp
.text()
.await
.map_err(|e| ErrorKind::ResponseError(format!("Cannot parse response: {}", e)))?;
.map_err(|e| Error::ResponseError(format!("Cannot parse response: {}", e)))?;
Ok(text)
}
+1 -1
View File
@@ -15,4 +15,4 @@
mod client;
pub mod json_rpc;
pub use client::{Client, Error as ClientError, ErrorKind as ClientErrorKind, RUNTIME};
pub use client::{Client, Error as ClientError, RUNTIME};
+27 -133
View File
@@ -17,194 +17,88 @@ use crate::core::libtx;
use crate::keychain;
use crate::libwallet;
use crate::util::secp;
use failure::{Backtrace, Context, Fail};
use grin_wallet_util::OnionV3AddressError;
use std::env;
use std::fmt::{self, Display};
/// Error definition
#[derive(Debug)]
pub struct Error {
pub inner: Context<ErrorKind>,
}
/// Wallet errors, mostly wrappers around underlying crypto or I/O errors.
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
pub enum ErrorKind {
#[derive(Clone, thiserror::Error, Eq, PartialEq, Debug)]
pub enum Error {
/// LibTX Error
#[fail(display = "LibTx Error")]
LibTX(libtx::ErrorKind),
#[error("LibTx Error")]
LibTX(#[from] libtx::Error),
/// LibWallet Error
#[fail(display = "LibWallet Error: {}", _1)]
LibWallet(libwallet::ErrorKind, String),
#[error("LibWallet Error: {0}")]
LibWallet(#[from] libwallet::Error),
/// Keychain error
#[fail(display = "Keychain error")]
Keychain(keychain::Error),
#[error("Keychain error")]
Keychain(#[from] keychain::Error),
/// Onion V3 Address Error
#[fail(display = "Onion V3 Address Error")]
OnionV3Address(OnionV3AddressError),
#[error("Onion V3 Address Error")]
OnionV3Address(#[from] OnionV3AddressError),
/// Error when obfs4proxy is not in the user path if TOR brigde is enabled
#[fail(display = "Unable to find obfs4proxy binary in your path; {}", _0)]
#[error("Unable to find obfs4proxy binary in your path; {}", _0)]
Obfs4proxyBin(String),
/// Error the bridge input is in bad format
#[fail(display = "Bridge line is in bad format; {}", _0)]
#[error("Bridge line is in bad format; {}", _0)]
BridgeLine(String),
/// Error when formatting json
#[fail(display = "IO error")]
#[error("IO error")]
IO,
/// Secp Error
#[fail(display = "Secp error")]
Secp(secp::Error),
#[error("Secp error")]
Secp(#[from] secp::Error),
/// Error when formatting json
#[fail(display = "Serde JSON error")]
#[error("Serde JSON error")]
Format,
/// Wallet seed already exists
#[fail(display = "Wallet seed file exists: {}", _0)]
#[error("Wallet seed file exists: {}", _0)]
WalletSeedExists(String),
/// Wallet seed doesn't exist
#[fail(display = "Wallet seed doesn't exist error")]
#[error("Wallet seed doesn't exist error")]
WalletSeedDoesntExist,
/// Wallet seed doesn't exist
#[fail(display = "Wallet doesn't exist at {}. {}", _0, _1)]
#[error("Wallet doesn't exist at {}. {}", _0, _1)]
WalletDoesntExist(String, String),
/// Enc/Decryption Error
#[fail(display = "Enc/Decryption error (check password?)")]
#[error("Enc/Decryption error (check password?)")]
Encryption,
/// BIP 39 word list
#[fail(display = "BIP39 Mnemonic (word list) Error")]
#[error("BIP39 Mnemonic (word list) Error")]
Mnemonic,
/// Command line argument error
#[fail(display = "{}", _0)]
#[error("{}", _0)]
ArgumentError(String),
/// Tor Bridge error
#[fail(display = "Tor Bridge Error: {}", _0)]
#[error("Tor Bridge Error: {}", _0)]
TorBridge(String),
/// Tor Proxy error
#[fail(display = "Tor Proxy Error: {}", _0)]
#[error("Tor Proxy Error: {}", _0)]
TorProxy(String),
/// Generating ED25519 Public Key
#[fail(display = "Error generating ed25519 secret key: {}", _0)]
#[error("Error generating ed25519 secret key: {}", _0)]
ED25519Key(String),
/// Checking for onion address
#[fail(display = "Address is not an Onion v3 Address: {}", _0)]
#[error("Address is not an Onion v3 Address: {}", _0)]
NotOnion(String),
/// Other
#[fail(display = "Generic error: {}", _0)]
#[error("Generic error: {}", _0)]
GenericError(String),
}
impl Fail for Error {
fn cause(&self) -> Option<&dyn Fail> {
self.inner.cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let show_bt = match env::var("RUST_BACKTRACE") {
Ok(r) => r == "1",
Err(_) => false,
};
let backtrace = match self.backtrace() {
Some(b) => format!("{}", b),
None => String::from("Unknown"),
};
let inner_output = format!("{}", self.inner,);
let backtrace_output = format!("\nBacktrace: {}", backtrace);
let mut output = inner_output;
if show_bt {
output.push_str(&backtrace_output);
}
Display::fmt(&output, f)
}
}
impl Error {
/// get kind
pub fn kind(&self) -> ErrorKind {
self.inner.get_context().clone()
}
/// get cause
pub fn cause(&self) -> Option<&dyn Fail> {
self.inner.cause()
}
/// get backtrace
pub fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error {
inner: Context::new(kind),
}
}
}
impl From<Context<ErrorKind>> for Error {
fn from(inner: Context<ErrorKind>) -> Error {
Error { inner: inner }
}
}
impl From<keychain::Error> for Error {
fn from(error: keychain::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Keychain(error)),
}
}
}
impl From<secp::Error> for Error {
fn from(error: secp::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Secp(error)),
}
}
}
impl From<libwallet::Error> for Error {
fn from(error: libwallet::Error) -> Error {
Error {
inner: Context::new(ErrorKind::LibWallet(error.kind(), format!("{}", error))),
}
}
}
impl From<libtx::Error> for Error {
fn from(error: libtx::Error) -> Error {
Error {
inner: Context::new(ErrorKind::LibTX(error.kind())),
}
}
}
impl From<OnionV3AddressError> for Error {
fn from(error: OnionV3AddressError) -> Error {
Error::from(ErrorKind::OnionV3Address(error))
}
}
+1 -1
View File
@@ -48,7 +48,7 @@ pub use crate::adapters::{
SlateSender,
};
pub use crate::backends::{wallet_db_exists, LMDBBackend};
pub use crate::error::{Error, ErrorKind};
pub use crate::error::Error;
pub use crate::lifecycle::DefaultLCProvider;
pub use crate::node_clients::HTTPNodeClient;
+35 -44
View File
@@ -19,14 +19,11 @@ use crate::config::{
};
use crate::core::global;
use crate::keychain::Keychain;
use crate::libwallet::{
Error, ErrorKind, NodeClient, WalletBackend, WalletInitStatus, WalletLCProvider,
};
use crate::libwallet::{Error, NodeClient, WalletBackend, WalletInitStatus, WalletLCProvider};
use crate::lifecycle::seed::WalletSeed;
use crate::util::secp::key::SecretKey;
use crate::util::ZeroingString;
use crate::LMDBBackend;
use failure::ResultExt;
use grin_wallet_util::grin_util::logger::LoggingConfig;
use std::fs;
use std::path::PathBuf;
@@ -132,7 +129,7 @@ where
file_name,
config_file_name.to_str().unwrap()
);
return Err(ErrorKind::Lifecycle(msg).into());
return Err(Error::Lifecycle(msg));
}
// just leave as is if file exists but there's no data dir
@@ -152,7 +149,7 @@ where
config_file_name.to_str().unwrap(),
e
);
return Err(ErrorKind::Lifecycle(msg).into());
return Err(Error::Lifecycle(msg));
}
info!(
@@ -186,7 +183,7 @@ where
if !test_mode {
if let Ok(true) = exists {
let msg = format!("Wallet seed already exists at: {}", data_dir_name);
return Err(ErrorKind::WalletSeedExists(msg).into());
return Err(Error::WalletSeedExists(msg));
}
}
WalletSeed::init_file(
@@ -196,16 +193,16 @@ where
password,
test_mode,
)
.context(ErrorKind::Lifecycle(
"Error creating wallet seed (is mnemonic valid?)".into(),
))?;
.map_err(|_| {
Error::Lifecycle("Error creating wallet seed (is mnemonic valid?)".to_owned())
})?;
info!("Wallet seed file created");
let mut wallet: LMDBBackend<'a, C, K> =
match LMDBBackend::new(&data_dir_name, self.node_client.clone()) {
Err(e) => {
let msg = format!("Error creating wallet: {}, Data Dir: {}", e, &data_dir_name);
error!("{}", msg);
return Err(ErrorKind::Lifecycle(msg).into());
return Err(Error::Lifecycle(msg).into());
}
Ok(d) => d,
};
@@ -234,16 +231,16 @@ where
match LMDBBackend::new(&data_dir_name, self.node_client.clone()) {
Err(e) => {
let msg = format!("Error opening wallet: {}, Data Dir: {}", e, &data_dir_name);
return Err(ErrorKind::Lifecycle(msg).into());
return Err(Error::Lifecycle(msg));
}
Ok(d) => d,
};
let wallet_seed = WalletSeed::from_file(&data_dir_name, password).context(
ErrorKind::Lifecycle("Error opening wallet (is password correct?)".into()),
)?;
let wallet_seed = WalletSeed::from_file(&data_dir_name, password).map_err(|_| {
Error::Lifecycle("Error opening wallet (is password correct?)".to_owned())
})?;
let keychain = wallet_seed
.derive_keychain(global::is_testnet())
.context(ErrorKind::Lifecycle("Error deriving keychain".into()))?;
.map_err(|_| Error::Lifecycle("Error deriving keychain".to_owned()))?;
let mask = wallet.set_keychain(Box::new(keychain), create_mask, use_test_rng)?;
self.backend = Some(Box::new(wallet));
@@ -262,9 +259,8 @@ where
let mut data_dir_name = PathBuf::from(self.data_dir.clone());
data_dir_name.push(GRIN_WALLET_DIR);
let data_dir_name = data_dir_name.to_str().unwrap();
let res = WalletSeed::seed_file_exists(&data_dir_name).context(ErrorKind::CallbackImpl(
"Error checking for wallet existence",
))?;
let res = WalletSeed::seed_file_exists(&data_dir_name)
.map_err(|_| Error::CallbackImpl("Error checking for wallet existence"))?;
Ok(res)
}
@@ -276,19 +272,18 @@ where
let mut data_dir_name = PathBuf::from(self.data_dir.clone());
data_dir_name.push(GRIN_WALLET_DIR);
let data_dir_name = data_dir_name.to_str().unwrap();
let wallet_seed = WalletSeed::from_file(&data_dir_name, password).context(
ErrorKind::Lifecycle("Error opening wallet seed file".into()),
)?;
let wallet_seed = WalletSeed::from_file(&data_dir_name, password)
.map_err(|_| Error::Lifecycle("Error opening wallet seed file".into()))?;
let res = wallet_seed
.to_mnemonic()
.context(ErrorKind::Lifecycle("Error recovering wallet seed".into()))?;
.map_err(|_| Error::Lifecycle("Error recovering wallet seed".into()))?;
Ok(ZeroingString::from(res))
}
fn validate_mnemonic(&self, mnemonic: ZeroingString) -> Result<(), Error> {
match WalletSeed::from_mnemonic(mnemonic) {
Ok(_) => Ok(()),
Err(_) => Err(ErrorKind::GenericError("Validating mnemonic".into()).into()),
Err(_) => Err(Error::GenericError("Validating mnemonic".into())),
}
}
@@ -300,9 +295,8 @@ where
let mut data_dir_name = PathBuf::from(self.data_dir.clone());
data_dir_name.push(GRIN_WALLET_DIR);
let data_dir_name = data_dir_name.to_str().unwrap();
WalletSeed::recover_from_phrase(data_dir_name, mnemonic, password).context(
ErrorKind::Lifecycle("Error recovering from mnemonic".into()),
)?;
WalletSeed::recover_from_phrase(data_dir_name, mnemonic, password)
.map_err(|_| Error::Lifecycle("Error recovering from mnemonic".into()))?;
Ok(())
}
@@ -317,23 +311,21 @@ where
let data_dir_name = data_dir_name.to_str().unwrap();
// get seed for later check
let orig_wallet_seed = WalletSeed::from_file(&data_dir_name, old).context(
ErrorKind::Lifecycle("Error opening wallet seed file".into()),
)?;
let orig_wallet_seed = WalletSeed::from_file(&data_dir_name, old)
.map_err(|_| Error::Lifecycle("Error opening wallet seed file".into()))?;
let orig_mnemonic = orig_wallet_seed
.to_mnemonic()
.context(ErrorKind::Lifecycle("Error recovering mnemonic".into()))?;
.map_err(|_| Error::Lifecycle("Error recovering mnemonic".into()))?;
// Back up existing seed, and keep track of filename as we're deleting it
// once the password change is confirmed
let backup_name = WalletSeed::backup_seed(data_dir_name).context(ErrorKind::Lifecycle(
"Error temporarily backing up existing seed".into(),
))?;
let backup_name = WalletSeed::backup_seed(data_dir_name)
.map_err(|_| Error::Lifecycle("Error temporarily backing up existing seed".into()))?;
// Delete seed file
WalletSeed::delete_seed_file(data_dir_name).context(ErrorKind::Lifecycle(
"Unable to delete seed file for password change".into(),
))?;
WalletSeed::delete_seed_file(data_dir_name).map_err(|_| {
Error::Lifecycle("Unable to delete seed file for password change".into())
})?;
// Init a new file
let _ = WalletSeed::init_file(
@@ -345,19 +337,18 @@ where
);
info!("Wallet seed file created");
let new_wallet_seed = WalletSeed::from_file(&data_dir_name, new).context(
ErrorKind::Lifecycle("Error opening wallet seed file".into()),
)?;
let new_wallet_seed = WalletSeed::from_file(&data_dir_name, new)
.map_err(|_| Error::Lifecycle("Error opening wallet seed file".into()))?;
if orig_wallet_seed != new_wallet_seed {
let msg =
"New and Old wallet seeds are not equal on password change, not removing backups."
.to_string();
return Err(ErrorKind::Lifecycle(msg).into());
return Err(Error::Lifecycle(msg));
}
// Removin
info!("Password change confirmed, removing old seed file.");
fs::remove_file(backup_name).context(ErrorKind::IO)?;
fs::remove_file(backup_name).map_err(|e| Error::IO(e.to_string()))?;
Ok(())
}
@@ -368,7 +359,7 @@ where
"Removing all wallet data from: {}",
data_dir_name.to_str().unwrap()
);
fs::remove_dir_all(data_dir_name).context(ErrorKind::IO)?;
fs::remove_dir_all(data_dir_name).map_err(|e| Error::IO(e.to_string()))?;
Ok(())
}
@@ -376,7 +367,7 @@ where
match self.backend.as_mut() {
None => {
let msg = "Wallet has not been opened".into();
Err(ErrorKind::Lifecycle(msg).into())
Err(Error::Lifecycle(msg))
}
Some(_) => Ok(&mut *self.backend.as_mut().unwrap()),
}
+25 -26
View File
@@ -27,8 +27,7 @@ use ring::pbkdf2;
use crate::keychain::{mnemonic, Keychain};
use crate::util::{self, ToHex};
use crate::{Error, ErrorKind};
use failure::ResultExt;
use crate::Error;
pub const SEED_FILE: &str = "wallet.seed";
@@ -44,13 +43,13 @@ impl WalletSeed {
let res = mnemonic::to_entropy(&word_list);
match res {
Ok(s) => Ok(WalletSeed::from_bytes(&s)),
Err(_) => Err(ErrorKind::Mnemonic.into()),
Err(_) => Err(Error::Mnemonic.into()),
}
}
pub fn _from_hex(hex: &str) -> Result<WalletSeed, Error> {
let bytes = util::from_hex(&hex.to_string())
.map_err(|_| ErrorKind::GenericError("Invalid hex".to_owned()))?;
.map_err(|_| Error::GenericError("Invalid hex".to_owned()))?;
Ok(WalletSeed::from_bytes(&bytes))
}
@@ -62,7 +61,7 @@ impl WalletSeed {
let result = mnemonic::from_entropy(&self.0);
match result {
Ok(r) => Ok(r),
Err(_) => Err(ErrorKind::Mnemonic.into()),
Err(_) => Err(Error::Mnemonic.into()),
}
}
@@ -122,7 +121,7 @@ impl WalletSeed {
}
path.push(backup_seed_file_name.clone());
if fs::rename(seed_file_name, backup_seed_file_name.as_str()).is_err() {
return Err(ErrorKind::GenericError("Can't rename wallet seed file".to_owned()).into());
return Err(Error::GenericError("Can't rename wallet seed file".to_owned()).into());
}
warn!("{} backed up as {}", seed_file_name, backup_seed_file_name);
Ok(backup_seed_file_name)
@@ -140,7 +139,7 @@ impl WalletSeed {
WalletSeed::backup_seed(data_file_dir)?;
}
if !Path::new(&data_file_dir).exists() {
return Err(ErrorKind::WalletDoesntExist(
return Err(Error::WalletDoesntExist(
data_file_dir.to_owned(),
"To create a new wallet from a recovery phrase, use 'grin-wallet init -r'"
.to_owned(),
@@ -149,10 +148,10 @@ impl WalletSeed {
}
let seed = WalletSeed::from_mnemonic(word_list)?;
let enc_seed = EncryptedWalletSeed::from_seed(&seed, password)?;
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).context(ErrorKind::Format)?;
let mut file = File::create(seed_file_path).context(ErrorKind::IO)?;
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).map_err(|_| Error::Format)?;
let mut file = File::create(seed_file_path).map_err(|_| Error::IO)?;
file.write_all(&enc_seed_json.as_bytes())
.context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
warn!("Seed created from word list");
Ok(())
}
@@ -165,7 +164,7 @@ impl WalletSeed {
test_mode: bool,
) -> Result<WalletSeed, Error> {
// create directory if it doesn't exist
fs::create_dir_all(data_file_dir).context(ErrorKind::IO)?;
fs::create_dir_all(data_file_dir).map_err(|_| Error::IO)?;
let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,);
@@ -174,7 +173,7 @@ impl WalletSeed {
if exists && !test_mode {
let msg = format!("Wallet seed already exists at: {}", data_file_dir);
error!("{}", msg);
return Err(ErrorKind::WalletSeedExists(msg).into());
return Err(Error::WalletSeedExists(msg));
}
let seed = match recovery_phrase {
@@ -183,10 +182,10 @@ impl WalletSeed {
};
let enc_seed = EncryptedWalletSeed::from_seed(&seed, password)?;
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).context(ErrorKind::Format)?;
let mut file = File::create(seed_file_path).context(ErrorKind::IO)?;
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).map_err(|_| Error::Format)?;
let mut file = File::create(seed_file_path).map_err(|_| Error::IO)?;
file.write_all(&enc_seed_json.as_bytes())
.context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
Ok(seed)
}
@@ -195,18 +194,18 @@ impl WalletSeed {
password: util::ZeroingString,
) -> Result<WalletSeed, Error> {
// create directory if it doesn't exist
fs::create_dir_all(data_file_dir).context(ErrorKind::IO)?;
fs::create_dir_all(data_file_dir).map_err(|_| Error::IO)?;
let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,);
debug!("Using wallet seed file at: {}", seed_file_path);
if Path::new(seed_file_path).exists() {
let mut file = File::open(seed_file_path).context(ErrorKind::IO)?;
let mut file = File::open(seed_file_path).map_err(|_| Error::IO)?;
let mut buffer = String::new();
file.read_to_string(&mut buffer).context(ErrorKind::IO)?;
file.read_to_string(&mut buffer).map_err(|_| Error::IO)?;
let enc_seed: EncryptedWalletSeed =
serde_json::from_str(&buffer).context(ErrorKind::Format)?;
serde_json::from_str(&buffer).map_err(|_| Error::Format)?;
let wallet_seed = enc_seed.decrypt(&password)?;
Ok(wallet_seed)
} else {
@@ -215,7 +214,7 @@ impl WalletSeed {
Run \"grin-wallet init\" to initialize a new wallet.",
seed_file_path
);
Err(ErrorKind::WalletSeedDoesntExist.into())
Err(Error::WalletSeedDoesntExist)
}
}
@@ -223,7 +222,7 @@ impl WalletSeed {
let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,);
if Path::new(seed_file_path).exists() {
debug!("Deleting wallet seed file at: {}", seed_file_path);
fs::remove_file(seed_file_path).context(ErrorKind::IO)?;
fs::remove_file(seed_file_path).map_err(|_| Error::IO)?;
}
Ok(())
}
@@ -274,7 +273,7 @@ impl EncryptedWalletSeed {
&mut enc_bytes,
);
if let Err(_) = res {
return Err(ErrorKind::Encryption.into());
return Err(Error::Encryption);
}
Ok(EncryptedWalletSeed {
@@ -288,15 +287,15 @@ impl EncryptedWalletSeed {
pub fn decrypt(&self, password: &str) -> Result<WalletSeed, Error> {
let mut encrypted_seed = match util::from_hex(&self.encrypted_seed.clone()) {
Ok(s) => s,
Err(_) => return Err(ErrorKind::Encryption.into()),
Err(_) => return Err(Error::Encryption),
};
let salt = match util::from_hex(&self.salt.clone()) {
Ok(s) => s,
Err(_) => return Err(ErrorKind::Encryption.into()),
Err(_) => return Err(Error::Encryption),
};
let nonce = match util::from_hex(&self.nonce.clone()) {
Ok(s) => s,
Err(_) => return Err(ErrorKind::Encryption.into()),
Err(_) => return Err(Error::Encryption),
};
let password = password.as_bytes();
let mut key = [0; 32];
@@ -319,7 +318,7 @@ impl EncryptedWalletSeed {
&mut encrypted_seed,
);
if let Err(_) = res {
return Err(ErrorKind::Encryption.into());
return Err(Error::Encryption);
}
for _ in 0..aead::AES_256_GCM.tag_len() {
encrypted_seed.pop();
+10 -10
View File
@@ -47,7 +47,7 @@ impl HTTPNodeClient {
node_api_secret: Option<String>,
) -> Result<HTTPNodeClient, libwallet::Error> {
Ok(HTTPNodeClient {
client: Client::new().map_err(|_| libwallet::ErrorKind::Node)?,
client: Client::new().map_err(|_| libwallet::Error::Node)?,
node_url: node_url.to_owned(),
node_api_secret: node_api_secret,
node_version_info: None,
@@ -74,7 +74,7 @@ impl HTTPNodeClient {
Err(e) => {
let report = format!("Error calling {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
Err(libwallet::Error::ClientCallback(report))
}
Ok(inner) => match inner.clone().into_result() {
Ok(r) => Ok(r),
@@ -82,7 +82,7 @@ impl HTTPNodeClient {
error!("{:?}", inner);
let report = format!("Unable to parse response for {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
Err(libwallet::Error::ClientCallback(report))
}
},
}
@@ -170,7 +170,7 @@ impl NodeClient for HTTPNodeClient {
Err(e) => {
let report = format!("Error calling {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
Err(libwallet::Error::ClientCallback(report))
}
Ok(inner) => match inner.clone().into_result::<LocatedTxKernel>() {
Ok(r) => Ok(Some((r.tx_kernel, r.height, r.mmr_index))),
@@ -181,7 +181,7 @@ impl NodeClient for HTTPNodeClient {
} else {
let report = format!("Unable to parse response for {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
Err(libwallet::Error::ClientCallback(report))
}
}
},
@@ -270,7 +270,7 @@ impl NodeClient for HTTPNodeClient {
Err(e) => {
let report = format!("Unable to parse response for get_outputs: {}", e);
error!("{}", report);
return Err(libwallet::ErrorKind::ClientCallback(report).into());
return Err(libwallet::Error::ClientCallback(report));
}
};
}
@@ -279,7 +279,7 @@ impl NodeClient for HTTPNodeClient {
Err(e) => {
let report = format!("Getting outputs by id: {}", e);
error!("Outputs by id failed: {}", e);
return Err(libwallet::ErrorKind::ClientCallback(report).into());
return Err(libwallet::Error::ClientCallback(report));
}
};
@@ -288,7 +288,7 @@ impl NodeClient for HTTPNodeClient {
Some(h) => h,
None => {
let msg = format!("Missing block height for output {:?}", out.commit);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
return Err(libwallet::Error::ClientCallback(msg));
}
};
api_outputs.insert(
@@ -331,7 +331,7 @@ impl NodeClient for HTTPNodeClient {
out.commit, out, e
);
error!("{}", msg);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
return Err(libwallet::Error::ClientCallback(msg));
}
};
let block_height = match out.block_height {
@@ -342,7 +342,7 @@ impl NodeClient for HTTPNodeClient {
out.commit, out
);
error!("{}", msg);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
return Err(libwallet::Error::ClientCallback(msg));
}
};
api_outputs.push((
+37 -40
View File
@@ -32,7 +32,6 @@ use crate::util::secp::key::SecretKey;
use crate::util::secp::pedersen;
use crate::util::secp::pedersen::Commitment;
use crate::util::{Mutex, ToHex};
use failure::ResultExt;
use serde_json;
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
@@ -181,9 +180,9 @@ where
fn post_tx(&mut self, m: WalletProxyMessage) -> Result<WalletProxyMessage, libwallet::Error> {
let dest_wallet = self.wallets.get_mut(&m.sender_id).unwrap().1.clone();
let dest_wallet_mask = self.wallets.get_mut(&m.sender_id).unwrap().2.clone();
let tx: Transaction = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Error parsing Transaction".to_owned()),
)?;
let tx: Transaction = serde_json::from_str(&m.body).map_err(|_| {
libwallet::Error::ClientCallback("Error parsing Transaction".to_owned())
})?;
super::award_block_to_wallet(
&self.chain,
@@ -211,9 +210,8 @@ where
Some(w) => w,
};
let slate: SlateV4 = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper".to_owned()),
)?;
let slate: SlateV4 = serde_json::from_str(&m.body)
.map_err(|_| libwallet::Error::ClientCallback("Error parsing TxWrapper".to_owned()))?;
let slate: Slate = {
let mut w_lock = wallet.1.lock();
@@ -403,16 +401,15 @@ impl LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"Send TX Slate".to_owned(),
))?;
p.send(m)
.map_err(|_| libwallet::Error::ClientCallback("Send TX Slate".to_owned()))?;
}
let r = self.rx.lock();
let m = r.recv().unwrap();
trace!("Received send_tx_slate response: {:?}", m.clone());
let slate: SlateV4 = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Parsing send_tx_slate response".to_owned()),
)?;
let slate: SlateV4 = serde_json::from_str(&m.body).map_err(|_| {
libwallet::Error::ClientCallback("Parsing send_tx_slate response".to_owned())
})?;
Ok(Slate::from(slate))
}
}
@@ -440,9 +437,8 @@ impl NodeClient for LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"post_tx send".to_owned(),
))?;
p.send(m)
.map_err(|_| libwallet::Error::ClientCallback("post_tx send".to_owned()))?;
}
let r = self.rx.lock();
let m = r.recv().unwrap();
@@ -460,19 +456,16 @@ impl NodeClient for LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"Get chain height send".to_owned(),
))?;
p.send(m).map_err(|_| {
libwallet::Error::ClientCallback("Get chain height send".to_owned())
})?;
}
let r = self.rx.lock();
let m = r.recv().unwrap();
trace!("Received get_chain_tip response: {:?}", m.clone());
let res = m
.body
.parse::<String>()
.context(libwallet::ErrorKind::ClientCallback(
"Parsing get_height response".to_owned(),
))?;
let res = m.body.parse::<String>().map_err(|_| {
libwallet::Error::ClientCallback("Parsing get_height response".to_owned())
})?;
let split: Vec<&str> = res.split(',').collect();
Ok((split[0].parse::<u64>().unwrap(), split[1].to_owned()))
}
@@ -495,9 +488,9 @@ impl NodeClient for LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"Get outputs from node send".to_owned(),
))?;
p.send(m).map_err(|_| {
libwallet::Error::ClientCallback("Get outputs from node send".to_owned())
})?;
}
let r = self.rx.lock();
let m = r.recv().unwrap();
@@ -538,15 +531,17 @@ impl NodeClient for LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"Get outputs from node by PMMR index send".to_owned(),
))?;
p.send(m).map_err(|_| {
libwallet::Error::ClientCallback(
"Get outputs from node by PMMR index send".to_owned(),
)
})?;
}
let r = self.rx.lock();
let m = r.recv().unwrap();
let res: Option<LocatedTxKernel> = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Get transaction kernels send".to_owned()),
)?;
let res: Option<LocatedTxKernel> = serde_json::from_str(&m.body).map_err(|_| {
libwallet::Error::ClientCallback("Get transaction kernels send".to_owned())
})?;
match res {
Some(k) => Ok(Some((k.tx_kernel, k.height, k.mmr_index))),
None => Ok(None),
@@ -580,9 +575,11 @@ impl NodeClient for LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"Get outputs from node by PMMR index send".to_owned(),
))?;
p.send(m).map_err(|_| {
libwallet::Error::ClientCallback(
"Get outputs from node by PMMR index send".to_owned(),
)
})?;
}
let r = self.rx.lock();
@@ -627,9 +624,9 @@ impl NodeClient for LocalWalletClient {
};
{
let p = self.proxy_tx.lock();
p.send(m).context(libwallet::ErrorKind::ClientCallback(
"Get outputs within height range send".to_owned(),
))?;
p.send(m).map_err(|_| {
libwallet::Error::ClientCallback("Get outputs within height range send".to_owned())
})?;
}
let r = self.rx.lock();
+22 -23
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::{Error, ErrorKind};
use crate::Error;
use base64;
use grin_wallet_config::types::TorBridgeConfig;
use std::collections::HashMap;
@@ -165,13 +165,13 @@ impl Transport {
match arg {
Some(addr) => {
let address = addr.parse::<SocketAddr>().map_err(|_e| {
ErrorKind::TorBridge(format!("Invalid bridge server address: {}", addr).into())
Error::TorBridge(format!("Invalid bridge server address: {}", addr))
})?;
Ok(address.to_string())
}
None => {
let msg = format!("Missing bridge server address");
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
@@ -185,7 +185,7 @@ impl Transport {
let fingerprint = fgp.to_uppercase();
if !(is_hex && fingerprint.len() == 40) {
let msg = format!("Invalid fingerprint: {}", fingerprint);
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg));
}
Ok(Some(fingerprint))
}
@@ -195,14 +195,14 @@ impl Transport {
/// Parse the certificate of the bridge line (obfs4)
pub fn parse_cert_arg(arg: &str) -> Result<String, Error> {
let cert_vec = base64::decode(arg).map_err(|_e| {
ErrorKind::TorBridge(format!(
Error::TorBridge(format!(
"Invalid certificate, error decoding bridge certificate: {}",
arg
))
})?;
if cert_vec.len() != 52 {
let msg = format!("Invalid certificate: {}", arg);
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg).into());
}
Ok(arg.to_string())
}
@@ -211,7 +211,7 @@ impl Transport {
let iatmode = arg.parse::<u8>().unwrap_or(0);
if !((0..3).contains(&iatmode)) {
let msg = format!("Invalid iatmode: {}, must be between 0 and 2", iatmode);
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg));
}
Ok(iatmode.to_string())
}
@@ -219,7 +219,7 @@ impl Transport {
/// Parse the max value for the arg -max in the client line option (snowflake)
fn parse_hpkp_arg(arg: &str) -> Result<String, Error> {
let max = arg.parse::<bool>().map_err(|_e| {
ErrorKind::TorBridge(
Error::TorBridge(
format!("Invalid -max value: {}, must be \"true\" or \"false\"", arg).into(),
)
})?;
@@ -289,7 +289,7 @@ impl PluginClient {
Some(path) => Ok(path.into_os_string().into_string().unwrap()),
None => {
let msg = format!("Transport client \"{}\" is missing, make sure it's installed and on your path.", plugin);
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
@@ -298,15 +298,14 @@ impl PluginClient {
fn parse_url_arg(arg: &str) -> Result<String, Error> {
let url = arg
.parse::<Url>()
.map_err(|_e| ErrorKind::TorBridge(format!("Invalid -url value: {}", arg).into()))?;
.map_err(|_e| Error::TorBridge(format!("Invalid -url value: {}", arg)))?;
Ok(url.to_string())
}
/// Parse the DNS domain value for the arg -front in the client line option (snowflake)
fn parse_front_arg(arg: &str) -> Result<String, Error> {
let front = Host::parse(arg).map_err(|_e| {
ErrorKind::TorBridge(format!("Invalid -front hostname value: {}", arg).into())
})?;
let front = Host::parse(arg)
.map_err(|_e| Error::TorBridge(format!("Invalid -front hostname value: {}", arg)))?;
match front {
Host::Domain(_) => Ok(front.to_string()),
Host::Ipv4(_) | Host::Ipv6(_) => {
@@ -314,7 +313,7 @@ impl PluginClient {
"Invalid front argument: {}, in the client option. Must be a DNS Domain",
front
);
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
@@ -328,13 +327,13 @@ impl PluginClient {
if addr.starts_with("stun:") || addr.starts_with("turn:") {
let address = addr.replace("stun:", "").replace("turn:", "");
let _p_address = TorProxy::parse_address(&address)
.map_err(|e| ErrorKind::TorBridge(format!("{}", e.kind()).into()))?;
.map_err(|e| Error::TorBridge(format!("{}", e)))?;
} else {
let msg = format!(
"Invalid ICE address: {}. Must be a stun or turn address",
addr
);
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg).into());
}
}
Ok(ice_addr.to_string())
@@ -346,7 +345,7 @@ impl PluginClient {
Ok(max) => Ok(max.to_string()),
Err(_e) => {
let msg = format!("Invalid -max argument: {} in the client option.", arg);
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
@@ -358,7 +357,7 @@ impl PluginClient {
"ERROR" | "WARN" | "INFO" | "DEBUG" => Ok(log_level.to_string()),
_ => {
let msg = format!("Invalid log level argurment: {}, in the client option. Must be: ERROR, WARN, INFO or DEBUG", log_level);
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
@@ -377,7 +376,7 @@ impl PluginClient {
} else {
format!("Missing ICE argurment for snowflake transport, specify \"-ice\"")
};
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg));
}
for (key, value) in hm_flags {
let p_value = match key {
@@ -517,7 +516,7 @@ impl TorBridge {
"Invalid transport method: {} - must be obfs4/meek_lite/meek/snowflake",
transport
);
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
@@ -544,7 +543,7 @@ impl TryFrom<TorBridgeConfig> for TorBridge {
None => {
let msg =
format!("Missing cert argurment in obfs4 transport, specify \"cert=\"");
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg));
}
};
let iatmode = match flags.get_key_value("iat-mode=") {
@@ -582,7 +581,7 @@ impl TryFrom<TorBridgeConfig> for TorBridge {
let msg = format!(
"Missing url argurment in meek_lite transport, specify \"url=\""
);
return Err(ErrorKind::TorBridge(msg).into());
return Err(Error::TorBridge(msg));
}
};
let front = match flags.get_key_value("front=") {
@@ -654,7 +653,7 @@ impl TryFrom<TorBridgeConfig> for TorBridge {
"Invalid transport method: {} - must be obfs4/meek_lite/meek/snowflake",
transport
);
Err(ErrorKind::TorBridge(msg).into())
Err(Error::TorBridge(msg))
}
}
}
+21 -23
View File
@@ -14,7 +14,7 @@
//! Tor Configuration + Onion (Hidden) Service operations
use crate::util::secp::key::SecretKey;
use crate::{Error, ErrorKind};
use crate::Error;
use grin_wallet_util::OnionV3Address;
use ed25519_dalek::ExpandedSecretKey;
@@ -27,8 +27,6 @@ use std::io::Write;
use std::path::{Path, MAIN_SEPARATOR};
use std::string::String;
use failure::ResultExt;
const SEC_KEY_FILE: &str = "hs_ed25519_secret_key";
const PUB_KEY_FILE: &str = "hs_ed25519_public_key";
const HOSTNAME_FILE: &str = "hostname";
@@ -40,7 +38,7 @@ const HIDDEN_SERVICES_DIR: &str = "onion_service_addresses";
#[cfg(unix)]
fn set_permissions(file_path: &str) -> Result<(), Error> {
use std::os::unix::prelude::*;
fs::set_permissions(file_path, fs::Permissions::from_mode(0o700)).context(ErrorKind::IO)?;
fs::set_permissions(file_path, fs::Permissions::from_mode(0o700)).map_err(|_| Error::IO)?;
Ok(())
}
@@ -81,14 +79,14 @@ impl TorRcConfig {
/// write to file
pub fn write_to_file(&self, file_path: &str) -> Result<(), Error> {
let mut file = File::create(file_path).context(ErrorKind::IO)?;
let mut file = File::create(file_path).map_err(|_| Error::IO)?;
for item in &self.items {
file.write_all(item.name.as_bytes())
.context(ErrorKind::IO)?;
file.write_all(b" ").context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
file.write_all(b" ").map_err(|_| Error::IO)?;
file.write_all(item.value.as_bytes())
.context(ErrorKind::IO)?;
file.write_all(b"\n").context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
file.write_all(b"\n").map_err(|_| Error::IO)?;
}
Ok(())
}
@@ -99,13 +97,13 @@ pub fn create_onion_service_sec_key_file(
sec_key: &DalekSecretKey,
) -> Result<(), Error> {
let key_file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, SEC_KEY_FILE);
let mut file = File::create(key_file_path).context(ErrorKind::IO)?;
let mut file = File::create(key_file_path).map_err(|_| Error::IO)?;
// Tag is always 32 bytes, so pad with null zeroes
file.write(b"== ed25519v1-secret: type0 ==\0\0\0")
.context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
let expanded_skey: ExpandedSecretKey = ExpandedSecretKey::from(sec_key);
file.write_all(&expanded_skey.to_bytes())
.context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
Ok(())
}
@@ -114,25 +112,25 @@ pub fn create_onion_service_pub_key_file(
pub_key: &DalekPublicKey,
) -> Result<(), Error> {
let key_file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, PUB_KEY_FILE);
let mut file = File::create(key_file_path).context(ErrorKind::IO)?;
let mut file = File::create(key_file_path).map_err(|_| Error::IO)?;
// Tag is always 32 bytes, so pad with null zeroes
file.write(b"== ed25519v1-public: type0 ==\0\0\0")
.context(ErrorKind::IO)?;
file.write_all(pub_key.as_bytes()).context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
file.write_all(pub_key.as_bytes()).map_err(|_| Error::IO)?;
Ok(())
}
pub fn create_onion_service_hostname_file(os_directory: &str, hostname: &str) -> Result<(), Error> {
let file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, HOSTNAME_FILE);
let mut file = File::create(file_path).context(ErrorKind::IO)?;
let mut file = File::create(file_path).map_err(|_| Error::IO)?;
file.write_all(&format!("{}.onion\n", hostname).as_bytes())
.context(ErrorKind::IO)?;
.map_err(|_| Error::IO)?;
Ok(())
}
pub fn create_onion_auth_clients_dir(os_directory: &str) -> Result<(), Error> {
let auth_dir_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, AUTH_CLIENTS_DIR);
fs::create_dir_all(auth_dir_path).context(ErrorKind::IO)?;
fs::create_dir_all(auth_dir_path).map_err(|_| Error::IO)?;
Ok(())
}
/// output an onion service config for the secret key, and return the address
@@ -141,7 +139,7 @@ pub fn output_onion_service_config(
sec_key: &SecretKey,
) -> Result<OnionV3Address, Error> {
let d_sec_key = DalekSecretKey::from_bytes(&sec_key.0)
.context(ErrorKind::ED25519Key("Unable to parse private key".into()))?;
.map_err(|_| Error::ED25519Key("Unable to parse private key".into()))?;
let address = OnionV3Address::from_private(&sec_key.0)?;
let hs_dir_file_path = format!(
"{}{}{}{}{}",
@@ -154,7 +152,7 @@ pub fn output_onion_service_config(
}
// create directory if it doesn't exist
fs::create_dir_all(&hs_dir_file_path).context(ErrorKind::IO)?;
fs::create_dir_all(&hs_dir_file_path).map_err(|_| Error::IO)?;
create_onion_service_sec_key_file(&hs_dir_file_path, &d_sec_key)?;
create_onion_service_pub_key_file(&hs_dir_file_path, &address.to_ed25519()?)?;
@@ -218,7 +216,7 @@ pub fn output_tor_listener_config(
let tor_data_dir = format!("{}{}{}", tor_config_directory, MAIN_SEPARATOR, TOR_DATA_DIR);
// create data directory if it doesn't exist
fs::create_dir_all(&tor_data_dir).context(ErrorKind::IO)?;
fs::create_dir_all(&tor_data_dir).map_err(|_| Error::IO)?;
let mut service_dirs = vec![];
@@ -248,7 +246,7 @@ pub fn output_tor_sender_config(
hm_tor_proxy: HashMap<String, String>,
) -> Result<(), Error> {
// create data directory if it doesn't exist
fs::create_dir_all(&tor_config_dir).context(ErrorKind::IO)?;
fs::create_dir_all(&tor_config_dir).map_err(|_| Error::IO)?;
output_torrc(
tor_config_dir,
@@ -267,7 +265,7 @@ pub fn is_tor_address(input: &str) -> Result<(), Error> {
Ok(_) => Ok(()),
Err(e) => {
let msg = format!("{:?}", e);
Err(ErrorKind::NotOnion(msg).into())
Err(Error::NotOnion(msg).into())
}
}
}
+5 -5
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::{Error, ErrorKind};
use crate::Error;
use grin_wallet_config::types::TorProxyConfig;
use std::collections::HashMap;
use std::convert::TryFrom;
@@ -72,11 +72,11 @@ impl TorProxy {
pub fn parse_address(addr: &str) -> Result<(String, Option<u16>), Error> {
let (host, str_port) = TorProxy::parse_host_port(&addr)?;
let host = Host::parse(&host)
.map_err(|_e| ErrorKind::TorProxy(format!("Invalid host address: {}", host)))?;
.map_err(|_e| Error::TorProxy(format!("Invalid host address: {}", host)))?;
let port = if let Some(p) = str_port {
let res = p
.parse::<u16>()
.map_err(|_e| ErrorKind::TorProxy(format!("Invalid port number: {}", p)))?;
.map_err(|_e| Error::TorProxy(format!("Invalid port number: {}", p)))?;
Some(res)
} else {
None
@@ -167,7 +167,7 @@ impl TryFrom<TorProxyConfig> for TorProxy {
"Missing proxy address: {} - must be <IP:PORT> or <Hostname>",
transport
);
return Err(ErrorKind::TorProxy(msg).into());
return Err(Error::TorProxy(msg).into());
}
}
// Missing transport type
@@ -176,7 +176,7 @@ impl TryFrom<TorProxyConfig> for TorProxy {
"Invalid proxy transport: {} - must be socks4/socks5/http(s)",
transport
);
Err(ErrorKind::TorProxy(msg).into())
Err(Error::TorProxy(msg).into())
}
}
} else {