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
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 1066 additions and 1586 deletions

635
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -22,8 +22,7 @@ exclude = ["integration"]
[dependencies]
clap = { version = "2.33", features = ["yaml"] }
rpassword = "4.0"
failure = "0.1"
failure_derive = "0.1"
thiserror = "1"
prettytable-rs = "0.8"
log = "0.4"
linefeed = "0.6"

View file

@ -10,8 +10,6 @@ exclude = ["**/*.grin", "**/*.grin2"]
edition = "2018"
[dependencies]
failure = "0.1"
failure_derive = "0.1"
log = "0.4"
uuid = { version = "0.8", features = ["serde", "v4"] }
serde = "1"

View file

@ -16,9 +16,8 @@
use crate::keychain::Keychain;
use crate::libwallet::{
self, BlockFees, CbData, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
NodeVersionInfo, Slate, SlateVersion, VersionInfo, VersionedCoinbase, VersionedSlate,
WalletLCProvider,
self, BlockFees, CbData, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeVersionInfo,
Slate, SlateVersion, VersionInfo, VersionedCoinbase, VersionedSlate, WalletLCProvider,
};
use crate::{Foreign, ForeignCheckMiddlewareFn};
use easy_jsonrpc_mw;
@ -62,7 +61,7 @@ pub trait ForeignRpc {
# ,false, 0, false, false);
```
*/
fn check_version(&self) -> Result<VersionInfo, ErrorKind>;
fn check_version(&self) -> Result<VersionInfo, Error>;
/**
Networked Legacy (non-secure token) version of [Foreign::build_coinbase](struct.Foreign.html#method.build_coinbase).
@ -111,7 +110,7 @@ pub trait ForeignRpc {
```
*/
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, ErrorKind>;
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, Error>;
/**
;Networked version of [Foreign::receive_tx](struct.Foreign.html#method.receive_tx).
@ -190,7 +189,7 @@ pub trait ForeignRpc {
slate: VersionedSlate,
dest_acct_name: Option<String>,
dest: Option<String>,
) -> Result<VersionedSlate, ErrorKind>;
) -> Result<VersionedSlate, Error>;
/**
@ -284,7 +283,7 @@ pub trait ForeignRpc {
# ,false, 5, false, true);
```
*/
fn finalize_tx(&self, slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind>;
fn finalize_tx(&self, slate: VersionedSlate) -> Result<VersionedSlate, Error>;
}
impl<'a, L, C, K> ForeignRpc for Foreign<'a, L, C, K>
@ -293,12 +292,12 @@ where
C: NodeClient + 'a,
K: Keychain + 'a,
{
fn check_version(&self) -> Result<VersionInfo, ErrorKind> {
Foreign::check_version(self).map_err(|e| e.kind())
fn check_version(&self) -> Result<VersionInfo, Error> {
Foreign::check_version(self)
}
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, ErrorKind> {
let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?;
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, Error> {
let cb: CbData = Foreign::build_coinbase(self, block_fees)?;
Ok(VersionedCoinbase::into_version(cb, SlateVersion::V4))
}
@ -307,7 +306,7 @@ where
in_slate: VersionedSlate,
dest_acct_name: Option<String>,
dest: Option<String>,
) -> Result<VersionedSlate, ErrorKind> {
) -> Result<VersionedSlate, Error> {
let version = in_slate.version();
let slate_from = Slate::from(in_slate);
let out_slate = Foreign::receive_tx(
@ -315,16 +314,14 @@ where
&slate_from,
dest_acct_name.as_ref().map(String::as_str),
dest,
)
.map_err(|e| e.kind())?;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
)?;
Ok(VersionedSlate::into_version(out_slate, version)?)
}
fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind> {
fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, Error> {
let version = in_slate.version();
let out_slate =
Foreign::finalize_tx(self, &Slate::from(in_slate), true).map_err(|e| e.kind())?;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
let out_slate = Foreign::finalize_tx(self, &Slate::from(in_slate), true)?;
Ok(VersionedSlate::into_version(out_slate, version)?)
}
}
@ -334,7 +331,7 @@ fn test_check_middleware(
_slate: Option<&Slate>,
) -> Result<(), libwallet::Error> {
// TODO: Implement checks
// return Err(ErrorKind::GenericError("Test Rejection".into()))?
// return Err(Error::GenericError("Test Rejection".into()))?
Ok(())
}

View file

@ -29,7 +29,6 @@ use grin_wallet_util::grin_util as util;
extern crate grin_wallet_impls as impls;
extern crate grin_wallet_libwallet as libwallet;
extern crate failure_derive;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

View file

@ -20,7 +20,7 @@ use crate::core::core::OutputFeatures;
use crate::core::global;
use crate::keychain::{Identifier, Keychain};
use crate::libwallet::{
AcctPathMapping, Amount, BuiltOutput, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
AcctPathMapping, Amount, BuiltOutput, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient,
NodeHeightResult, OutputCommitMapping, PaymentProof, Slate, SlateVersion, Slatepack,
SlatepackAddress, StatusMessage, TxLogEntry, VersionedSlate, ViewWallet, WalletInfo,
WalletLCProvider,
@ -78,7 +78,7 @@ pub trait OwnerRpc {
# , 4, false, false, false, false);
```
*/
fn accounts(&self, token: Token) -> Result<Vec<AcctPathMapping>, ErrorKind>;
fn accounts(&self, token: Token) -> Result<Vec<AcctPathMapping>, Error>;
/**
Networked version of [Owner::create_account_path](struct.Owner.html#method.create_account_path).
@ -111,7 +111,7 @@ pub trait OwnerRpc {
# , 4, false, false, false, false);
```
*/
fn create_account_path(&self, token: Token, label: &String) -> Result<Identifier, ErrorKind>;
fn create_account_path(&self, token: Token, label: &String) -> Result<Identifier, Error>;
/**
Networked version of [Owner::set_active_account](struct.Owner.html#method.set_active_account).
@ -144,7 +144,7 @@ pub trait OwnerRpc {
# , 4, false, false, false, false);
```
*/
fn set_active_account(&self, token: Token, label: &String) -> Result<(), ErrorKind>;
fn set_active_account(&self, token: Token, label: &String) -> Result<(), Error>;
/**
Networked version of [Owner::retrieve_outputs](struct.Owner.html#method.retrieve_outputs).
@ -221,7 +221,7 @@ pub trait OwnerRpc {
include_spent: bool,
refresh_from_node: bool,
tx_id: Option<u32>,
) -> Result<(bool, Vec<OutputCommitMapping>), ErrorKind>;
) -> Result<(bool, Vec<OutputCommitMapping>), Error>;
/**
Networked version of [Owner::retrieve_txs](struct.Owner.html#method.retrieve_txs).
@ -307,7 +307,7 @@ pub trait OwnerRpc {
refresh_from_node: bool,
tx_id: Option<u32>,
tx_slate_id: Option<Uuid>,
) -> Result<(bool, Vec<TxLogEntry>), ErrorKind>;
) -> Result<(bool, Vec<TxLogEntry>), Error>;
/**
Networked version of [Owner::retrieve_summary_info](struct.Owner.html#method.retrieve_summary_info).
@ -358,7 +358,7 @@ pub trait OwnerRpc {
token: Token,
refresh_from_node: bool,
minimum_confirmations: u64,
) -> Result<(bool, WalletInfo), ErrorKind>;
) -> Result<(bool, WalletInfo), Error>;
/**
;Networked version of [Owner::init_send_tx](struct.Owner.html#method.init_send_tx).
@ -417,7 +417,7 @@ pub trait OwnerRpc {
```
*/
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, ErrorKind>;
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, Error>;
/**
;Networked version of [Owner::issue_invoice_tx](struct.Owner.html#method.issue_invoice_tx).
@ -468,7 +468,7 @@ pub trait OwnerRpc {
&self,
token: Token,
args: IssueInvoiceTxArgs,
) -> Result<VersionedSlate, ErrorKind>;
) -> Result<VersionedSlate, Error>;
/**
;Networked version of [Owner::process_invoice_tx](struct.Owner.html#method.process_invoice_tx).
@ -552,7 +552,7 @@ pub trait OwnerRpc {
token: Token,
slate: VersionedSlate,
args: InitTxArgs,
) -> Result<VersionedSlate, ErrorKind>;
) -> Result<VersionedSlate, Error>;
/**
Networked version of [Owner::tx_lock_outputs](struct.Owner.html#method.tx_lock_outputs).
@ -597,7 +597,7 @@ pub trait OwnerRpc {
```
*/
fn tx_lock_outputs(&self, token: Token, slate: VersionedSlate) -> Result<(), ErrorKind>;
fn tx_lock_outputs(&self, token: Token, slate: VersionedSlate) -> Result<(), Error>;
/**
Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx).
@ -683,8 +683,7 @@ pub trait OwnerRpc {
# , 5, true, true, false, false);
```
*/
fn finalize_tx(&self, token: Token, slate: VersionedSlate)
-> Result<VersionedSlate, ErrorKind>;
fn finalize_tx(&self, token: Token, slate: VersionedSlate) -> Result<VersionedSlate, Error>;
/**
Networked version of [Owner::post_tx](struct.Owner.html#method.post_tx).
@ -753,7 +752,7 @@ pub trait OwnerRpc {
```
*/
fn post_tx(&self, token: Token, slate: VersionedSlate, fluff: bool) -> Result<(), ErrorKind>;
fn post_tx(&self, token: Token, slate: VersionedSlate, fluff: bool) -> Result<(), Error>;
/**
Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx).
@ -791,7 +790,7 @@ pub trait OwnerRpc {
token: Token,
tx_id: Option<u32>,
tx_slate_id: Option<Uuid>,
) -> Result<(), ErrorKind>;
) -> Result<(), Error>;
/**
Networked version of [Owner::get_stored_tx](struct.Owner.html#method.get_stored_tx).
@ -840,7 +839,7 @@ pub trait OwnerRpc {
token: Token,
id: Option<u32>,
slate_id: Option<Uuid>,
) -> Result<Option<VersionedSlate>, ErrorKind>;
) -> Result<Option<VersionedSlate>, Error>;
/**
Networked version of [Owner::get_rewind_hash](struct.Owner.html#method.get_rewind_hash).
@ -869,7 +868,7 @@ pub trait OwnerRpc {
# , 0, false, false, false, false);
```
*/
fn get_rewind_hash(&self, token: Token) -> Result<String, ErrorKind>;
fn get_rewind_hash(&self, token: Token) -> Result<String, Error>;
/**
Networked version of [Owner::scan_rewind_hash](struct.Owner.html#method.scan_rewind_hash).
@ -949,7 +948,7 @@ pub trait OwnerRpc {
&self,
rewind_hash: String,
start_height: Option<u64>,
) -> Result<ViewWallet, ErrorKind>;
) -> Result<ViewWallet, Error>;
/**
Networked version of [Owner::scan](struct.Owner.html#method.scan).
@ -987,7 +986,7 @@ pub trait OwnerRpc {
token: Token,
start_height: Option<u64>,
delete_unconfirmed: bool,
) -> Result<(), ErrorKind>;
) -> Result<(), Error>;
/**
Networked version of [Owner::node_height](struct.Owner.html#method.node_height).
@ -1021,7 +1020,7 @@ pub trait OwnerRpc {
# , 5, false, false, false, false);
```
*/
fn node_height(&self, token: Token) -> Result<NodeHeightResult, ErrorKind>;
fn node_height(&self, token: Token) -> Result<NodeHeightResult, Error>;
/**
Initializes the secure JSON-RPC API. This function must be called and a shared key
@ -1075,7 +1074,7 @@ pub trait OwnerRpc {
*/
fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result<ECDHPubkey, ErrorKind>;
fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result<ECDHPubkey, Error>;
/**
Networked version of [Owner::get_top_level_directory](struct.Owner.html#method.get_top_level_directory).
@ -1105,7 +1104,7 @@ pub trait OwnerRpc {
```
*/
fn get_top_level_directory(&self) -> Result<String, ErrorKind>;
fn get_top_level_directory(&self) -> Result<String, Error>;
/**
Networked version of [Owner::set_top_level_directory](struct.Owner.html#method.set_top_level_directory).
@ -1135,7 +1134,7 @@ pub trait OwnerRpc {
```
*/
fn set_top_level_directory(&self, dir: String) -> Result<(), ErrorKind>;
fn set_top_level_directory(&self, dir: String) -> Result<(), Error>;
/**
Networked version of [Owner::create_config](struct.Owner.html#method.create_config).
@ -1205,7 +1204,7 @@ pub trait OwnerRpc {
wallet_config: Option<WalletConfig>,
logging_config: Option<LoggingConfig>,
tor_config: Option<TorConfig>,
) -> Result<(), ErrorKind>;
) -> Result<(), Error>;
/**
Networked version of [Owner::create_wallet](struct.Owner.html#method.create_wallet).
@ -1244,7 +1243,7 @@ pub trait OwnerRpc {
mnemonic: Option<String>,
mnemonic_length: u32,
password: String,
) -> Result<(), ErrorKind>;
) -> Result<(), Error>;
/**
Networked version of [Owner::open_wallet](struct.Owner.html#method.open_wallet).
@ -1275,7 +1274,7 @@ pub trait OwnerRpc {
```
*/
fn open_wallet(&self, name: Option<String>, password: String) -> Result<Token, ErrorKind>;
fn open_wallet(&self, name: Option<String>, password: String) -> Result<Token, Error>;
/**
Networked version of [Owner::close_wallet](struct.Owner.html#method.close_wallet).
@ -1305,7 +1304,7 @@ pub trait OwnerRpc {
```
*/
fn close_wallet(&self, name: Option<String>) -> Result<(), ErrorKind>;
fn close_wallet(&self, name: Option<String>) -> Result<(), Error>;
/**
Networked version of [Owner::get_mnemonic](struct.Owner.html#method.get_mnemonic).
@ -1336,7 +1335,7 @@ pub trait OwnerRpc {
```
*/
fn get_mnemonic(&self, name: Option<String>, password: String) -> Result<String, ErrorKind>;
fn get_mnemonic(&self, name: Option<String>, password: String) -> Result<String, Error>;
/**
Networked version of [Owner::change_password](struct.Owner.html#method.change_password).
@ -1367,12 +1366,7 @@ pub trait OwnerRpc {
# , 0, false, false, false, false);
```
*/
fn change_password(
&self,
name: Option<String>,
old: String,
new: String,
) -> Result<(), ErrorKind>;
fn change_password(&self, name: Option<String>, old: String, new: String) -> Result<(), Error>;
/**
Networked version of [Owner::delete_wallet](struct.Owner.html#method.delete_wallet).
@ -1401,7 +1395,7 @@ pub trait OwnerRpc {
# , 0, false, false, false, false);
```
*/
fn delete_wallet(&self, name: Option<String>) -> Result<(), ErrorKind>;
fn delete_wallet(&self, name: Option<String>) -> Result<(), Error>;
/**
Networked version of [Owner::start_updated](struct.Owner.html#method.start_updater).
@ -1432,7 +1426,7 @@ pub trait OwnerRpc {
```
*/
fn start_updater(&self, token: Token, frequency: u32) -> Result<(), ErrorKind>;
fn start_updater(&self, token: Token, frequency: u32) -> Result<(), Error>;
/**
Networked version of [Owner::stop_updater](struct.Owner.html#method.stop_updater).
@ -1459,7 +1453,7 @@ pub trait OwnerRpc {
# , 0, false, false, false, false);
```
*/
fn stop_updater(&self) -> Result<(), ErrorKind>;
fn stop_updater(&self) -> Result<(), Error>;
/**
Networked version of [Owner::get_updater_messages](struct.Owner.html#method.get_updater_messages).
@ -1489,7 +1483,7 @@ pub trait OwnerRpc {
```
*/
fn get_updater_messages(&self, count: u32) -> Result<Vec<StatusMessage>, ErrorKind>;
fn get_updater_messages(&self, count: u32) -> Result<Vec<StatusMessage>, Error>;
/**
Networked version of [Owner::get_slatepack_address](struct.Owner.html#method.get_slatepack_address).
@ -1524,7 +1518,7 @@ pub trait OwnerRpc {
&self,
token: Token,
derivation_index: u32,
) -> Result<SlatepackAddress, ErrorKind>;
) -> Result<SlatepackAddress, Error>;
/**
Networked version of [Owner::get_slatepack_secret_key](struct.Owner.html#method.get_slatepack_secret_key).
@ -1559,7 +1553,7 @@ pub trait OwnerRpc {
&self,
token: Token,
derivation_index: u32,
) -> Result<Ed25519SecretKey, ErrorKind>;
) -> Result<Ed25519SecretKey, Error>;
/**
Networked version of [Owner::create_slatepack_message](struct.Owner.html#method.create_slatepack_message).
@ -1611,7 +1605,7 @@ pub trait OwnerRpc {
slate: VersionedSlate,
sender_index: Option<u32>,
recipients: Vec<SlatepackAddress>,
) -> Result<String, ErrorKind>;
) -> Result<String, Error>;
/**
Networked version of [Owner::slate_from_slatepack_message](struct.Owner.html#method.slate_from_slatepack_message).
@ -1665,7 +1659,7 @@ pub trait OwnerRpc {
token: Token,
message: String,
secret_indices: Vec<u32>,
) -> Result<VersionedSlate, ErrorKind>;
) -> Result<VersionedSlate, Error>;
/**
Networked version of [Owner::decode_slatepack_message](struct.Owner.html#method.decode_slatepack_message).
@ -1707,7 +1701,7 @@ pub trait OwnerRpc {
token: Token,
message: String,
secret_indices: Vec<u32>,
) -> Result<Slatepack, ErrorKind>;
) -> Result<Slatepack, Error>;
/**
Networked version of [Owner::retrieve_payment_proof](struct.Owner.html#method.retrieve_payment_proof).
@ -1753,7 +1747,7 @@ pub trait OwnerRpc {
refresh_from_node: bool,
tx_id: Option<u32>,
tx_slate_id: Option<Uuid>,
) -> Result<PaymentProof, ErrorKind>;
) -> Result<PaymentProof, Error>;
/**
Networked version of [Owner::verify_payment_proof](struct.Owner.html#method.verify_payment_proof).
@ -1798,7 +1792,7 @@ pub trait OwnerRpc {
&self,
token: Token,
proof: PaymentProof,
) -> Result<(bool, bool), ErrorKind>;
) -> Result<(bool, bool), Error>;
/**
Networked version of [Owner::set_tor_config](struct.Owner.html#method.set_tor_config).
@ -1831,7 +1825,7 @@ pub trait OwnerRpc {
# , 0, false, false, false, false);
```
*/
fn set_tor_config(&self, tor_config: Option<TorConfig>) -> Result<(), ErrorKind>;
fn set_tor_config(&self, tor_config: Option<TorConfig>) -> Result<(), Error>;
/**
Networked version of [Owner::build_output](struct.Owner.html#method.build_output).
@ -1875,7 +1869,7 @@ pub trait OwnerRpc {
token: Token,
features: OutputFeatures,
amount: Amount,
) -> Result<BuiltOutput, ErrorKind>;
) -> Result<BuiltOutput, Error>;
}
impl<L, C, K> OwnerRpc for Owner<L, C, K>
@ -1884,18 +1878,16 @@ where
C: NodeClient + 'static,
K: Keychain + 'static,
{
fn accounts(&self, token: Token) -> Result<Vec<AcctPathMapping>, ErrorKind> {
Owner::accounts(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind())
fn accounts(&self, token: Token) -> Result<Vec<AcctPathMapping>, Error> {
Owner::accounts(self, (&token.keychain_mask).as_ref())
}
fn create_account_path(&self, token: Token, label: &String) -> Result<Identifier, ErrorKind> {
fn create_account_path(&self, token: Token, label: &String) -> Result<Identifier, Error> {
Owner::create_account_path(self, (&token.keychain_mask).as_ref(), label)
.map_err(|e| e.kind())
}
fn set_active_account(&self, token: Token, label: &String) -> Result<(), ErrorKind> {
fn set_active_account(&self, token: Token, label: &String) -> Result<(), Error> {
Owner::set_active_account(self, (&token.keychain_mask).as_ref(), label)
.map_err(|e| e.kind())
}
fn retrieve_outputs(
@ -1904,7 +1896,7 @@ where
include_spent: bool,
refresh_from_node: bool,
tx_id: Option<u32>,
) -> Result<(bool, Vec<OutputCommitMapping>), ErrorKind> {
) -> Result<(bool, Vec<OutputCommitMapping>), Error> {
Owner::retrieve_outputs(
self,
(&token.keychain_mask).as_ref(),
@ -1912,7 +1904,6 @@ where
refresh_from_node,
tx_id,
)
.map_err(|e| e.kind())
}
fn retrieve_txs(
@ -1921,7 +1912,7 @@ where
refresh_from_node: bool,
tx_id: Option<u32>,
tx_slate_id: Option<Uuid>,
) -> Result<(bool, Vec<TxLogEntry>), ErrorKind> {
) -> Result<(bool, Vec<TxLogEntry>), Error> {
Owner::retrieve_txs(
self,
(&token.keychain_mask).as_ref(),
@ -1929,7 +1920,6 @@ where
tx_id,
tx_slate_id,
)
.map_err(|e| e.kind())
}
fn retrieve_summary_info(
@ -1937,32 +1927,29 @@ where
token: Token,
refresh_from_node: bool,
minimum_confirmations: u64,
) -> Result<(bool, WalletInfo), ErrorKind> {
) -> Result<(bool, WalletInfo), Error> {
Owner::retrieve_summary_info(
self,
(&token.keychain_mask).as_ref(),
refresh_from_node,
minimum_confirmations,
)
.map_err(|e| e.kind())
}
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, ErrorKind> {
let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), args)
.map_err(|e| e.kind())?;
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, Error> {
let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), args)?;
let version = SlateVersion::V4;
Ok(VersionedSlate::into_version(slate, version).map_err(|e| e.kind())?)
VersionedSlate::into_version(slate, version)
}
fn issue_invoice_tx(
&self,
token: Token,
args: IssueInvoiceTxArgs,
) -> Result<VersionedSlate, ErrorKind> {
let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), args)
.map_err(|e| e.kind())?;
) -> Result<VersionedSlate, Error> {
let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), args)?;
let version = SlateVersion::V4;
Ok(VersionedSlate::into_version(slate, version).map_err(|e| e.kind())?)
VersionedSlate::into_version(slate, version)
}
fn process_invoice_tx(
@ -1970,40 +1957,33 @@ where
token: Token,
in_slate: VersionedSlate,
args: InitTxArgs,
) -> Result<VersionedSlate, ErrorKind> {
) -> Result<VersionedSlate, Error> {
let out_slate = Owner::process_invoice_tx(
self,
(&token.keychain_mask).as_ref(),
&Slate::from(in_slate),
args,
)
.map_err(|e| e.kind())?;
)?;
let version = SlateVersion::V4;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
VersionedSlate::into_version(out_slate, version)
}
fn finalize_tx(
&self,
token: Token,
in_slate: VersionedSlate,
) -> Result<VersionedSlate, ErrorKind> {
fn finalize_tx(&self, token: Token, in_slate: VersionedSlate) -> Result<VersionedSlate, Error> {
let out_slate = Owner::finalize_tx(
self,
(&token.keychain_mask).as_ref(),
&Slate::from(in_slate),
)
.map_err(|e| e.kind())?;
)?;
let version = SlateVersion::V4;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
VersionedSlate::into_version(out_slate, version)
}
fn tx_lock_outputs(&self, token: Token, in_slate: VersionedSlate) -> Result<(), ErrorKind> {
fn tx_lock_outputs(&self, token: Token, in_slate: VersionedSlate) -> Result<(), Error> {
Owner::tx_lock_outputs(
self,
(&token.keychain_mask).as_ref(),
&Slate::from(in_slate),
)
.map_err(|e| e.kind())
}
fn cancel_tx(
@ -2011,9 +1991,8 @@ where
token: Token,
tx_id: Option<u32>,
tx_slate_id: Option<Uuid>,
) -> Result<(), ErrorKind> {
) -> Result<(), Error> {
Owner::cancel_tx(self, (&token.keychain_mask).as_ref(), tx_id, tx_slate_id)
.map_err(|e| e.kind())
}
fn get_stored_tx(
@ -2021,45 +2000,41 @@ where
token: Token,
id: Option<u32>,
slate_id: Option<Uuid>,
) -> Result<Option<VersionedSlate>, ErrorKind> {
) -> Result<Option<VersionedSlate>, Error> {
let out_slate = Owner::get_stored_tx(
self,
(&token.keychain_mask).as_ref(),
id,
(&slate_id).as_ref(),
)
.map_err(|e| e.kind())?;
)?;
match out_slate {
Some(s) => {
let version = SlateVersion::V4;
Ok(Some(
VersionedSlate::into_version(s, version).map_err(|e| e.kind())?,
))
Ok(Some(VersionedSlate::into_version(s, version)?))
}
None => Ok(None),
}
}
fn post_tx(&self, token: Token, slate: VersionedSlate, fluff: bool) -> Result<(), ErrorKind> {
fn post_tx(&self, token: Token, slate: VersionedSlate, fluff: bool) -> Result<(), Error> {
Owner::post_tx(
self,
(&token.keychain_mask).as_ref(),
&Slate::from(slate),
fluff,
)
.map_err(|e| e.kind())
}
fn get_rewind_hash(&self, token: Token) -> Result<String, ErrorKind> {
Owner::get_rewind_hash(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind())
fn get_rewind_hash(&self, token: Token) -> Result<String, Error> {
Owner::get_rewind_hash(self, (&token.keychain_mask).as_ref())
}
fn scan_rewind_hash(
&self,
rewind_hash: String,
start_height: Option<u64>,
) -> Result<ViewWallet, ErrorKind> {
Owner::scan_rewind_hash(self, rewind_hash, start_height).map_err(|e| e.kind())
) -> Result<ViewWallet, Error> {
Owner::scan_rewind_hash(self, rewind_hash, start_height)
}
fn scan(
@ -2067,21 +2042,20 @@ where
token: Token,
start_height: Option<u64>,
delete_unconfirmed: bool,
) -> Result<(), ErrorKind> {
) -> Result<(), Error> {
Owner::scan(
self,
(&token.keychain_mask).as_ref(),
start_height,
delete_unconfirmed,
)
.map_err(|e| e.kind())
}
fn node_height(&self, token: Token) -> Result<NodeHeightResult, ErrorKind> {
Owner::node_height(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind())
fn node_height(&self, token: Token) -> Result<NodeHeightResult, Error> {
Owner::node_height(self, (&token.keychain_mask).as_ref())
}
fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result<ECDHPubkey, ErrorKind> {
fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result<ECDHPubkey, Error> {
let secp_inst = static_secp_instance();
let secp = secp_inst.lock();
let sec_key = SecretKey::new(&secp, &mut thread_rng());
@ -2089,28 +2063,28 @@ where
let mut shared_pubkey = ecdh_pubkey.ecdh_pubkey;
shared_pubkey
.mul_assign(&secp, &sec_key)
.map_err(ErrorKind::Secp)?;
.map_err(Error::Secp)?;
let x_coord = shared_pubkey.serialize_vec(&secp, true);
let shared_key = SecretKey::from_slice(&secp, &x_coord[1..]).map_err(ErrorKind::Secp)?;
let shared_key = SecretKey::from_slice(&secp, &x_coord[1..]).map_err(Error::Secp)?;
{
let mut s = self.shared_key.lock();
*s = Some(shared_key);
}
let pub_key = PublicKey::from_secret_key(&secp, &sec_key).map_err(ErrorKind::Secp)?;
let pub_key = PublicKey::from_secret_key(&secp, &sec_key).map_err(Error::Secp)?;
Ok(ECDHPubkey {
ecdh_pubkey: pub_key,
})
}
fn get_top_level_directory(&self) -> Result<String, ErrorKind> {
Owner::get_top_level_directory(self).map_err(|e| e.kind())
fn get_top_level_directory(&self) -> Result<String, Error> {
Owner::get_top_level_directory(self)
}
fn set_top_level_directory(&self, dir: String) -> Result<(), ErrorKind> {
Owner::set_top_level_directory(self, &dir).map_err(|e| e.kind())
fn set_top_level_directory(&self, dir: String) -> Result<(), Error> {
Owner::set_top_level_directory(self, &dir)
}
fn create_config(
@ -2119,9 +2093,8 @@ where
wallet_config: Option<WalletConfig>,
logging_config: Option<LoggingConfig>,
tor_config: Option<TorConfig>,
) -> Result<(), ErrorKind> {
) -> Result<(), Error> {
Owner::create_config(self, &chain_type, wallet_config, logging_config, tor_config)
.map_err(|e| e.kind())
}
fn create_wallet(
@ -2130,90 +2103,78 @@ where
mnemonic: Option<String>,
mnemonic_length: u32,
password: String,
) -> Result<(), ErrorKind> {
) -> Result<(), Error> {
let n = name.as_ref().map(|s| s.as_str());
let m = match mnemonic {
Some(s) => Some(ZeroingString::from(s)),
None => None,
};
Owner::create_wallet(self, n, m, mnemonic_length, ZeroingString::from(password))
.map_err(|e| e.kind())
}
fn open_wallet(&self, name: Option<String>, password: String) -> Result<Token, ErrorKind> {
fn open_wallet(&self, name: Option<String>, password: String) -> Result<Token, Error> {
let n = name.as_ref().map(|s| s.as_str());
let sec_key = Owner::open_wallet(self, n, ZeroingString::from(password), true)
.map_err(|e| e.kind())?;
let sec_key = Owner::open_wallet(self, n, ZeroingString::from(password), true)?;
Ok(Token {
keychain_mask: sec_key,
})
}
fn close_wallet(&self, name: Option<String>) -> Result<(), ErrorKind> {
fn close_wallet(&self, name: Option<String>) -> Result<(), Error> {
let n = name.as_ref().map(|s| s.as_str());
Owner::close_wallet(self, n).map_err(|e| e.kind())
Owner::close_wallet(self, n)
}
fn get_mnemonic(&self, name: Option<String>, password: String) -> Result<String, ErrorKind> {
fn get_mnemonic(&self, name: Option<String>, password: String) -> Result<String, Error> {
let n = name.as_ref().map(|s| s.as_str());
let res =
Owner::get_mnemonic(self, n, ZeroingString::from(password)).map_err(|e| e.kind())?;
let res = Owner::get_mnemonic(self, n, ZeroingString::from(password))?;
Ok((&*res).to_string())
}
fn change_password(
&self,
name: Option<String>,
old: String,
new: String,
) -> Result<(), ErrorKind> {
fn change_password(&self, name: Option<String>, old: String, new: String) -> Result<(), Error> {
let n = name.as_ref().map(|s| s.as_str());
Owner::change_password(self, n, ZeroingString::from(old), ZeroingString::from(new))
.map_err(|e| e.kind())
}
fn delete_wallet(&self, name: Option<String>) -> Result<(), ErrorKind> {
fn delete_wallet(&self, name: Option<String>) -> Result<(), Error> {
let n = name.as_ref().map(|s| s.as_str());
Owner::delete_wallet(self, n).map_err(|e| e.kind())
Owner::delete_wallet(self, n)
}
fn start_updater(&self, token: Token, frequency: u32) -> Result<(), ErrorKind> {
fn start_updater(&self, token: Token, frequency: u32) -> Result<(), Error> {
Owner::start_updater(
self,
(&token.keychain_mask).as_ref(),
Duration::from_millis(frequency as u64),
)
.map_err(|e| e.kind())
}
fn stop_updater(&self) -> Result<(), ErrorKind> {
Owner::stop_updater(self).map_err(|e| e.kind())
fn stop_updater(&self) -> Result<(), Error> {
Owner::stop_updater(self)
}
fn get_updater_messages(&self, count: u32) -> Result<Vec<StatusMessage>, ErrorKind> {
Owner::get_updater_messages(self, count as usize).map_err(|e| e.kind())
fn get_updater_messages(&self, count: u32) -> Result<Vec<StatusMessage>, Error> {
Owner::get_updater_messages(self, count as usize)
}
fn get_slatepack_address(
&self,
token: Token,
derivation_index: u32,
) -> Result<SlatepackAddress, ErrorKind> {
) -> Result<SlatepackAddress, Error> {
Owner::get_slatepack_address(self, (&token.keychain_mask).as_ref(), derivation_index)
.map_err(|e| e.kind())
}
fn get_slatepack_secret_key(
&self,
token: Token,
derivation_index: u32,
) -> Result<Ed25519SecretKey, ErrorKind> {
) -> Result<Ed25519SecretKey, Error> {
let key = Owner::get_slatepack_secret_key(
self,
(&token.keychain_mask).as_ref(),
derivation_index,
)
.map_err(|e| e.kind())?;
)?;
Ok(Ed25519SecretKey { key })
}
@ -2223,15 +2184,14 @@ where
slate: VersionedSlate,
sender_index: Option<u32>,
recipients: Vec<SlatepackAddress>,
) -> Result<String, ErrorKind> {
) -> Result<String, Error> {
let res = Owner::create_slatepack_message(
self,
(&token.keychain_mask).as_ref(),
&Slate::from(slate),
sender_index,
recipients,
)
.map_err(|e| e.kind())?;
)?;
Ok(res.trim().into())
}
@ -2240,16 +2200,15 @@ where
token: Token,
message: String,
secret_indices: Vec<u32>,
) -> Result<VersionedSlate, ErrorKind> {
) -> Result<VersionedSlate, Error> {
let slate = Owner::slate_from_slatepack_message(
self,
(&token.keychain_mask).as_ref(),
message,
secret_indices,
)
.map_err(|e| e.kind())?;
)?;
let version = SlateVersion::V4;
Ok(VersionedSlate::into_version(slate, version).map_err(|e| e.kind())?)
VersionedSlate::into_version(slate, version)
}
fn decode_slatepack_message(
@ -2257,14 +2216,13 @@ where
token: Token,
message: String,
secret_indices: Vec<u32>,
) -> Result<Slatepack, ErrorKind> {
) -> Result<Slatepack, Error> {
Owner::decode_slatepack_message(
self,
(&token.keychain_mask).as_ref(),
message,
secret_indices,
)
.map_err(|e| e.kind())
}
fn retrieve_payment_proof(
@ -2273,7 +2231,7 @@ where
refresh_from_node: bool,
tx_id: Option<u32>,
tx_slate_id: Option<Uuid>,
) -> Result<PaymentProof, ErrorKind> {
) -> Result<PaymentProof, Error> {
Owner::retrieve_payment_proof(
self,
(&token.keychain_mask).as_ref(),
@ -2281,19 +2239,17 @@ where
tx_id,
tx_slate_id,
)
.map_err(|e| e.kind())
}
fn verify_payment_proof(
&self,
token: Token,
proof: PaymentProof,
) -> Result<(bool, bool), ErrorKind> {
) -> Result<(bool, bool), Error> {
Owner::verify_payment_proof(self, (&token.keychain_mask).as_ref(), &proof)
.map_err(|e| e.kind())
}
fn set_tor_config(&self, tor_config: Option<TorConfig>) -> Result<(), ErrorKind> {
fn set_tor_config(&self, tor_config: Option<TorConfig>) -> Result<(), Error> {
Owner::set_tor_config(self, tor_config);
Ok(())
}
@ -2303,9 +2259,8 @@ where
token: Token,
features: OutputFeatures,
amount: Amount,
) -> Result<BuiltOutput, ErrorKind> {
) -> Result<BuiltOutput, Error> {
Owner::build_output(self, (&token.keychain_mask).as_ref(), features, amount.0)
.map_err(|e| e.kind())
}
}

View file

@ -13,11 +13,10 @@
use crate::core::libtx::secp_ser;
use crate::libwallet::slate_versions::ser as dalek_ser;
use crate::libwallet::{Error, ErrorKind};
use crate::libwallet::Error;
use crate::util::secp::key::{PublicKey, SecretKey};
use crate::util::{from_hex, ToHex};
use ed25519_dalek::SecretKey as DalekSecretKey;
use failure::ResultExt;
use base64;
use rand::{thread_rng, Rng};
@ -75,9 +74,9 @@ impl EncryptedBody {
/// Encrypts and encodes json as base 64
pub fn from_json(json_in: &Value, enc_key: &SecretKey) -> Result<Self, Error> {
let mut to_encrypt = serde_json::to_string(&json_in)
.context(ErrorKind::APIEncryption(
"EncryptedBody Enc: Unable to encode JSON".to_owned(),
))?
.map_err(|_| {
Error::APIEncryption("EncryptedBody Enc: Unable to encode JSON".to_owned())
})?
.as_bytes()
.to_vec();
@ -92,9 +91,7 @@ impl EncryptedBody {
&mut to_encrypt,
);
if let Err(_) = res {
return Err(
ErrorKind::APIEncryption("EncryptedBody: encryption failed".to_owned()).into(),
);
return Err(Error::APIEncryption("EncryptedBody: encryption failed".to_owned()).into());
}
Ok(EncryptedBody {
@ -105,31 +102,32 @@ impl EncryptedBody {
/// return serialize JSON self
pub fn as_json_value(&self) -> Result<Value, Error> {
let res = serde_json::to_value(self).context(ErrorKind::APIEncryption(
"EncryptedBody: JSON serialization failed".to_owned(),
))?;
let res = serde_json::to_value(self).map_err(|_| {
Error::APIEncryption("EncryptedBody: JSON serialization failed".to_owned())
})?;
Ok(res)
}
/// return serialized JSON self as string
pub fn as_json_str(&self) -> Result<String, Error> {
let res = self.as_json_value()?;
let res = serde_json::to_string(&res).context(ErrorKind::APIEncryption(
"EncryptedBody: JSON String serialization failed".to_owned(),
))?;
let res = serde_json::to_string(&res).map_err(|_| {
Error::APIEncryption("EncryptedBody: JSON String serialization failed".to_owned())
})?;
Ok(res)
}
/// Return original request
pub fn decrypt(&self, dec_key: &SecretKey) -> Result<Value, Error> {
let mut to_decrypt = base64::decode(&self.body_enc).context(ErrorKind::APIEncryption(
"EncryptedBody Dec: Encrypted request contains invalid Base64".to_string(),
))?;
let nonce = from_hex(&self.nonce).map_err(|_| {
ErrorKind::APIEncryption("EncryptedBody Dec: Invalid Nonce".to_string())
let mut to_decrypt = base64::decode(&self.body_enc).map_err(|_| {
Error::APIEncryption(
"EncryptedBody Dec: Encrypted request contains invalid Base64".to_string(),
)
})?;
let nonce = from_hex(&self.nonce)
.map_err(|_| Error::APIEncryption("EncryptedBody Dec: Invalid Nonce".to_string()))?;
if nonce.len() < 12 {
return Err(ErrorKind::APIEncryption(
return Err(Error::APIEncryption(
"EncryptedBody Dec: Invalid Nonce length".to_string(),
)
.into());
@ -142,22 +140,16 @@ impl EncryptedBody {
let res =
opening_key.open_in_place(aead::Nonce::assume_unique_for_key(n), aad, &mut to_decrypt);
if let Err(_) = res {
return Err(
ErrorKind::APIEncryption("EncryptedBody: decryption failed".to_owned()).into(),
);
return Err(Error::APIEncryption("EncryptedBody: decryption failed".to_owned()).into());
}
for _ in 0..aead::AES_256_GCM.tag_len() {
to_decrypt.pop();
}
let decrypted = String::from_utf8(to_decrypt).context(ErrorKind::APIEncryption(
"EncryptedBody Dec: Invalid UTF-8".to_string(),
))?;
Ok(
serde_json::from_str(&decrypted).context(ErrorKind::APIEncryption(
"EncryptedBody Dec: Invalid JSON".to_string(),
))?,
)
let decrypted = String::from_utf8(to_decrypt)
.map_err(|_| Error::APIEncryption("EncryptedBody Dec: Invalid UTF-8".to_string()))?;
Ok(serde_json::from_str(&decrypted)
.map_err(|_| Error::APIEncryption("EncryptedBody Dec: Invalid JSON".to_string()))?)
}
}
@ -187,18 +179,18 @@ impl EncryptedRequest {
/// return serialize JSON self
pub fn as_json_value(&self) -> Result<Value, Error> {
let res = serde_json::to_value(self).context(ErrorKind::APIEncryption(
"EncryptedRequest: JSON serialization failed".to_owned(),
))?;
let res = serde_json::to_value(self).map_err(|_| {
Error::APIEncryption("EncryptedRequest: JSON serialization failed".to_owned())
})?;
Ok(res)
}
/// return serialized JSON self as string
pub fn as_json_str(&self) -> Result<String, Error> {
let res = self.as_json_value()?;
let res = serde_json::to_string(&res).context(ErrorKind::APIEncryption(
"EncryptedRequest: JSON String serialization failed".to_owned(),
))?;
let res = serde_json::to_string(&res).map_err(|_| {
Error::APIEncryption("EncryptedRequest: JSON String serialization failed".to_owned())
})?;
Ok(res)
}
@ -236,18 +228,18 @@ impl EncryptedResponse {
/// return serialize JSON self
pub fn as_json_value(&self) -> Result<Value, Error> {
let res = serde_json::to_value(self).context(ErrorKind::APIEncryption(
"EncryptedResponse: JSON serialization failed".to_owned(),
))?;
let res = serde_json::to_value(self).map_err(|_| {
Error::APIEncryption("EncryptedResponse: JSON serialization failed".to_owned())
})?;
Ok(res)
}
/// return serialized JSON self as string
pub fn as_json_str(&self) -> Result<String, Error> {
let res = self.as_json_value()?;
let res = serde_json::to_string(&res).context(ErrorKind::APIEncryption(
"EncryptedResponse: JSON String serialization failed".to_owned(),
))?;
let res = serde_json::to_string(&res).map_err(|_| {
Error::APIEncryption("EncryptedResponse: JSON String serialization failed".to_owned())
})?;
Ok(res)
}
@ -293,9 +285,9 @@ impl EncryptionErrorResponse {
/// return serialized JSON self
pub fn as_json_value(&self) -> Value {
let res = serde_json::to_value(self).context(ErrorKind::APIEncryption(
"EncryptedResponse: JSON serialization failed".to_owned(),
));
let res = serde_json::to_value(self).map_err(|_| {
Error::APIEncryption("EncryptedResponse: JSON serialization failed".to_owned())
});
match res {
Ok(r) => r,
// proverbial "should never happen"

View file

@ -11,8 +11,6 @@ exclude = ["**/*.grin", "**/*.grin2"]
edition = "2018"
[dependencies]
failure = "0.1"
failure_derive = "0.1"
futures = "0.3"
hyper = "0.13"
rand = "0.7"
@ -29,6 +27,7 @@ url = "2.1"
chrono = { version = "0.4.11", features = ["serde"] }
easy-jsonrpc-mw = "0.5.4"
lazy_static = "1"
thiserror = "1"
qr_code = "1.1.0"
grin_wallet_util = { path = "../util", version = "5.2.0-alpha.1" }

View file

@ -18,7 +18,7 @@ use crate::api::TLSConfig;
use crate::apiwallet::{try_slatepack_sync_workflow, Owner};
use crate::config::{TorConfig, WalletConfig, WALLET_CONFIG_FILE_NAME};
use crate::core::{core, global};
use crate::error::{Error, ErrorKind};
use crate::error::Error;
use crate::impls::PathToSlatepack;
use crate::impls::SlateGetter as _;
use crate::keychain;
@ -184,7 +184,6 @@ where
}
Err(e) => {
error!("View wallet check failed: {}", e);
error!("Backtrace: {}", e.backtrace().unwrap());
Err(e)
}
}
@ -235,7 +234,7 @@ where
let r = t.join();
if let Err(_) = r {
error!("Error starting listener");
return Err(ErrorKind::ListenerError.into());
return Err(Error::ListenerError);
}
}
}
@ -269,7 +268,7 @@ where
test_mode,
);
if let Err(e) = res {
return Err(ErrorKind::LibWallet(e.kind(), e.cause_string()).into());
return Err(Error::LibWallet(e));
}
Ok(())
}
@ -299,7 +298,7 @@ where
});
if let Err(e) = res {
error!("Error listing accounts: {}", e);
return Err(ErrorKind::LibWallet(e.kind(), e.cause_string()).into());
return Err(Error::LibWallet(e));
}
} else {
let label = args.create.unwrap();
@ -312,7 +311,7 @@ where
if let Err(e) = res {
thread::sleep(Duration::from_millis(200));
error!("Error creating account '{}': {}", label, e);
return Err(ErrorKind::LibWallet(e.kind(), e.cause_string()).into());
return Err(Error::LibWallet(e));
}
}
Ok(())
@ -616,7 +615,7 @@ where
}
None => {
let msg = "No slate provided via file or direct input";
return Err(ErrorKind::GenericError(msg.into()).into());
return Err(Error::GenericError(msg.into()).into());
}
}
slate
@ -740,7 +739,7 @@ where
sp
}
None => {
return Err(ErrorKind::ArgumentError("Invalid Slatepack Input".into()).into());
return Err(Error::ArgumentError("Invalid Slatepack Input".into()).into());
}
},
};
@ -1343,7 +1342,6 @@ where
}
Err(e) => {
error!("Wallet check failed: {}", e);
error!("Backtrace: {}", e.backtrace().unwrap());
Err(e)
}
}
@ -1436,7 +1434,7 @@ where
"Unable to open payment proof file at {}: {}",
args.input_file, e
);
return Err(libwallet::ErrorKind::PaymentProofParsing(msg).into());
return Err(libwallet::Error::PaymentProofParsing(msg));
}
};
let mut proof = String::new();
@ -1447,7 +1445,7 @@ where
Err(e) => {
let msg = format!("{}", e);
error!("Unable to parse payment proof file: {}", e);
return Err(libwallet::ErrorKind::PaymentProofParsing(msg).into());
return Err(libwallet::Error::PaymentProofParsing(msg));
}
};
let result = api.verify_payment_proof(m, &proof);

View file

@ -18,12 +18,11 @@ use crate::api::{self, ApiServer, BasicAuthMiddleware, ResponseFuture, Router, T
use crate::config::TorConfig;
use crate::keychain::Keychain;
use crate::libwallet::{
address, Error, ErrorKind, NodeClient, NodeVersionInfo, Slate, SlatepackAddress, WalletInst,
address, Error, NodeClient, NodeVersionInfo, Slate, SlatepackAddress, WalletInst,
WalletLCProvider, GRIN_BLOCK_HEADER_VERSION,
};
use crate::util::secp::key::SecretKey;
use crate::util::{from_hex, static_secp_instance, to_base64, Mutex};
use failure::ResultExt;
use futures::channel::oneshot;
use grin_wallet_api::JsonId;
use grin_wallet_config::types::{TorBridgeConfig, TorProxyConfig};
@ -70,7 +69,7 @@ fn check_middleware(
}
if let Some(s) = slate {
if bhv > 4 && s.version_info.block_header_version < GRIN_BLOCK_HEADER_VERSION {
Err(ErrorKind::Compatibility(
Err(Error::Compatibility(
"Incoming Slate is not compatible with this wallet. \
Please upgrade the node or use a different one."
.into(),
@ -105,9 +104,9 @@ where
let parent_key_id = w_inst.parent_key_id();
let tor_dir = format!("{}/tor/listener", lc.get_top_level_directory()?);
let sec_key = address::address_from_derivation_path(&k, &parent_key_id, 0)
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
let onion_address = OnionV3Address::from_private(&sec_key.0)
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e)))?;
let sp_address = SlatepackAddress::try_from(onion_address.clone())?;
let mut hm_tor_bridge: HashMap<String, String> = HashMap::new();
@ -115,19 +114,19 @@ where
if bridge.bridge_line.is_some() {
tor_timeout = 40;
let bridge_config = tor_bridge::TorBridge::try_from(bridge)
.map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{}", e).into()))?;
hm_tor_bridge = bridge_config
.to_hashmap()
.map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{}", e).into()))?;
}
let mut hm_tor_poxy: HashMap<String, String> = HashMap::new();
if tor_proxy.transport.is_some() || tor_proxy.allowed_port.is_some() {
let proxy_config = tor_proxy::TorProxy::try_from(tor_proxy)
.map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{}", e).into()))?;
hm_tor_poxy = proxy_config
.to_hashmap()
.map_err(|e| ErrorKind::TorConfig(format!("{}", e.kind()).into()))?;
.map_err(|e| Error::TorConfig(format!("{}", e).into()))?;
}
warn!(
@ -141,7 +140,7 @@ where
hm_tor_bridge,
hm_tor_poxy,
)
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorConfig(format!("{:?}", e).into()))?;
// Start TOR process
process
.torrc_path(&format!("{}/torrc", tor_dir))
@ -149,7 +148,7 @@ where
.timeout(tor_timeout)
.completion_percent(100)
.launch()
.map_err(|e| ErrorKind::TorProcess(format!("{:?}", e).into()))?;
.map_err(|e| Error::TorProcess(format!("{:?}", e)))?;
Ok((process, sp_address))
}
@ -173,10 +172,9 @@ where
let wallet = match wallet {
Some(w) => w,
None => {
return Err(ErrorKind::GenericError(format!(
return Err(Error::GenericError(format!(
"Instantiated wallet or Owner API context must be provided"
))
.into())
)))
}
};
f(&mut Owner::new(wallet, None), keychain_mask)?
@ -251,7 +249,7 @@ where
router
.add_route("/v3/owner", Arc::new(api_handler_v3))
.map_err(|_| ErrorKind::GenericError("Router failed to add route".to_string()))?;
.map_err(|_| Error::GenericError("Router failed to add route".to_string()))?;
// If so configured, add the foreign API to the same port
if running_foreign {
@ -260,7 +258,7 @@ where
ForeignAPIHandlerV2::new(wallet, keychain_mask, test_mode, Mutex::new(tor_config));
router
.add_route("/v2/foreign", Arc::new(foreign_api_handler_v2))
.map_err(|_| ErrorKind::GenericError("Router failed to add route".to_string()))?;
.map_err(|_| Error::GenericError("Router failed to add route".to_string()))?;
}
let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) =
@ -271,13 +269,11 @@ where
let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address");
let api_thread = apis
.start(socket_addr, router, tls_config, api_chan)
.context(ErrorKind::GenericError(
"API thread failed to start".to_string(),
))?;
.map_err(|_| Error::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())
.map_err(|e| Error::GenericError(format!("API thread panicked :{:?}", e)))
}
/// Listener version, providing same API but listening for requests on a
@ -336,7 +332,7 @@ where
router
.add_route("/v2/foreign", Arc::new(api_handler_v2))
.map_err(|_| ErrorKind::GenericError("Router failed to add route".to_string()))?;
.map_err(|_| Error::GenericError("Router failed to add route".to_string()))?;
let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) =
Box::leak(Box::new(oneshot::channel::<()>()));
@ -346,9 +342,7 @@ where
let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address");
let api_thread = apis
.start(socket_addr, router, tls_config, api_chan)
.context(ErrorKind::GenericError(
"API thread failed to start".to_string(),
))?;
.map_err(|_| Error::GenericError("API thread failed to start".to_string()))?;
warn!("HTTP Foreign listener started.");
if let Some(a) = address {
@ -361,7 +355,7 @@ where
api_thread
.join()
.map_err(|e| ErrorKind::GenericError(format!("API thread panicked :{:?}", e)).into())
.map_err(|e| Error::GenericError(format!("API thread panicked :{:?}", e)))
}
/// V3 API Handler/Wrapper for owner functions, which include a secure
@ -477,7 +471,7 @@ impl OwnerV3Helpers {
})?;
let id = enc_req.id.clone();
let res = enc_req.decrypt(&shared_key).map_err(|e| {
EncryptionErrorResponse::new(1, -32002, &format!("Decryption error: {}", e.kind()))
EncryptionErrorResponse::new(1, -32002, &format!("Decryption error: {}", e))
.as_json_value()
})?;
Ok((id, res))
@ -492,7 +486,7 @@ impl OwnerV3Helpers {
let share_key_ref = key.lock();
let shared_key = share_key_ref.as_ref().unwrap();
let enc_res = EncryptedResponse::from_json(id, res, &shared_key).map_err(|e| {
EncryptionErrorResponse::new(1, -32003, &format!("EncryptionError: {}", e.kind()))
EncryptionErrorResponse::new(1, -32003, &format!("EncryptionError: {}", e))
.as_json_value()
})?;
let res = enc_res.as_json_value().map_err(|e| {
@ -874,8 +868,8 @@ where
{
let body = body::to_bytes(req.into_body())
.await
.map_err(|_| ErrorKind::GenericError("Failed to read request".to_string()))?;
.map_err(|_| Error::GenericError("Failed to read request".to_string()))?;
serde_json::from_reader(&body[..])
.map_err(|e| ErrorKind::GenericError(format!("Invalid request body: {}", e)).into())
.map_err(|e| Error::GenericError(format!("Invalid request body: {}", e)))
}

View file

@ -19,209 +19,87 @@ use crate::core::libtx;
use crate::impls;
use crate::keychain;
use crate::libwallet;
use failure::{Backtrace, Context, Fail};
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, Eq, PartialEq, Debug, thiserror::Error)]
pub enum Error {
/// LibTX Error
#[fail(display = "LibTx Error")]
LibTX(libtx::ErrorKind),
#[error("LibTx Error")]
LibTX(#[from] libtx::Error),
/// Impls error
#[fail(display = "Impls Error")]
Impls(impls::ErrorKind),
#[error("Impls Error")]
Impls(#[from] impls::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),
/// Transaction Error
#[fail(display = "Transaction error")]
Transaction(transaction::Error),
#[error("Transaction error")]
Transaction(#[from] transaction::Error),
/// Secp Error
#[fail(display = "Secp error")]
#[error("Secp error")]
Secp,
/// Filewallet error
#[fail(display = "Wallet data error: {}", _0)]
#[error("Wallet data error: {0}")]
FileWallet(&'static str),
/// Error when formatting json
#[fail(display = "IO error")]
#[error("IO error")]
IO,
/// Error when formatting json
#[fail(display = "Serde JSON error")]
#[error("Serde JSON error")]
Format,
/// Error when contacting a node through its API
#[fail(display = "Node API error")]
Node(api::ErrorKind),
#[error("Node API error")]
Node(#[from] api::Error),
/// Error originating from hyper.
#[fail(display = "Hyper error")]
#[error("Hyper error")]
Hyper,
/// Error originating from hyper uri parsing.
#[fail(display = "Uri parsing error")]
#[error("Uri parsing error")]
Uri,
/// Attempt to use duplicate transaction id in separate transactions
#[fail(display = "Duplicate transaction ID error")]
#[error("Duplicate transaction ID error")]
DuplicateTransactionId,
/// 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,
/// 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),
/// Other
#[fail(display = "Listener Startup Error")]
#[error("Listener Startup Error")]
ListenerError,
/// 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) => {
if r == "1" {
true
} else {
false
}
}
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.clone();
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<api::Error> for Error {
fn from(error: api::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Node(error.kind().clone())),
}
}
}
impl From<keychain::Error> for Error {
fn from(error: keychain::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Keychain(error)),
}
}
}
impl From<transaction::Error> for Error {
fn from(error: transaction::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Transaction(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<impls::Error> for Error {
fn from(error: impls::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Impls(error.kind())),
}
}
}

View file

@ -21,7 +21,6 @@ extern crate prettytable;
extern crate log;
#[macro_use]
extern crate lazy_static;
use failure;
use grin_wallet_api as apiwallet;
use grin_wallet_config as config;
use grin_wallet_impls as impls;
@ -36,4 +35,4 @@ pub mod controller;
pub mod display;
mod error;
pub use crate::error::{Error, ErrorKind};
pub use crate::error::Error;

View file

@ -270,7 +270,7 @@ fn accounts() {
let test_dir = "test_output/accounts";
setup(test_dir);
if let Err(e) = accounts_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -165,7 +165,7 @@ fn build_chain_to_height() {
clean_output_dir(test_dir);
setup(test_dir);
if let Err(e) = build_chain(test_dir, 2048) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
// don't clean to get the result for testing
}

View file

@ -95,7 +95,7 @@ fn build_output() {
let test_dir = "test_output/build_output";
setup(test_dir);
if let Err(e) = build_output_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -852,7 +852,7 @@ fn scan() {
let test_dir = "test_output/scan";
setup(test_dir);
if let Err(e) = scan_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -862,7 +862,7 @@ fn two_wallets_one_seed() {
let test_dir = "test_output/two_wallets_one_seed";
setup(test_dir);
if let Err(e) = two_wallets_one_seed_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -872,7 +872,7 @@ fn output_scanning() {
let test_dir = "test_output/output_scanning";
setup(test_dir);
if let Err(e) = output_scanning_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -304,7 +304,7 @@ fn wallet_file_exchange_json() {
setup(test_dir);
// Json output
if let Err(e) = file_exchange_test_impl(test_dir, false) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -314,7 +314,7 @@ fn wallet_file_exchange_bin() {
let test_dir = "test_output/file_exchange_bin";
setup(test_dir);
if let Err(e) = file_exchange_test_impl(test_dir, true) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -152,7 +152,7 @@ fn late_lock() {
let test_dir = "test_output/late_lock";
setup(test_dir);
if let Err(e) = late_lock_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -206,7 +206,7 @@ fn no_change() {
let test_dir = "test_output/no_change";
setup(test_dir);
if let Err(e) = no_change_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -166,7 +166,7 @@ fn payment_proofs() {
let test_dir = "test_output/payment_proofs";
setup(test_dir);
if let Err(e) = payment_proofs_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -262,7 +262,7 @@ fn wallet_file_repost() {
let test_dir = "test_output/file_repost";
setup(test_dir);
if let Err(e) = file_repost_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -363,7 +363,7 @@ fn tx_revert_reconfirm() {
let test_dir = "test_output/revert_tx";
setup(test_dir);
if let Err(e) = revert_reconfirm_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -373,7 +373,7 @@ fn tx_revert_cancel() {
let test_dir = "test_output/revert_tx_cancel";
setup(test_dir);
if let Err(e) = revert_cancel_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -142,7 +142,7 @@ fn wallet_self_send() {
let test_dir = "test_output/self_send";
setup(test_dir);
if let Err(e) = self_send_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -515,7 +515,7 @@ fn slatepack_exchange_json() {
setup(test_dir);
// Json output
if let Err(e) = slatepack_exchange_test_impl(test_dir, false, false, false) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -526,7 +526,7 @@ fn slatepack_exchange_bin() {
setup(test_dir);
// Bin output
if let Err(e) = slatepack_exchange_test_impl(test_dir, true, false, false) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -537,7 +537,7 @@ fn slatepack_exchange_armored() {
setup(test_dir);
// Bin output
if let Err(e) = slatepack_exchange_test_impl(test_dir, true, true, true) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -548,7 +548,7 @@ fn slatepack_exchange_json_enc() {
setup(test_dir);
// Json output
if let Err(e) = slatepack_exchange_test_impl(test_dir, false, false, true) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -559,7 +559,7 @@ fn slatepack_exchange_bin_enc() {
setup(test_dir);
// Bin output
if let Err(e) = slatepack_exchange_test_impl(test_dir, true, false, true) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -570,7 +570,7 @@ fn slatepack_exchange_armored_enc() {
setup(test_dir);
// Bin output
if let Err(e) = slatepack_exchange_test_impl(test_dir, true, true, true) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -581,7 +581,7 @@ fn slatepack_api() {
setup(test_dir);
// Json output
if let Err(e) = slatepack_api_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -585,7 +585,7 @@ fn db_wallet_basic_transaction_api() {
let test_dir = "test_output/basic_transaction_api";
setup(test_dir);
if let Err(e) = basic_transaction_api(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}
@ -595,7 +595,7 @@ fn db_wallet_tx_rollback() {
let test_dir = "test_output/tx_rollback";
setup(test_dir);
if let Err(e) = tx_rollback(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -179,7 +179,7 @@ fn ttl_cutoff() {
let test_dir = "test_output/ttl_cutoff";
setup(test_dir);
if let Err(e) = ttl_cutoff_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

View file

@ -117,7 +117,7 @@ fn updater_thread() {
let test_dir = "test_output/updater_thread";
setup(test_dir);
if let Err(e) = updater_thread_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
clean_output_dir(test_dir);
}

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"

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))
}
}

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)
}
}

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(),
)?;
}

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))
}
}

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)
}

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};

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))
}
}

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;

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()),
}

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();

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((

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();

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))
}
}
}

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())
}
}
}

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 {

View file

@ -12,8 +12,6 @@ edition = "2018"
[dependencies]
blake2-rfc = "0.2"
failure = "0.1"
failure_derive = "0.1"
rand = "0.6"
serde = "1"
serde_derive = "1"
@ -24,6 +22,7 @@ chrono = { version = "0.4.11", features = ["serde"] }
lazy_static = "1"
strum = "0.18"
strum_macros = "0.18"
thiserror = "1"
ed25519-dalek = "1.0.0-pre.4"
x25519-dalek = "0.6"
base64 = "0.9"

View file

@ -23,8 +23,8 @@ use crate::grin_util::secp::key::SecretKey;
use crate::internal::{selection, tx, updater};
use crate::slate_versions::SlateVersion;
use crate::{
address, BlockFees, CbData, Error, ErrorKind, NodeClient, Slate, SlateState, TxLogEntryType,
VersionInfo, WalletBackend,
address, BlockFees, CbData, Error, NodeClient, Slate, SlateState, TxLogEntryType, VersionInfo,
WalletBackend,
};
const FOREIGN_API_VERSION: u16 = 2;
@ -87,7 +87,7 @@ where
)?;
for t in &tx {
if t.tx_type == TxLogEntryType::TxReceived {
return Err(ErrorKind::TransactionAlreadyReceived(ret_slate.id.to_string()).into());
return Err(Error::TransactionAlreadyReceived(ret_slate.id.to_string()));
}
}

View file

@ -30,12 +30,12 @@ use crate::grin_keychain::{BlindingFactor, Identifier, Keychain, SwitchCommitmen
use crate::internal::{keys, scan, selection, tx, updater};
use crate::slate::{PaymentInfo, Slate, SlateState};
use crate::types::{AcctPathMapping, NodeClient, TxLogEntry, WalletBackend, WalletInfo};
use crate::Error;
use crate::{
address, wallet_lock, BuiltOutput, InitTxArgs, IssueInvoiceTxArgs, NodeHeightResult,
OutputCommitMapping, PaymentProof, ScannedBlockInfo, Slatepack, SlatepackAddress, Slatepacker,
SlatepackerArgs, TxLogEntryType, ViewWallet, WalletInitStatus, WalletInst, WalletLCProvider,
};
use crate::{Error, ErrorKind};
use ed25519_dalek::PublicKey as DalekPublicKey;
use ed25519_dalek::SecretKey as DalekSecretKey;
use ed25519_dalek::Verifier;
@ -211,9 +211,9 @@ where
};
return packer.get_slate(&slatepack);
}
return Err(ErrorKind::SlatepackDecryption(
return Err(Error::SlatepackDecryption(
"Could not decrypt slatepack with any provided index on the address derivation path"
.into(),
.to_owned(),
)
.into());
}
@ -382,10 +382,9 @@ where
K: Keychain + 'a,
{
if tx_id.is_none() && tx_slate_id.is_none() {
return Err(ErrorKind::PaymentProofRetrieval(
"Transaction ID or Slate UUID must be specified".into(),
)
.into());
return Err(Error::PaymentProofRetrieval(
"Transaction ID or Slate UUID must be specified".to_owned(),
));
}
if refresh_from_node {
update_wallet_state(
@ -406,17 +405,18 @@ where
tx_slate_id,
)?;
if txs.1.len() != 1 {
return Err(ErrorKind::PaymentProofRetrieval("Transaction doesn't exist".into()).into());
return Err(Error::PaymentProofRetrieval(
"Transaction doesn't exist".to_owned(),
));
}
// Pull out all needed fields, returning an error if they're not present
let tx = txs.1[0].clone();
let proof = match tx.payment_proof {
Some(p) => p,
None => {
return Err(ErrorKind::PaymentProofRetrieval(
"Transaction does not contain a payment proof".into(),
)
.into());
return Err(Error::PaymentProofRetrieval(
"Transaction does not contain a payment proof".to_owned(),
));
}
};
let amount = if tx.amount_credited >= tx.amount_debited {
@ -431,28 +431,25 @@ where
let excess = match tx.kernel_excess {
Some(e) => e,
None => {
return Err(ErrorKind::PaymentProofRetrieval(
"Transaction does not contain kernel excess".into(),
)
.into());
return Err(Error::PaymentProofRetrieval(
"Transaction does not contain kernel excess".to_owned(),
));
}
};
let r_sig = match proof.receiver_signature {
Some(e) => e,
None => {
return Err(ErrorKind::PaymentProofRetrieval(
"Proof does not contain receiver signature ".into(),
)
.into());
return Err(Error::PaymentProofRetrieval(
"Proof does not contain receiver signature ".to_owned(),
));
}
};
let s_sig = match proof.sender_signature {
Some(e) => e,
None => {
return Err(ErrorKind::PaymentProofRetrieval(
"Proof does not contain sender signature ".into(),
)
.into());
return Err(Error::PaymentProofRetrieval(
"Proof does not contain sender signature ".to_owned(),
));
}
};
Ok(PaymentProof {
@ -669,7 +666,7 @@ where
)?;
for t in &tx {
if t.tx_type == TxLogEntryType::TxSent {
return Err(ErrorKind::TransactionAlreadyReceived(ret_slate.id.to_string()).into());
return Err(Error::TransactionAlreadyReceived(ret_slate.id.to_string()));
}
}
@ -882,10 +879,9 @@ where
status_send_channel,
false,
)? {
return Err(ErrorKind::TransactionCancellationError(
return Err(Error::TransactionCancellationError(
"Can't contact running Grin node. Not Cancelling.",
)
.into());
));
}
wallet_lock!(wallet_inst, w);
let parent_key_id = w.parent_key_id();
@ -919,10 +915,9 @@ where
let id = match uuid {
Some(u) => u,
None => {
return Err(ErrorKind::StoredTx(
return Err(Error::StoredTx(
"Both the provided Transaction Id and Slate UUID are invalid.".to_owned(),
)
.into());
));
}
};
let tx_res = w.get_stored_tx(&format!("{}", id))?;
@ -977,7 +972,7 @@ where
let rewind_hash = rewind_hash.to_lowercase();
if !(is_hex && rewind_hash.len() == 64) {
let msg = format!("Invalid Rewind Hash");
return Err(ErrorKind::RewindHash(msg).into());
return Err(Error::RewindHash(msg));
}
let tip = {
@ -1227,7 +1222,7 @@ where
let last_confirmed_height = w.last_confirmed_height()?;
if slate.ttl_cutoff_height != 0 {
if last_confirmed_height >= slate.ttl_cutoff_height {
return Err(ErrorKind::TransactionExpired.into());
return Err(Error::TransactionExpired);
}
}
Ok(())
@ -1260,18 +1255,16 @@ where
// Check kernel exists
match client.get_kernel(&proof.excess, None, None) {
Err(e) => {
return Err(ErrorKind::PaymentProof(format!(
return Err(Error::PaymentProof(format!(
"Error retrieving kernel from chain: {}",
e
))
.into());
)));
}
Ok(None) => {
return Err(ErrorKind::PaymentProof(format!(
return Err(Error::PaymentProof(format!(
"Transaction kernel with excess {:?} not found on chain",
proof.excess
))
.into());
)));
}
Ok(Some(_)) => {}
};
@ -1279,12 +1272,14 @@ where
// Check Sigs
let recipient_pubkey = proof.recipient_address.pub_key;
if recipient_pubkey.verify(&msg, &proof.recipient_sig).is_err() {
return Err(ErrorKind::PaymentProof("Invalid recipient signature".to_owned()).into());
return Err(Error::PaymentProof(
"Invalid recipient signature".to_owned(),
));
};
let sender_pubkey = proof.sender_address.pub_key;
if sender_pubkey.verify(&msg, &proof.sender_sig).is_err() {
return Err(ErrorKind::PaymentProof("Invalid sender signature".to_owned()).into());
return Err(Error::PaymentProof("Invalid sender signature".to_owned()));
};
// for now, simple test as to whether one of the addresses belongs to this wallet
@ -1292,7 +1287,7 @@ where
let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) {
Ok(k) => k,
Err(e) => {
return Err(ErrorKind::ED25519Key(format!("{}", e)).into());
return Err(Error::ED25519Key(format!("{}", e)));
}
};
let my_address_pubkey: DalekPublicKey = (&d_skey).into();
@ -1319,7 +1314,7 @@ where
match updater::refresh_outputs(&mut **w, keychain_mask, &parent_key_id, update_all) {
Ok(_) => Ok(true),
Err(e) => {
if let ErrorKind::InvalidKeychainMask = e.kind() {
if let Error::InvalidKeychainMask = e {
return Err(e);
}
Ok(false)

View file

@ -17,28 +17,14 @@
use crate::grin_core::core::{committed, transaction};
use crate::grin_core::libtx;
use crate::grin_keychain;
use crate::grin_store;
use crate::grin_util::secp;
use crate::util;
use failure::{Backtrace, Context, Fail};
use std::env;
use std::fmt::{self, Display};
use std::io;
/// Error definition
#[derive(Debug, Fail)]
pub struct Error {
inner: Context<ErrorKind>,
}
use crate::util::{self, grin_store};
/// Wallet errors, mostly wrappers around underlying crypto or I/O errors.
#[derive(Clone, Eq, PartialEq, Debug, Fail, Serialize, Deserialize)]
pub enum ErrorKind {
#[derive(Clone, Eq, PartialEq, Debug, thiserror::Error, Serialize, Deserialize)]
pub enum Error {
/// Not enough funds
#[fail(
display = "Not enough funds. Required: {}, Available: {}",
needed_disp, available_disp
)]
#[error("Not enough funds. Required: {needed_disp:?}, Available: {available_disp:?}")]
NotEnoughFunds {
/// available funds
available: u64,
@ -51,426 +37,306 @@ pub enum ErrorKind {
},
/// Fee error
#[fail(display = "Fee Error: {}", _0)]
#[error("Fee Error: {0}")]
Fee(String),
/// LibTX Error
#[fail(display = "LibTx Error")]
LibTX(libtx::ErrorKind),
#[error("LibTx Error")]
LibTX(#[from] libtx::Error),
/// Keychain error
#[fail(display = "Keychain error")]
Keychain(grin_keychain::Error),
#[error("Keychain error")]
Keychain(#[from] grin_keychain::Error),
/// Transaction Error
#[fail(display = "Transaction error")]
Transaction(transaction::Error),
#[error("Transaction error")]
Transaction(#[from] transaction::Error),
/// API Error
#[fail(display = "Client Callback Error: {}", _0)]
#[error("Client Callback Error: {0}")]
ClientCallback(String),
/// Secp Error
#[fail(display = "Secp error")]
Secp(secp::Error),
/// Error from underlying secp lib
#[error("Secp Lib Error")]
Secp(#[from] secp::Error),
/// Onion V3 Address Error
#[fail(display = "Onion V3 Address Error")]
OnionV3Address(util::OnionV3AddressError),
#[error("Onion V3 Address Error: {0}")]
OnionV3Address(#[from] util::OnionV3AddressError),
/// Callback implementation error conversion
#[fail(display = "Trait Implementation error")]
#[error("Trait Implementation error")]
CallbackImpl(&'static str),
/// Wallet backend error
#[fail(display = "Wallet store error: {}", _0)]
#[error("Wallet store error: {0}")]
Backend(String),
/// Callback implementation error conversion
#[fail(display = "Restore Error")]
#[error("Restore Error")]
Restore,
/// An error in the format of the JSON structures exchanged by the wallet
#[fail(display = "JSON format error: {}", _0)]
#[error("JSON format error: {0}")]
Format(String),
/// Other serialization errors
#[fail(display = "Ser/Deserialization error")]
#[error("Ser/Deserialization error")]
Deser(crate::grin_core::ser::Error),
/// IO Error
#[fail(display = "I/O error")]
IO,
#[error("I/O error {0}")]
IO(String),
/// Error when contacting a node through its API
#[fail(display = "Node API error")]
#[error("Node API error")]
Node,
/// Error contacting wallet API
#[fail(display = "Wallet Communication Error: {}", _0)]
#[error("Wallet Communication Error: {0}")]
WalletComms(String),
/// Error originating from hyper.
#[fail(display = "Hyper error")]
#[error("Hyper error")]
Hyper,
/// Error originating from hyper uri parsing.
#[fail(display = "Uri parsing error")]
#[error("Uri parsing error")]
Uri,
/// Signature error
#[fail(display = "Signature error: {}", _0)]
#[error("Signature error: {0}")]
Signature(String),
/// OwnerAPIEncryption
#[fail(display = "{}", _0)]
#[error("{}", _0)]
APIEncryption(String),
/// Attempt to use duplicate transaction id in separate transactions
#[fail(display = "Duplicate transaction ID error")]
#[error("Duplicate transaction ID error")]
DuplicateTransactionId,
/// Wallet seed already exists
#[fail(display = "Wallet seed exists error: {}", _0)]
#[error("Wallet seed exists error: {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 seed decryption error")]
#[error("Wallet seed decryption error")]
WalletSeedDecryption,
/// Transaction doesn't exist
#[fail(display = "Transaction {} doesn't exist", _0)]
#[error("Transaction {0} doesn't exist")]
TransactionDoesntExist(String),
/// Transaction already rolled back
#[fail(display = "Transaction {} cannot be cancelled", _0)]
#[error("Transaction {0} cannot be cancelled")]
TransactionNotCancellable(String),
/// Cancellation error
#[fail(display = "Cancellation Error: {}", _0)]
#[error("Cancellation Error: {0}")]
TransactionCancellationError(&'static str),
/// Cancellation error
#[fail(display = "Tx dump Error: {}", _0)]
#[error("Tx dump Error: {0}")]
TransactionDumpError(&'static str),
/// Attempt to repost a transaction that's already confirmed
#[fail(display = "Transaction already confirmed error")]
#[error("Transaction already confirmed error")]
TransactionAlreadyConfirmed,
/// Transaction has already been received
#[fail(display = "Transaction {} has already been received", _0)]
#[error("Transaction {0} has already been received")]
TransactionAlreadyReceived(String),
/// Attempt to repost a transaction that's not completed and stored
#[fail(display = "Transaction building not completed: {}", _0)]
#[error("Transaction building not completed: {0}")]
TransactionBuildingNotCompleted(u32),
/// Invalid BIP-32 Depth
#[fail(display = "Invalid BIP32 Depth (must be 1 or greater)")]
#[error("Invalid BIP32 Depth (must be 1 or greater)")]
InvalidBIP32Depth,
/// Attempt to add an account that exists
#[fail(display = "Account Label '{}' already exists", _0)]
#[error("Account Label '{0}' already exists")]
AccountLabelAlreadyExists(String),
/// Reference unknown account label
#[fail(display = "Unknown Account Label '{}'", _0)]
#[error("Unknown Account Label '{0}'")]
UnknownAccountLabel(String),
/// Error from summing commitments via committed trait.
#[fail(display = "Committed Error")]
#[error("Committed Error")]
Committed(committed::Error),
/// Error from summing commitments
#[fail(display = "Committed Error: {}", _0)]
#[error("Committed Error: {0}")]
Commit(String),
/// Can't parse slate version
#[fail(display = "Can't parse slate version")]
#[error("Can't parse slate version")]
SlateVersionParse,
/// Can't serialize slate
#[fail(display = "Can't Serialize slate")]
#[error("Can't Serialize slate")]
SlateSer,
/// Can't deserialize slate
#[fail(display = "Can't Deserialize slate")]
#[error("Can't Deserialize slate")]
SlateDeser,
/// Can't serialize slate pack
#[fail(display = "Can't Serialize slatepack")]
#[error("Can't Serialize slatepack")]
SlatepackSer,
/// Can't deserialize slate
#[fail(display = "Can't Deserialize slatepack: {}", _0)]
#[error("Can't Deserialize slatepack: {0}")]
SlatepackDeser(String),
/// Unknown slate version
#[fail(display = "Unknown Slate Version: {}", _0)]
#[error("Unknown Slate Version: {0}")]
SlateVersion(u16),
/// Attempt to use slate transaction data that doesn't exists
#[fail(display = "Slate transaction required in this context")]
#[error("Slate transaction required in this context")]
SlateTransactionRequired,
/// Attempt to downgrade slate that can't be downgraded
#[fail(display = "Can't downgrade slate: {}", _0)]
#[error("Can't downgrade slate: {0}")]
SlateInvalidDowngrade(String),
/// Compatibility error between incoming slate versions and what's expected
#[fail(display = "Compatibility Error: {}", _0)]
#[error("Compatibility Error: {0}")]
Compatibility(String),
/// Keychain doesn't exist (wallet not openend)
#[fail(display = "Keychain doesn't exist (has wallet been opened?)")]
#[error("Keychain doesn't exist (has wallet been opened?)")]
KeychainDoesntExist,
/// Lifecycle Error
#[fail(display = "Lifecycle Error: {}", _0)]
#[error("Lifecycle Error: {0}")]
Lifecycle(String),
/// Invalid Keychain Mask Error
#[fail(display = "Supplied Keychain Mask Token is incorrect")]
#[error("Supplied Keychain Mask Token is incorrect")]
InvalidKeychainMask,
/// Tor Process error
#[fail(display = "Tor Process Error: {}", _0)]
#[error("Tor Process Error: {0}")]
TorProcess(String),
/// Tor Configuration Error
#[fail(display = "Tor Config Error: {}", _0)]
#[error("Tor Config Error: {0}")]
TorConfig(String),
/// Generating ED25519 Public Key
#[fail(display = "Error generating ed25519 secret key: {}", _0)]
#[error("Error generating ed25519 secret key: {0}")]
ED25519Key(String),
/// Generating Payment Proof
#[fail(display = "Payment Proof generation error: {}", _0)]
#[error("Payment Proof generation error: {0}")]
PaymentProof(String),
/// Retrieving Payment Proof
#[fail(display = "Payment Proof retrieval error: {}", _0)]
#[error("Payment Proof retrieval error: {0}")]
PaymentProofRetrieval(String),
/// Retrieving Payment Proof
#[fail(display = "Payment Proof parsing error: {}", _0)]
#[error("Payment Proof parsing error: {0}")]
PaymentProofParsing(String),
/// Decoding OnionV3 addresses to payment proof addresses
#[fail(display = "Proof Address decoding: {}", _0)]
#[error("Proof Address decoding: {0}")]
AddressDecoding(String),
/// Transaction has expired it's TTL
#[fail(display = "Transaction Expired")]
#[error("Transaction Expired")]
TransactionExpired,
/// Kernel features args don't exist
#[fail(display = "Kernel Features Arg {} missing", _0)]
#[error("Kernel Features Arg {0} missing")]
KernelFeaturesMissing(String),
/// Unknown Kernel Feature
#[fail(display = "Unknown Kernel Feature: {}", _0)]
#[error("Unknown Kernel Feature: {0}")]
UnknownKernelFeatures(u8),
/// Invalid Kernel Feature
#[fail(display = "Invalid Kernel Feature: {}", _0)]
#[error("Invalid Kernel Feature: {0}")]
InvalidKernelFeatures(u8),
/// Invalid Slatepack Data
#[fail(display = "Invalid Slatepack Data: {}", _0)]
#[error("Invalid Slatepack Data: {0}")]
InvalidSlatepackData(String),
/// Slatepack Encryption
#[fail(display = "Couldn't encrypt Slatepack: {}", _0)]
#[error("Couldn't encrypt Slatepack: {0}")]
SlatepackEncryption(String),
/// Slatepack Decryption
#[fail(display = "Couldn't decrypt Slatepack: {}", _0)]
#[error("Couldn't decrypt Slatepack: {0}")]
SlatepackDecryption(String),
/// age error
#[fail(display = "Age error: {}", _0)]
#[error("Age error: {0}")]
Age(String),
/// Rewind Hash parsing error
#[fail(display = "Rewind Hash error: {}", _0)]
#[error("Rewind Hash error: {0}")]
RewindHash(String),
/// Nonce creation error
#[fail(display = "Nonce error: {}", _0)]
#[error("Nonce error: {0}")]
Nonce(String),
/// Slatepack address parsing error
#[fail(display = "SlatepackAddress error: {}", _0)]
#[error("SlatepackAddress error: {0}")]
SlatepackAddress(String),
/// Retrieving Stored Tx
#[fail(display = "Stored Tx error: {}", _0)]
#[error("Stored Tx error: {0}")]
StoredTx(String),
/// Other
#[fail(display = "Generic error: {}", _0)]
#[error("Generic error: {0}")]
GenericError(String),
}
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!("\n Backtrace: {}", 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 string
pub fn cause_string(&self) -> String {
match self.cause() {
Some(k) => format!("{}", k),
None => "Unknown".to_string(),
}
}
/// 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<io::Error> for Error {
fn from(_error: io::Error) -> Error {
Error {
inner: Context::new(ErrorKind::IO),
}
}
}
impl From<grin_keychain::Error> for Error {
fn from(error: grin_keychain::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Keychain(error)),
}
}
}
impl From<libtx::Error> for Error {
fn from(error: crate::grin_core::libtx::Error) -> Error {
Error {
inner: Context::new(ErrorKind::LibTX(error.kind())),
}
}
}
impl From<transaction::Error> for Error {
fn from(error: transaction::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Transaction(error)),
}
}
}
impl From<crate::grin_core::ser::Error> for Error {
fn from(error: crate::grin_core::ser::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Deser(error)),
}
}
}
impl From<secp::Error> for Error {
fn from(error: secp::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Secp(error)),
}
}
}
impl From<committed::Error> for Error {
fn from(error: committed::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Committed(error)),
}
}
}
impl From<grin_store::Error> for Error {
fn from(error: grin_store::Error) -> Error {
Error::from(ErrorKind::Backend(format!("{}", error)))
}
}
impl From<util::OnionV3AddressError> for Error {
fn from(error: util::OnionV3AddressError) -> Error {
Error::from(ErrorKind::OnionV3Address(error))
Error::Backend(format!("{}", error))
}
}
impl From<age::EncryptError> for Error {
fn from(error: age::EncryptError) -> Error {
Error {
inner: Context::new(ErrorKind::Age(format!("{}", error))),
}
Error::Age(format!("{}", error))
}
}
impl From<age::DecryptError> for Error {
fn from(error: age::DecryptError) -> Error {
Error {
inner: Context::new(ErrorKind::Age(format!("{}", error))),
}
Error::Age(format!("{}", error))
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Error {
Error::IO(e.to_string())
}
}
impl From<&str> for Error {
fn from(error: &str) -> Error {
Error {
inner: Context::new(ErrorKind::Age(format!("Bech32 Key Encoding - {}", error))),
}
Error::Age(format!("Bech32 Key Encoding - {}", error))
}
}
impl From<bech32::Error> for Error {
fn from(error: bech32::Error) -> Error {
Error {
inner: Context::new(ErrorKind::SlatepackAddress(format!("{}", error))),
}
Error::SlatepackAddress(format!("{}", error))
}
}

View file

@ -13,7 +13,7 @@
// limitations under the License.
//! Wallet key management functions
use crate::error::{Error, ErrorKind};
use crate::error::Error;
use crate::grin_keychain::{ChildNumber, ExtKeychain, Identifier, Keychain};
use crate::grin_util::secp::key::SecretKey;
use crate::types::{AcctPathMapping, NodeClient, WalletBackend};
@ -72,7 +72,7 @@ where
{
let label = label.to_owned();
if wallet.acct_path_iter().any(|l| l.label == label) {
return Err(ErrorKind::AccountLabelAlreadyExists(label).into());
return Err(Error::AccountLabelAlreadyExists(label));
}
// We're always using paths at m/k/0 for parent keys for output derivations

View file

@ -25,7 +25,7 @@ use crate::grin_util::secp::{ContextFlag, Secp256k1};
use crate::grin_util::Mutex;
use crate::grin_util::{from_hex, ToHex};
use crate::internal::{keys, updater};
use crate::{types::*, ErrorKind};
use crate::types::*;
use crate::{wallet_lock, Error, OutputCommitMapping};
use blake2_rfc::blake2b::blake2b;
use std::cmp;
@ -187,12 +187,11 @@ where
// Scanning outputs
for output in outputs.iter() {
let (commit, proof, is_coinbase, height, mmr_index) = output;
let rewind_hash = from_hex(vw.rewind_hash.as_str()).map_err(|e| {
ErrorKind::RewindHash(format!("Unable to decode rewind hash: {}", e))
})?;
let rewind_hash = from_hex(vw.rewind_hash.as_str())
.map_err(|e| Error::RewindHash(format!("Unable to decode rewind hash: {}", e)))?;
let rewind_nonce = blake2b(32, &commit.0, &rewind_hash);
let nonce = SecretKey::from_slice(&secp, rewind_nonce.as_bytes())
.map_err(|e| ErrorKind::Nonce(format!("Unable to create nonce: {}", e)))?;
.map_err(|e| Error::Nonce(format!("Unable to create nonce: {}", e)))?;
let info = secp.rewind_bullet_proof(*commit, nonce.clone(), None, *proof);
if info.is_err() {

View file

@ -15,7 +15,7 @@
//! Selection of inputs for building transactions
use crate::address;
use crate::error::{Error, ErrorKind};
use crate::error::Error;
use crate::grin_core::core::amount_to_hr_string;
use crate::grin_core::libtx::{
build,
@ -72,16 +72,15 @@ where
false,
)?;
if amount_includes_fee {
slate.amount = slate
.amount
.checked_sub(fee)
.ok_or(ErrorKind::GenericError(
format!("Transaction amount is too small to include fee").into(),
))?;
slate.amount = slate.amount.checked_sub(fee).ok_or(Error::GenericError(
format!("Transaction amount is too small to include fee").into(),
))?;
};
if fixed_fee.map(|f| fee != f).unwrap_or(false) {
return Err(ErrorKind::Fee("The initially selected fee is not sufficient".into()).into());
return Err(Error::Fee(
"The initially selected fee is not sufficient".into(),
));
}
// Update the fee on the slate so we account for this when building the tx.
@ -192,7 +191,7 @@ where
let sender_address_path = match context.payment_proof_derivation_index {
Some(p) => p,
None => {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Payment proof derivation index required".to_owned(),
)
.into());
@ -420,24 +419,22 @@ where
};
if total == 0 {
return Err(ErrorKind::NotEnoughFunds {
return Err(Error::NotEnoughFunds {
available: 0,
available_disp: amount_to_hr_string(0, false),
needed: amount_with_fee as u64,
needed_disp: amount_to_hr_string(amount_with_fee as u64, false),
}
.into());
});
}
// The amount with fee is more than the total values of our max outputs
if total < amount_with_fee && coins.len() == max_outputs {
return Err(ErrorKind::NotEnoughFunds {
return Err(Error::NotEnoughFunds {
available: total,
available_disp: amount_to_hr_string(total, false),
needed: amount_with_fee as u64,
needed_disp: amount_to_hr_string(amount_with_fee as u64, false),
}
.into());
});
}
let num_outputs = change_outputs + 1;
@ -455,13 +452,12 @@ where
while total < amount_with_fee {
// End the loop if we have selected all the outputs and still not enough funds
if coins.len() == max_outputs {
return Err(ErrorKind::NotEnoughFunds {
return Err(Error::NotEnoughFunds {
available: total as u64,
available_disp: amount_to_hr_string(total, false),
needed: amount_with_fee as u64,
needed_disp: amount_to_hr_string(amount_with_fee as u64, false),
}
.into());
});
}
// select some spendable coins from the wallet
@ -486,7 +482,7 @@ where
// If original amount includes fee, the new amount should
// be reduced, to accommodate the fee.
let new_amount = match amount_includes_fee {
true => amount.checked_sub(fee).ok_or(ErrorKind::GenericError(
true => amount.checked_sub(fee).ok_or(Error::GenericError(
format!("Transaction amount is too small to include fee").into(),
))?,
false => amount,
@ -688,7 +684,7 @@ where
if update_fee {
slate.fee_fields = context
.fee
.ok_or_else(|| ErrorKind::Fee("Missing fee fields".into()))?;
.ok_or_else(|| Error::Fee("Missing fee fields".into()))?;
}
let keychain = wallet.keychain(keychain_mask)?;

View file

@ -29,7 +29,7 @@ use crate::slate::Slate;
use crate::types::{Context, NodeClient, StoredProofInfo, TxLogEntryType, WalletBackend};
use crate::util::OnionV3Address;
use crate::InitTxArgs;
use crate::{address, Error, ErrorKind};
use crate::{address, Error};
use ed25519_dalek::Keypair as DalekKeypair;
use ed25519_dalek::PublicKey as DalekPublicKey;
use ed25519_dalek::SecretKey as DalekSecretKey;
@ -353,15 +353,15 @@ where
}
let tx_vec = updater::retrieve_txs(wallet, tx_id, tx_slate_id, Some(&parent_key_id), false)?;
if tx_vec.len() != 1 {
return Err(ErrorKind::TransactionDoesntExist(tx_id_string).into());
return Err(Error::TransactionDoesntExist(tx_id_string));
}
let tx = tx_vec[0].clone();
match tx.tx_type {
TxLogEntryType::TxSent | TxLogEntryType::TxReceived | TxLogEntryType::TxReverted => {}
_ => return Err(ErrorKind::TransactionNotCancellable(tx_id_string).into()),
_ => return Err(Error::TransactionNotCancellable(tx_id_string)),
}
if tx.confirmed {
return Err(ErrorKind::TransactionNotCancellable(tx_id_string).into());
return Err(Error::TransactionNotCancellable(tx_id_string));
}
// get outputs associated with tx
let res = updater::retrieve_outputs(
@ -405,7 +405,7 @@ where
}
let mut tx = match tx {
Some(t) => t,
None => return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()).into()),
None => return Err(Error::TransactionDoesntExist(slate.id.to_string())),
};
let parent_key = tx.parent_key_id.clone();
{
@ -487,7 +487,7 @@ pub fn create_payment_proof_signature(
let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) {
Ok(k) => k,
Err(e) => {
return Err(ErrorKind::ED25519Key(format!("{}", e)).into());
return Err(Error::ED25519Key(format!("{}", e)));
}
};
let pub_key: DalekPublicKey = (&d_skey).into();
@ -513,56 +513,50 @@ where
{
let tx_vec = updater::retrieve_txs(wallet, None, Some(slate.id), Some(parent_key_id), false)?;
if tx_vec.is_empty() {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"TxLogEntry with original proof info not found (is account correct?)".to_owned(),
)
.into());
));
}
let orig_proof_info = tx_vec[0].clone().payment_proof;
if orig_proof_info.is_some() && slate.payment_proof.is_none() {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Expected Payment Proof for this Transaction is not present".to_owned(),
)
.into());
));
}
if let Some(ref p) = slate.clone().payment_proof {
let orig_proof_info = match orig_proof_info {
Some(p) => p.clone(),
None => {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Original proof info not stored in tx".to_owned(),
)
.into());
));
}
};
let keychain = wallet.keychain(keychain_mask)?;
let index = match context.payment_proof_derivation_index {
Some(i) => i,
None => {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Payment proof derivation index required".to_owned(),
)
.into());
));
}
};
let orig_sender_sk =
address::address_from_derivation_path(&keychain, parent_key_id, index)?;
let orig_sender_address = OnionV3Address::from_private(&orig_sender_sk.0)?;
if p.sender_address != orig_sender_address.to_ed25519()? {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Sender address on slate does not match original sender address".to_owned(),
)
.into());
));
}
if orig_proof_info.receiver_address != p.receiver_address {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Recipient address on slate does not match original recipient address".to_owned(),
)
.into());
));
}
let msg = payment_proof_message(
slate.amount,
@ -572,15 +566,14 @@ where
let sig = match p.receiver_signature {
Some(s) => s,
None => {
return Err(ErrorKind::PaymentProof(
return Err(Error::PaymentProof(
"Recipient did not provide requested proof signature".to_owned(),
)
.into());
));
}
};
if p.receiver_address.verify(&msg, &sig).is_err() {
return Err(ErrorKind::PaymentProof("Invalid proof signature".to_owned()).into());
return Err(Error::PaymentProof("Invalid proof signature".to_owned()));
};
}
Ok(())

View file

@ -25,16 +25,12 @@
use grin_wallet_config as config;
use grin_wallet_util::grin_core;
use grin_wallet_util::grin_keychain;
use grin_wallet_util::grin_store;
use grin_wallet_util::grin_util;
use grin_wallet_util as util;
use blake2_rfc as blake2;
use failure;
extern crate failure_derive;
#[macro_use]
extern crate serde_derive;
#[macro_use]
@ -55,7 +51,7 @@ pub mod slate_versions;
pub mod slatepack;
mod types;
pub use crate::error::{Error, ErrorKind};
pub use crate::error::Error;
pub use crate::slate::{ParticipantData, Slate, SlateState};
pub use crate::slate_versions::v4::sig_is_blank;
pub use crate::slate_versions::{

View file

@ -15,7 +15,7 @@
//! Functions for building partial transactions to be passed
//! around during an interactive wallet exchange
use crate::error::{Error, ErrorKind};
use crate::error::Error;
use crate::grin_core::core::amount_to_hr_string;
use crate::grin_core::core::transaction::{
FeeFields, Input, Inputs, KernelFeatures, NRDRelativeHeight, Output, OutputFeatures,
@ -196,7 +196,7 @@ impl Slate {
pub fn tx_or_err(&self) -> Result<&Transaction, Error> {
match &self.tx {
Some(t) => Ok(t),
None => Err(ErrorKind::SlateTransactionRequired.into()),
None => Err(Error::SlateTransactionRequired),
}
}
@ -204,7 +204,7 @@ impl Slate {
pub fn tx_or_err_mut(&mut self) -> Result<&mut Transaction, Error> {
match &mut self.tx {
Some(t) => Ok(t),
None => Err(ErrorKind::SlateTransactionRequired.into()),
None => Err(Error::SlateTransactionRequired),
}
}
@ -220,7 +220,7 @@ impl Slate {
/// Throw error if this can't be done
pub fn deserialize_upgrade(slate_json: &str) -> Result<Slate, Error> {
let v_slate: VersionedSlate =
serde_json::from_str(slate_json).map_err(|_| ErrorKind::SlateVersionParse)?;
serde_json::from_str(slate_json).map_err(|_| Error::SlateVersionParse)?;
Slate::upgrade(v_slate)
}
@ -352,26 +352,22 @@ impl Slate {
0 => Ok(KernelFeatures::Plain {
fee: self.fee_fields,
}),
1 => Err(ErrorKind::InvalidKernelFeatures(1).into()),
1 => Err(Error::InvalidKernelFeatures(1)),
2 => Ok(KernelFeatures::HeightLocked {
fee: self.fee_fields,
lock_height: match &self.kernel_features_args {
Some(a) => a.lock_height,
None => {
return Err(ErrorKind::KernelFeaturesMissing(format!("lock_height")).into())
}
None => return Err(Error::KernelFeaturesMissing(format!("lock_height"))),
},
}),
3 => Ok(KernelFeatures::NoRecentDuplicate {
fee: self.fee_fields,
relative_height: match &self.kernel_features_args {
Some(a) => NRDRelativeHeight::new(a.lock_height)?,
None => {
return Err(ErrorKind::KernelFeaturesMissing(format!("lock_height")).into())
}
None => return Err(Error::KernelFeaturesMissing(format!("lock_height"))),
},
}),
n => Err(ErrorKind::UnknownKernelFeatures(n).into()),
n => Err(Error::UnknownKernelFeatures(n)),
}
}
@ -436,11 +432,11 @@ impl Slate {
.map(|p| &p.public_nonce)
.collect();
if pub_nonces.len() == 0 {
return Err(ErrorKind::Commit(format!("Participant nonces cannot be empty")).into());
return Err(Error::Commit(format!("Participant nonces cannot be empty")));
}
match PublicKey::from_combination(secp, pub_nonces) {
Ok(k) => Ok(k),
Err(e) => Err(ErrorKind::Secp(e).into()),
Err(e) => Err(Error::Secp(e)),
}
}
@ -452,13 +448,13 @@ impl Slate {
.map(|p| &p.public_blind_excess)
.collect();
if pub_blinds.len() == 0 {
return Err(
ErrorKind::Commit(format!("Participant Blind sums cannot be empty")).into(),
);
return Err(Error::Commit(format!(
"Participant Blind sums cannot be empty"
)));
}
match PublicKey::from_combination(secp, pub_blinds) {
Ok(k) => Ok(k),
Err(e) => Err(ErrorKind::Secp(e).into()),
Err(e) => Err(Error::Secp(e)),
}
}
@ -553,9 +549,11 @@ impl Slate {
if fee > tx.fee() {
// apply fee mask past HF4
return Err(
ErrorKind::Fee(format!("Fee Dispute Error: {}, {}", tx.fee(), fee,)).into(),
);
return Err(Error::Fee(format!(
"Fee Dispute Error: {}, {}",
tx.fee(),
fee,
)));
}
if fee > self.amount + self.fee_fields.fee() {
@ -565,7 +563,7 @@ impl Slate {
amount_to_hr_string(self.amount + self.fee_fields.fee(), false)
);
info!("{}", reason);
return Err(ErrorKind::Fee(reason).into());
return Err(Error::Fee(reason));
}
Ok(())

View file

@ -24,7 +24,7 @@ use crate::grin_core::global;
use crate::grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use crate::grin_util::secp::key::SecretKey;
use crate::util::OnionV3Address;
use crate::{Error, ErrorKind};
use crate::Error;
use std::convert::TryFrom;
use std::fmt::{self, Display};
@ -91,7 +91,7 @@ impl TryFrom<&str> for SlatepackAddress {
let pub_key = match edDalekPublicKey::from_bytes(&bytes) {
Ok(k) => k,
Err(e) => {
return Err(ErrorKind::ED25519Key(format!("{}", e)).into());
return Err(Error::ED25519Key(format!("{}", e)));
}
};
Ok(SlatepackAddress { hrp, pub_key })
@ -127,9 +127,9 @@ impl TryFrom<&SlatepackAddress> for xDalekPublicKey {
let ep = match cep.decompress() {
Some(p) => p,
None => {
return Err(
ErrorKind::ED25519Key("Can't decompress ed25519 Edwards Point".into()).into(),
);
return Err(Error::ED25519Key(
"Can't decompress ed25519 Edwards Point".into(),
));
}
};
let res = xDalekPublicKey::from(ep.to_montgomery().to_bytes());
@ -143,11 +143,10 @@ impl TryFrom<&SecretKey> for SlatepackAddress {
let d_skey = match edDalekSecretKey::from_bytes(&key.0) {
Ok(k) => k,
Err(e) => {
return Err(ErrorKind::ED25519Key(format!(
return Err(Error::ED25519Key(format!(
"Can't create slatepack address from SecretKey: {}",
e
))
.into());
)));
}
};
let d_pub_key: edDalekPublicKey = (&d_skey).into();

View file

@ -20,7 +20,7 @@
// 3. Base58 encode bytes from step 2
// Finally add armor framing and space/newline formatting as desired
use crate::{Error, ErrorKind};
use crate::Error;
use grin_wallet_util::{byte_ser, grin_core::global::max_tx_weight};
use regex::Regex;
use sha2::{Digest, Sha256};
@ -97,7 +97,7 @@ impl SlatepackArmor {
// Decode payload from base58
let base_decode = bs58::decode(&clean_payload)
.into_vec()
.map_err(|_| ErrorKind::SlatepackDeser("Bad bytes".into()))?;
.map_err(|_| Error::SlatepackDeser("Bad bytes".into()))?;
let error_code = &base_decode[0..4];
let slatepack_bytes = &base_decode[4..];
// Make sure the error check code is valid for the slate data
@ -109,7 +109,7 @@ impl SlatepackArmor {
/// Encode an armored slatepack
pub fn encode(slatepack: &Slatepack) -> Result<String, Error> {
let slatepack_bytes = byte_ser::to_bytes(&SlatepackBin(slatepack.clone()))
.map_err(|_| ErrorKind::SlatepackSer)?;
.map_err(|_| Error::SlatepackSer)?;
let encoded_slatepack = base58check(&slatepack_bytes)?;
let formatted_slatepack = format_slatepack(&format!("{}{}", HEADER, encoded_slatepack))?;
Ok(format!("{}{}\n", formatted_slatepack, FOOTER))
@ -122,32 +122,29 @@ fn error_check(error_code: &[u8], slate_bytes: &[u8]) -> Result<(), Error> {
if error_code.iter().eq(new_check.iter()) {
Ok(())
} else {
Err(ErrorKind::InvalidSlatepackData(
Err(Error::InvalidSlatepackData(
"Bad slate error code- some data was corrupted".to_string(),
)
.into())
))
}
}
// Checks header framing bytes and returns an error if they are invalid
fn check_header(header: &[u8]) -> Result<(), Error> {
let framing =
str::from_utf8(header).map_err(|_| ErrorKind::SlatepackDeser("Bad bytes".into()))?;
let framing = str::from_utf8(header).map_err(|_| Error::SlatepackDeser("Bad bytes".into()))?;
if HEADER_REGEX.is_match(framing) {
Ok(())
} else {
Err(ErrorKind::InvalidSlatepackData("Bad armor header".to_string()).into())
Err(Error::InvalidSlatepackData("Bad armor header".to_string()))
}
}
// Checks footer framing bytes and returns an error if they are invalid
fn check_footer(footer: &[u8]) -> Result<(), Error> {
let framing =
str::from_utf8(footer).map_err(|_| ErrorKind::SlatepackDeser("Bad bytes".into()))?;
let framing = str::from_utf8(footer).map_err(|_| Error::SlatepackDeser("Bad bytes".into()))?;
if FOOTER_REGEX.is_match(framing) {
Ok(())
} else {
Err(ErrorKind::InvalidSlatepackData("Bad armor footer".to_string()).into())
Err(Error::InvalidSlatepackData("Bad armor footer".to_string()))
}
}

View file

@ -16,11 +16,11 @@ use std::convert::TryFrom;
use std::str;
use super::armor::HEADER;
use crate::Error;
use crate::{
slatepack, Slate, SlateVersion, Slatepack, SlatepackAddress, SlatepackArmor, SlatepackBin,
VersionedBinSlate, VersionedSlate,
};
use crate::{Error, ErrorKind};
use grin_wallet_util::byte_ser;
@ -53,7 +53,7 @@ impl<'a> Slatepacker<'a> {
let data_len = data.len() as u64;
if data_len < slatepack::min_size() || data_len > slatepack::max_size() {
let msg = format!("Data invalid length");
return Err(ErrorKind::SlatepackDeser(msg).into());
return Err(Error::SlatepackDeser(msg));
}
let test_header = &data[..HEADER.len()];
@ -76,11 +76,11 @@ impl<'a> Slatepacker<'a> {
debug!("Not a valid binary slatepack: {} - Will try JSON", e);
let content = String::from_utf8(data).map_err(|e| {
let msg = format!("{}", e);
ErrorKind::SlatepackDeser(msg)
Error::SlatepackDeser(msg)
})?;
serde_json::from_str(&content).map_err(|e| {
let msg = format!("Error reading JSON slatepack: {}", e);
ErrorKind::SlatepackDeser(msg)
Error::SlatepackDeser(msg)
})?
}
};
@ -95,10 +95,9 @@ impl<'a> Slatepacker<'a> {
/// Create slatepack from slate and args
pub fn create_slatepack(&self, slate: &Slate) -> Result<Slatepack, Error> {
let out_slate = VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?;
let bin_slate =
VersionedBinSlate::try_from(out_slate).map_err(|_| ErrorKind::SlatepackSer)?;
let bin_slate = VersionedBinSlate::try_from(out_slate).map_err(|_| Error::SlatepackSer)?;
let mut slatepack = Slatepack::default();
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| ErrorKind::SlatepackSer)?;
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| Error::SlatepackSer)?;
slatepack.sender = self.0.sender.clone();
slatepack.try_encrypt_payload(self.0.recipients.clone())?;
Ok(slatepack)
@ -115,7 +114,7 @@ impl<'a> Slatepacker<'a> {
byte_ser::from_bytes::<VersionedBinSlate>(&slatepack.payload).map_err(|e| {
error!("Error reading slate from armored slatepack: {}", e);
let msg = format!("{}", e);
ErrorKind::SlatepackDeser(msg)
Error::SlatepackDeser(msg)
})?;
Ok(Slate::upgrade(slate_bin.into())?)
}

View file

@ -21,7 +21,7 @@ use x25519_dalek::StaticSecret;
use crate::dalek_ser;
use crate::grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use crate::{Error, ErrorKind};
use crate::Error;
use grin_wallet_util::byte_ser;
use super::SlatepackAddress;
@ -147,7 +147,7 @@ impl Slatepack {
// Create encrypted metadata, which will be length prefixed
let bin_meta = SlatepackEncMetadataBin(self.encrypted_meta.clone());
let mut to_encrypt = byte_ser::to_bytes(&bin_meta).map_err(|_| ErrorKind::SlatepackSer)?;
let mut to_encrypt = byte_ser::to_bytes(&bin_meta).map_err(|_| Error::SlatepackSer)?;
if self.future_test_mode {
Slatepack::pad_test_data(&mut to_encrypt);
@ -213,7 +213,7 @@ impl Slatepack {
let meta_len = Cursor::new(len_bytes).read_u32::<BigEndian>()?;
self.payload = decrypted.split_off(meta_len as usize + 4);
let meta = byte_ser::from_bytes::<SlatepackEncMetadataBin>(&decrypted)
.map_err(|_| ErrorKind::SlatepackSer)?
.map_err(|_| Error::SlatepackSer)?
.0;
self.sender = meta.sender;
self.encrypted_meta.recipients = meta.recipients;
@ -777,8 +777,8 @@ fn slatepack_encrypted_meta() -> Result<(), Error> {
slatepack.add_recipient(SlatepackAddress::random());
let v_slate = VersionedSlate::into_version(Slate::blank(2, false), SlateVersion::V4)?;
let bin_slate = VersionedBinSlate::try_from(v_slate).map_err(|_| ErrorKind::SlatepackSer)?;
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| ErrorKind::SlatepackSer)?;
let bin_slate = VersionedBinSlate::try_from(v_slate).map_err(|_| Error::SlatepackSer)?;
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| Error::SlatepackSer)?;
let orig_sp = slatepack.clone();
@ -826,8 +826,8 @@ fn slatepack_encrypted_meta_future() -> Result<(), Error> {
slatepack.add_recipient(SlatepackAddress::random());
let v_slate = VersionedSlate::into_version(Slate::blank(2, false), SlateVersion::V4)?;
let bin_slate = VersionedBinSlate::try_from(v_slate).map_err(|_| ErrorKind::SlatepackSer)?;
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| ErrorKind::SlatepackSer)?;
let bin_slate = VersionedBinSlate::try_from(v_slate).map_err(|_| Error::SlatepackSer)?;
slatepack.payload = byte_ser::to_bytes(&bin_slate).map_err(|_| Error::SlatepackSer)?;
let orig_sp = slatepack.clone();

View file

@ -16,7 +16,7 @@
//! implementation
use crate::config::{TorConfig, WalletConfig};
use crate::error::{Error, ErrorKind};
use crate::error::Error;
use crate::grin_core::core::hash::Hash;
use crate::grin_core::core::FeeFields;
use crate::grin_core::core::{Output, Transaction, TxKernel};
@ -32,7 +32,6 @@ use crate::InitTxArgs;
use chrono::prelude::*;
use ed25519_dalek::PublicKey as DalekPublicKey;
use ed25519_dalek::Signature as DalekSignature;
use failure::ResultExt;
use rand::rngs::mock::StepRng;
use rand::thread_rng;
use serde;
@ -681,7 +680,7 @@ impl BlockIdentifier {
/// convert to hex string
pub fn from_hex(hex: &str) -> Result<BlockIdentifier, Error> {
let hash =
Hash::from_hex(hex).context(ErrorKind::GenericError("Invalid hex".to_owned()))?;
Hash::from_hex(hex).map_err(|e| Error::GenericError(format!("Invalid hex: {}", e)))?;
Ok(BlockIdentifier(hash))
}
}

View file

@ -20,11 +20,9 @@ use crate::util::secp::key::SecretKey;
use crate::util::{Mutex, ZeroingString};
/// Argument parsing and error handling for wallet commands
use clap::ArgMatches;
use failure::Fail;
use grin_wallet_api::Owner;
use grin_wallet_config::{config_file_exists, TorConfig, WalletConfig};
use grin_wallet_controller::command;
use grin_wallet_controller::{Error, ErrorKind};
use grin_wallet_controller::{command, Error};
use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl};
use grin_wallet_libwallet::{self, Slate, SlatepackAddress, SlatepackArmor};
use grin_wallet_libwallet::{IssueInvoiceTxArgs, NodeClient, WalletInst, WalletLCProvider};
@ -44,22 +42,22 @@ macro_rules! arg_parse {
match $r {
Ok(res) => res,
Err(e) => {
return Err(ErrorKind::ArgumentError(format!("{}", e)).into());
return Err(Error::ArgumentError(format!("{}", e)));
}
}
};
}
/// Simple error definition, just so we can return errors from all commands
/// and let the caller figure out what to do
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
#[derive(Clone, Eq, PartialEq, Debug, thiserror::Error)]
pub enum ParseError {
#[fail(display = "Invalid Arguments: {}", _0)]
#[error("Invalid Arguments: {0}")]
ArgumentError(String),
#[fail(display = "Parsing IO error: {}", _0)]
#[error("Parsing IO error: {0}")]
IOError(String),
#[fail(display = "Wallet configuration already exists: {}", _0)]
#[error("Wallet configuration already exists: {0}")]
WalletExists(String),
#[fail(display = "User Cancelled")]
#[error("User Cancelled")]
CancelledError,
}
@ -722,7 +720,7 @@ where
// validate input
if !Path::new(&file).is_file() {
let msg = format!("File {} not found.", &file);
return Err(ErrorKind::GenericError(msg).into());
return Err(Error::GenericError(msg));
}
Some(file)
}
@ -733,7 +731,7 @@ where
if input_file.is_none() {
input_slatepack_message = Some(prompt_slatepack().map_err(|e| {
let msg = format!("{}", e);
ErrorKind::GenericError(msg)
Error::GenericError(msg)
})?)
}
@ -1299,7 +1297,7 @@ where
}
_ => {
let msg = format!("Unknown wallet command, use 'grin-wallet help' for details");
return Err(ErrorKind::ArgumentError(msg).into());
return Err(Error::ArgumentError(msg));
}
}
}

View file

@ -721,6 +721,6 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
fn wallet_command_line() {
let test_dir = "target/test_output/command_line";
if let Err(e) = command_line_test_impl(test_dir) {
panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap());
panic!("Libwallet Error: {}", e);
}
}

View file

@ -160,7 +160,7 @@ pub fn config_command_wallet(
let mut config_file_name = current_dir.clone();
config_file_name.push("grin-wallet.toml");
if config_file_name.exists() {
return Err(grin_wallet_controller::ErrorKind::ArgumentError(
return Err(grin_wallet_controller::Error::ArgumentError(
"grin-wallet.toml already exists in the target directory. Please remove it first"
.to_owned(),
))?;
@ -472,11 +472,26 @@ pub fn derive_ecdh_key(sec_key_str: &str, other_pubkey: &PublicKey) -> SecretKey
}
// Types to make working with json responses easier
#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub struct WalletAPIReturnError {
pub message: String,
pub code: i32,
}
impl std::fmt::Display for WalletAPIReturnError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} - {}", self.code, &self.message)
}
}
impl From<grin_wallet_controller::Error> for WalletAPIReturnError {
fn from(error: grin_wallet_controller::Error) -> WalletAPIReturnError {
WalletAPIReturnError {
message: error.to_string(),
code: -1,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RetrieveSummaryInfoResp(pub bool, pub WalletInfo);

View file

@ -16,6 +16,7 @@ serde_derive = "1"
ed25519-dalek = "1.0.0-pre.4"
data-encoding = "2"
sha3 = "0.8"
thiserror = "1"
# For Release
#grin_core = "4.0.0"

View file

@ -20,12 +20,14 @@ use sha3::{Digest, Sha3_256};
use std::convert::TryFrom;
use std::fmt;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, Eq, PartialEq, thiserror::Error, Serialize, Deserialize)]
/// OnionV3 Address Errors
pub enum OnionV3Error {
/// Error decoding an address from a string
#[error("Address Decoding: {0}")]
AddressDecoding(String),
/// Error with given private key
#[error("Invalid Private Key: {0}")]
InvalidPrivateKey(String),
}