From 652e69855223d5d5326f86b9d924fc891df8376e Mon Sep 17 00:00:00 2001 From: bayk Date: Mon, 12 Aug 2024 18:28:11 -0700 Subject: [PATCH] rebase 5.3.X [PATCH 116/142] Replace `failure` with `thiserror` (#654) --- Cargo.lock | 21 +- Cargo.toml | 3 +- api/Cargo.toml | 2 - api/src/foreign_rpc.rs | 94 ++--- api/src/lib.rs | 1 - api/src/owner.rs | 52 +-- api/src/owner_rpc_v2.rs | 214 +++++----- api/src/owner_rpc_v3.rs | 285 ++++++-------- api/src/types.rs | 48 ++- config/Cargo.toml | 3 +- config/src/types.rs | 21 +- controller/Cargo.toml | 3 +- controller/src/command.rs | 500 +++++++++++------------- controller/src/controller.rs | 109 +++--- controller/src/error.rs | 195 +++------ controller/src/lib.rs | 3 +- controller/tests/accounts.rs | 2 +- controller/tests/build_chain.rs | 2 +- controller/tests/build_output.rs | 2 +- controller/tests/check.rs | 6 +- controller/tests/file.rs | 2 +- controller/tests/integrity_kernel.rs | 2 +- controller/tests/late_lock.rs | 2 +- controller/tests/no_change.rs | 2 +- controller/tests/payment_proofs.rs | 2 +- controller/tests/repost.rs | 2 +- controller/tests/revert.rs | 4 +- controller/tests/self_send.rs | 2 +- controller/tests/self_spend.rs | 2 +- controller/tests/slatepack.rs | 13 +- controller/tests/transaction.rs | 4 +- controller/tests/ttl_cutoff.rs | 2 +- controller/tests/updater_thread.rs | 2 +- impls/Cargo.toml | 3 +- impls/src/adapters/file.rs | 72 ++-- impls/src/adapters/http.rs | 146 +++---- impls/src/adapters/libp2p_messaging.rs | 9 +- impls/src/adapters/mod.rs | 23 +- impls/src/adapters/mwcmq.rs | 121 +++--- impls/src/adapters/types.rs | 19 +- impls/src/backends/lmdb.rs | 29 +- impls/src/client_utils/client.rs | 76 +--- impls/src/client_utils/json_rpc.rs | 9 +- impls/src/client_utils/mod.rs | 2 +- impls/src/error.rs | 193 ++------- impls/src/lib.rs | 2 +- impls/src/lifecycle/default.rs | 59 ++- impls/src/lifecycle/seed.rs | 70 ++-- impls/src/node_clients/http.rs | 26 +- impls/src/test_framework/testclient.rs | 39 +- impls/src/tor/bridge.rs | 45 ++- impls/src/tor/config.rs | 44 +-- impls/src/tor/process.rs | 21 +- impls/src/tor/proxy.rs | 10 +- libwallet/Cargo.toml | 3 +- libwallet/src/address.rs | 21 +- libwallet/src/api_impl/foreign.rs | 37 +- libwallet/src/api_impl/owner.rs | 87 ++--- libwallet/src/api_impl/owner_eth.rs | 5 +- libwallet/src/api_impl/owner_libp2p.rs | 7 +- libwallet/src/api_impl/owner_swap.rs | 135 +++---- libwallet/src/error.rs | 321 +++++---------- libwallet/src/internal/keys.rs | 12 +- libwallet/src/internal/scan.rs | 29 +- libwallet/src/internal/selection.rs | 33 +- libwallet/src/internal/tx.rs | 76 ++-- libwallet/src/internal/updater.rs | 4 +- libwallet/src/lib.rs | 6 +- libwallet/src/proof/base58.rs | 18 +- libwallet/src/proof/crypto.rs | 27 +- libwallet/src/proof/hasher.rs | 8 +- libwallet/src/proof/message.rs | 30 +- libwallet/src/proof/proofaddress.rs | 11 +- libwallet/src/proof/tx_proof.rs | 126 +++--- libwallet/src/slate.rs | 129 +++--- libwallet/src/slate_versions/mod.rs | 12 +- libwallet/src/slate_versions/v3.rs | 23 +- libwallet/src/slatepack/armor.rs | 26 +- libwallet/src/slatepack/slatepack.rs | 107 ++--- libwallet/src/swap/api.rs | 34 +- libwallet/src/swap/bitcoin/api.rs | 72 ++-- libwallet/src/swap/bitcoin/client.rs | 26 +- libwallet/src/swap/bitcoin/electrum.rs | 66 ++-- libwallet/src/swap/bitcoin/rpc.rs | 42 +- libwallet/src/swap/bitcoin/types.rs | 68 ++-- libwallet/src/swap/buyer.rs | 103 +++-- libwallet/src/swap/error.rs | 188 ++++----- libwallet/src/swap/ethereum/api.rs | 81 ++-- libwallet/src/swap/ethereum/client.rs | 47 +-- libwallet/src/swap/ethereum/ethereum.rs | 46 +-- libwallet/src/swap/ethereum/infura.rs | 150 ++++--- libwallet/src/swap/ethereum/types.rs | 24 +- libwallet/src/swap/fsm/buyer_swap.rs | 66 ++-- libwallet/src/swap/fsm/machine.rs | 32 +- libwallet/src/swap/fsm/seller_swap.rs | 80 ++-- libwallet/src/swap/fsm/state.rs | 8 +- libwallet/src/swap/message.rs | 53 ++- libwallet/src/swap/mod.rs | 28 +- libwallet/src/swap/multisig/error.rs | 40 +- libwallet/src/swap/multisig/mod.rs | 2 +- libwallet/src/swap/multisig/types.rs | 107 +++-- libwallet/src/swap/seller.rs | 90 ++--- libwallet/src/swap/ser.rs | 14 +- libwallet/src/swap/swap.rs | 47 +-- libwallet/src/swap/trades.rs | 125 +++--- libwallet/src/swap/types.rs | 121 +++--- libwallet/src/types.rs | 4 +- src/cmd/wallet_args.rs | 27 +- tests/cmd_line_basic.rs | 6 +- tests/common/mod.rs | 19 +- util/Cargo.toml | 3 +- util/src/ov3.rs | 8 +- 112 files changed, 2453 insertions(+), 3292 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b68e86a0a..a953a1ae1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1627,7 +1627,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" dependencies = [ - "backtrace", "failure_derive", ] @@ -2254,8 +2253,6 @@ dependencies = [ "colored", "easy-jsonrpc-mw", "ed25519-dalek", - "failure", - "failure_derive", "grin_wallet_config", "grin_wallet_impls", "grin_wallet_libwallet", @@ -2276,13 +2273,12 @@ name = "grin_wallet_config" version = "5.1.0" dependencies = [ "dirs 2.0.2", - "failure", - "failure_derive", "grin_wallet_util", "pretty_assertions", "rand 0.6.5", "serde", "serde_derive", + "thiserror", "toml", ] @@ -2294,8 +2290,6 @@ dependencies = [ "colored", "easy-jsonrpc-mw", "ed25519-dalek", - "failure", - "failure_derive", "futures 0.3.30", "grin_wallet_api", "grin_wallet_config", @@ -2315,6 +2309,7 @@ dependencies = [ "serde_derive", "serde_json", "term 0.6.1", + "thiserror", "tokio 0.2.25", "url", "uuid", @@ -2332,8 +2327,6 @@ dependencies = [ "chrono", "data-encoding", "ed25519-dalek", - "failure", - "failure_derive", "futures 0.3.30", "grin_wallet_config", "grin_wallet_libwallet", @@ -2351,6 +2344,7 @@ dependencies = [ "serde_derive", "serde_json", "sysinfo", + "thiserror", "timer", "tokio 0.2.25", "url", @@ -2380,8 +2374,6 @@ dependencies = [ "data-encoding", "digest 0.9.0", "ed25519-dalek", - "failure", - "failure_derive", "futures-timer", "grin_wallet_config", "grin_wallet_util", @@ -2409,6 +2401,7 @@ dependencies = [ "smaz", "strum", "strum_macros", + "thiserror", "tokio 0.2.25", "uuid", "wagyu-ethereum", @@ -2424,8 +2417,6 @@ version = "5.1.0" dependencies = [ "data-encoding", "ed25519-dalek", - "failure", - "failure_derive", "grin_api", "grin_chain", "grin_core", @@ -2439,6 +2430,7 @@ dependencies = [ "serde", "serde_derive", "sha3 0.8.2", + "thiserror", "tokio 0.2.25", ] @@ -3605,8 +3597,6 @@ dependencies = [ "clap", "easy-jsonrpc-mw", "ed25519-dalek", - "failure", - "failure_derive", "funty", "grin_wallet_api", "grin_wallet_config", @@ -3625,6 +3615,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "thiserror", "url", "uuid", "x25519-dalek 0.6.0", diff --git a/Cargo.toml b/Cargo.toml index 0308c1691..817092c39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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.10.0" log = "0.4" linefeed = "0.6" diff --git a/api/Cargo.toml b/api/Cargo.toml index 315f897bd..ac8528570 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -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" diff --git a/api/src/foreign_rpc.rs b/api/src/foreign_rpc.rs index 29f784e36..96c9ff032 100644 --- a/api/src/foreign_rpc.rs +++ b/api/src/foreign_rpc.rs @@ -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; @@ -69,7 +68,7 @@ pub trait ForeignRpc { # ,false, 0, false, false, true); ``` */ - fn check_version(&self) -> Result; + fn check_version(&self) -> Result; /** Networked version of [Foreign::check_version](struct.Foreign.html#method.check_version). @@ -99,7 +98,7 @@ pub trait ForeignRpc { # ,false, 0, false, false, true); ``` */ - fn get_proof_address(&self) -> Result; + fn get_proof_address(&self) -> Result; /** Networked Legacy (non-secure token) version of [Foreign::build_coinbase](struct.Foreign.html#method.build_coinbase). @@ -150,7 +149,7 @@ pub trait ForeignRpc { ``` */ - fn build_coinbase(&self, block_fees: &BlockFees) -> Result; + fn build_coinbase(&self, block_fees: &BlockFees) -> Result; /** Networked version of [Foreign::verify_slate_messages](struct.Foreign.html#method.verify_slate_messages). @@ -232,7 +231,7 @@ pub trait ForeignRpc { # ,false, 1 ,false, false, false); ``` */ - fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind>; + fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), Error>; /** Networked version of [Foreign::receive_tx](struct.Foreign.html#method.receive_tx). @@ -548,7 +547,7 @@ pub trait ForeignRpc { slate: VersionedSlate, dest_acct_name: Option, message: Option, - ) -> Result; + ) -> Result; /** @@ -906,20 +905,20 @@ pub trait ForeignRpc { # ,false, 5, false, true, true); ``` */ - fn finalize_invoice_tx(&self, slate: VersionedSlate) -> Result; + fn finalize_invoice_tx(&self, slate: VersionedSlate) -> Result; /** Networked version of [Foreign::receive_swap_message](struct.Foreign.html#method.receive_swap_message). # Json rpc example */ - fn receive_swap_message(&self, message: String) -> Result<(), ErrorKind>; + fn receive_swap_message(&self, message: String) -> Result<(), Error>; /** Networked version of [Foreign::marketplace_message](struct.Foreign.html#method.marketplace_message). # Json rpc example */ - fn marketplace_message(&self, accept_offer_message: &String) -> Result; + fn marketplace_message(&self, accept_offer_message: &String) -> Result; } impl<'a, L, C, K> ForeignRpc for Foreign<'a, L, C, K> @@ -928,28 +927,22 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - fn check_version(&self) -> Result { - Foreign::check_version(self).map_err(|e| e.kind()) + fn check_version(&self) -> Result { + Foreign::check_version(self) } - fn get_proof_address(&self) -> Result { - Foreign::get_proof_address(self).map_err(|e| e.kind()) + fn get_proof_address(&self) -> Result { + Foreign::get_proof_address(self) } - fn build_coinbase(&self, block_fees: &BlockFees) -> Result { - let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?; + fn build_coinbase(&self, block_fees: &BlockFees) -> Result { + let cb: CbData = Foreign::build_coinbase(self, block_fees)?; Ok(VersionedCoinbase::into_version(cb, SlateVersion::V2)) } // verify_slate_messages doesn't make sense for the slate pack. That is why supporting only plain slates - fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind> { - Foreign::verify_slate_messages( - self, - &slate.into_slate_plain(true).map_err(|e| { - ErrorKind::Compatibility(format!("Expected non ecrypted slate only, {}", e)) - })?, - ) - .map_err(|e| e.kind()) + fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), Error> { + Foreign::verify_slate_messages(self, &slate.into_slate_plain(true)?) } fn receive_tx( @@ -957,23 +950,20 @@ where in_slate: VersionedSlate, dest_acct_name: Option, message: Option, - ) -> Result { + ) -> Result { let version = in_slate.version(); let (slate_from, sender) = if in_slate.is_slatepack() { - let (slate_from, content, sender) = - Foreign::decrypt_slate(self, in_slate).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to decrypt a slatepack, {}", e)) - })?; + let (slate_from, content, sender) = Foreign::decrypt_slate(self, in_slate)?; if content != SlatePurpose::SendInitial { - return Err(ErrorKind::SlatepackDecodeError(format!( + return Err(Error::SlatepackDecodeError(format!( "Expecting SendInitial content of the slatepack, get {:?}", content ))); } (slate_from, sender) } else { - let slate_from = in_slate.into_slate_plain(false).map_err(|e| e.kind())?; + let slate_from = in_slate.into_slate_plain(false)?; (slate_from, None) }; let out_slate = Foreign::receive_tx( @@ -982,8 +972,7 @@ where sender.map(|p| ProvableAddress::from_tor_pub_key(&p).public_key), // We don't want to change RPC. New fields required new version dest_acct_name.as_ref().map(String::as_str), message, - ) - .map_err(|e| e.kind())?; + )?; let res_slate = Foreign::encrypt_slate( self, @@ -993,24 +982,18 @@ where sender, // sending back to the sender None, self.doctest_mode, - ) - .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) - })?; + )?; Ok(res_slate) } - fn finalize_invoice_tx(&self, in_slate: VersionedSlate) -> Result { + fn finalize_invoice_tx(&self, in_slate: VersionedSlate) -> Result { let version = in_slate.version(); let (in_slate, sender) = if in_slate.is_slatepack() { - let (slate_from, content, sender) = - Foreign::decrypt_slate(self, in_slate).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to decrypt a slatepack, {}", e)) - })?; + let (slate_from, content, sender) = Foreign::decrypt_slate(self, in_slate)?; if content != SlatePurpose::InvoiceResponse { - return Err(ErrorKind::SlatepackDecodeError(format!( + return Err(Error::SlatepackDecodeError(format!( "Expecting InvoiceResponse content of the slatepack, get {:?}", content ))); @@ -1018,11 +1001,11 @@ where (slate_from, sender) } else { - let slate_from = in_slate.into_slate_plain(false).map_err(|e| e.kind())?; + let slate_from = in_slate.into_slate_plain(false)?; (slate_from, None) }; - let out_slate = Foreign::finalize_invoice_tx(self, &in_slate).map_err(|e| e.kind())?; + let out_slate = Foreign::finalize_invoice_tx(self, &in_slate)?; let res_slate = Foreign::encrypt_slate( self, @@ -1032,24 +1015,17 @@ where sender, // sending back to the sender None, self.doctest_mode, - ) - .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) - })?; + )?; Ok(res_slate) } - fn receive_swap_message(&self, message: String) -> Result<(), ErrorKind> { - Foreign::receive_swap_message(&self, &message).map_err(|e| { - ErrorKind::SwapError(format!("Error encountered receiving swap message, {}", e)) - })?; + fn receive_swap_message(&self, message: String) -> Result<(), Error> { + Foreign::receive_swap_message(&self, &message)?; Ok(()) } - fn marketplace_message(&self, message: &String) -> Result { - let res = Foreign::marketplace_message(&self, &message).map_err(|e| { - ErrorKind::SwapError(format!("Error encountered receiving swap message, {}", e)) - })?; + fn marketplace_message(&self, message: &String) -> Result { + let res = Foreign::marketplace_message(&self, &message)?; Ok(res) } } @@ -1060,7 +1036,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(()) } diff --git a/api/src/lib.rs b/api/src/lib.rs index dd313ab4c..7b4089a7e 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -28,7 +28,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; diff --git a/api/src/owner.rs b/api/src/owner.rs index 24d7c8c38..cb0af657f 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -33,7 +33,7 @@ use crate::libwallet::swap::fsm::state::{StateEtaInfo, StateId, StateProcessResp use crate::libwallet::swap::types::{Action, Currency, SwapTransactionsConfirmations}; use crate::libwallet::swap::{message::Message, swap::Swap, swap::SwapJournalRecord}; use crate::libwallet::{ - AcctPathMapping, BuiltOutput, Error, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, + AcctPathMapping, BuiltOutput, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, OutputCommitMapping, PaymentProof, Slate, SlatePurpose, SlateVersion, SwapStartArgs, TxLogEntry, VersionedSlate, ViewWallet, WalletInfo, WalletInst, WalletLCProvider, @@ -704,19 +704,17 @@ where //minimum_confirmations cannot be zero. let minimum_confirmations = args.minimum_confirmations.clone(); if minimum_confirmations < 1 { - return Err(ErrorKind::ClientCallback( + return Err(Error::ClientCallback( "Minimum_confirmations can not be smaller than 1".to_owned(), - ) - .into()); + )); } match args.send_args.clone() { Some(sa) => { if sa.post_tx && !sa.finalize { - return Err(ErrorKind::ClientCallback( + return Err(Error::ClientCallback( "Transcations can not be posted without being finalized!".to_owned(), - ) - .into()); + )); } } None => {} @@ -738,16 +736,13 @@ where let comm_adapter = create_sender(&sa.method, &sa.dest, &sa.apisecret, tor_config_lock.clone()) .map_err(|e| { - ErrorKind::GenericError(format!("Unable to create a sender, {}", e)) + Error::GenericError(format!("Unable to create a sender, {}", e)) })?; let other_wallet_version = comm_adapter .check_other_wallet_version(&sa.dest) .map_err(|e| { - ErrorKind::GenericError(format!( - "Unable to get other wallet info, {}", - e - )) + Error::GenericError(format!("Unable to get other wallet info, {}", e)) })?; if let Some(other_wallet_version) = &other_wallet_version { @@ -797,7 +792,7 @@ where &secp, ) .map_err(|e| { - ErrorKind::ClientCallback(format!( + Error::ClientCallback(format!( "Unable to send slate {} with {}, {}", slate.id, sa.method, e )) @@ -805,10 +800,9 @@ where } None => { error!("unsupported payment method: {}", sa.method); - return Err(ErrorKind::ClientCallback( + return Err(Error::ClientCallback( "unsupported payment method".to_owned(), - ) - .into()); + )); } }; @@ -960,10 +954,9 @@ where //minimum_confirmations cannot be zero. let minimum_confirmations = args.minimum_confirmations.clone(); if minimum_confirmations < 1 { - return Err(ErrorKind::ClientCallback( + return Err(Error::ClientCallback( "minimum_confirmations can not smaller than 1".to_owned(), - ) - .into()); + )); } let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; @@ -2443,6 +2436,7 @@ where // Updating wallet state first because we need to select outputs. owner::update_wallet_state(self.wallet_inst.clone(), keychain_mask, &None)?; owner_swap::swap_start(self.wallet_inst.clone(), keychain_mask, params) + .map_err(|e| e.into()) } pub fn swap_create_from_offer( @@ -2455,6 +2449,7 @@ where keychain_mask, message_filename, ) + .map_err(|e| e.into()) } /// List all available swap operations. SwapId & Status @@ -2464,6 +2459,7 @@ where do_check: bool, ) -> Result<(Vec, Vec), Error> { owner_swap::swap_list(self.wallet_inst.clone(), keychain_mask, do_check) + .map_err(|e| e.into()) } /// Delete swap trade @@ -2473,6 +2469,7 @@ where swap_id: String, ) -> Result<(), Error> { owner_swap::swap_delete(self.wallet_inst.clone(), keychain_mask, &swap_id) + .map_err(|e| e.into()) } /// Retrieve swap trade pub fn swap_get( @@ -2481,6 +2478,7 @@ where swap_id: String, ) -> Result { owner_swap::swap_get(self.wallet_inst.clone(), keychain_mask, &swap_id) + .map_err(|e| e.into()) } /// Adjust the sate of swap trade. @@ -2513,6 +2511,7 @@ where eth_infura_project_id, tag, ) + .map_err(|e| e.into()) } /// Dump swap file content @@ -2522,11 +2521,12 @@ where swap_id: String, ) -> Result { owner_swap::swap_dump(self.wallet_inst.clone(), keychain_mask, &swap_id) + .map_err(|e| e.into()) } /// dump ethereum info pub fn eth_info(&self, currency: Currency) -> Result<(String, String, String), Error> { - owner_eth::info(self.wallet_inst.clone(), currency) + owner_eth::info(self.wallet_inst.clone(), currency).map_err(|e| e.into()) } /// ethereum transfer @@ -2535,7 +2535,7 @@ where dest: Option, currency: Currency, amount: Option, - ) -> Result<(), libwallet::swap::ErrorKind> { + ) -> Result<(), libwallet::swap::Error> { owner_eth::transfer(self.wallet_inst.clone(), currency, dest, amount) } @@ -2574,6 +2574,7 @@ where eth_infura_project_id, false, ) + .map_err(|e| e.into()) } /// Get a status of the transactions that involved into the swap. @@ -2597,6 +2598,7 @@ where erc20_swap_contract_address, eth_infura_project_id, ) + .map_err(|e| e.into()) } pub fn swap_process( @@ -2613,7 +2615,7 @@ where eth_infura_project_id: Option, ) -> Result<(StateProcessRespond, Vec), Error> where - F: FnOnce(Message, String, String) -> Result<(bool, String), crate::libwallet::Error> + F: FnOnce(Message, String, String) -> Result<(bool, String), libwallet::swap::Error> + 'static, { owner_swap::swap_process( @@ -2630,6 +2632,7 @@ where eth_infura_project_id, false, ) + .map_err(|e| e.into()) } /// Process swap income message @@ -2639,6 +2642,7 @@ where message: String, ) -> Result, Error> { owner_swap::swap_income_message(self.wallet_inst.clone(), keychain_mask, &message, None) + .map_err(|e| e.into()) } // decryipt income slate. It is the common routine for most API calls that accept the slates @@ -2652,11 +2656,11 @@ where let (slate_from, content, sender, _receiver) = self .decrypt_slatepack(keychain_mask, in_slate, None) .map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to decrypt a slatepack, {}", e)) + Error::SlatepackDecodeError(format!("Unable to decrypt a slatepack, {}", e)) })?; (slate_from, Some(content), sender) } else { - let slate_from = in_slate.into_slate_plain(false).map_err(|e| e.kind())?; + let slate_from = in_slate.into_slate_plain(false)?; (slate_from, None, None) }; Ok((slate_from, content, sender)) diff --git a/api/src/owner_rpc_v2.rs b/api/src/owner_rpc_v2.rs index 4d18cc70e..193fe0845 100644 --- a/api/src/owner_rpc_v2.rs +++ b/api/src/owner_rpc_v2.rs @@ -21,7 +21,7 @@ use crate::core::core::Transaction; use crate::keychain::{Identifier, Keychain}; use crate::libwallet::slate_versions::v3::TransactionV3; use crate::libwallet::{ - AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, + AcctPathMapping, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, OutputCommitMapping, PaymentProof, Slate, SlatePurpose, SlateVersion, StatusMessage, TxLogEntry, VersionedSlate, WalletInfo, WalletLCProvider, }; @@ -77,7 +77,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 4, false, false, false, false, true); ``` */ - fn accounts(&self) -> Result, ErrorKind>; + fn accounts(&self) -> Result, Error>; /** Networked version of [Owner::create_account_path](struct.Owner.html#method.create_account_path). @@ -110,7 +110,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn create_account_path(&self, label: &String) -> Result; + fn create_account_path(&self, label: &String) -> Result; /** Networked version of [Owner::set_active_account](struct.Owner.html#method.set_active_account). @@ -142,7 +142,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 4, false, false, false, false, true); ``` */ - fn set_active_account(&self, label: &String) -> Result<(), ErrorKind>; + fn set_active_account(&self, label: &String) -> Result<(), Error>; /** Networked version of [Owner::retrieve_outputs](struct.Owner.html#method.retrieve_outputs). @@ -217,7 +217,7 @@ pub trait OwnerRpcV2: Sync + Send { include_spent: bool, refresh_from_node: bool, tx_id: Option, - ) -> Result<(bool, Vec), ErrorKind>; + ) -> Result<(bool, Vec), Error>; /** Networked version of [Owner::retrieve_txs](struct.Owner.html#method.retrieve_txs). @@ -317,7 +317,7 @@ pub trait OwnerRpcV2: Sync + Send { refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result<(bool, Vec), ErrorKind>; + ) -> Result<(bool, Vec), Error>; /** Networked version of [Owner::retrieve_summary_info](struct.Owner.html#method.retrieve_summary_info). @@ -366,7 +366,7 @@ pub trait OwnerRpcV2: Sync + Send { &self, refresh_from_node: bool, minimum_confirmations: u64, - ) -> Result<(bool, WalletInfo), ErrorKind>; + ) -> Result<(bool, WalletInfo), Error>; // Case with Minimal and full number of arguments. // Minimal test doesn't have funds because defailt numbers of confirmations is 10, so funds are not available yet @@ -718,7 +718,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn init_send_tx(&self, args: InitTxArgs) -> Result; + fn init_send_tx(&self, args: InitTxArgs) -> Result; /** Networked version of [Owner::issue_invoice_tx](struct.Owner.html#method.issue_invoice_tx). @@ -907,7 +907,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result; + fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result; /** Networked version of [Owner::process_invoice_tx](struct.Owner.html#method.process_invoice_tx). @@ -1255,7 +1255,7 @@ pub trait OwnerRpcV2: Sync + Send { &self, slate: VersionedSlate, args: InitTxArgs, - ) -> Result; + ) -> Result; /** Networked version of [Owner::tx_lock_outputs](struct.Owner.html#method.tx_lock_outputs). @@ -1425,11 +1425,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 5 ,true, false, false, false, true); ``` */ - fn tx_lock_outputs( - &self, - slate: VersionedSlate, - participant_id: usize, - ) -> Result<(), ErrorKind>; + fn tx_lock_outputs(&self, slate: VersionedSlate, participant_id: usize) -> Result<(), Error>; /** Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx). @@ -1785,7 +1781,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 5, true, true, false, false, true); ``` */ - fn finalize_tx(&self, slate: VersionedSlate) -> Result; + fn finalize_tx(&self, slate: VersionedSlate) -> Result; /** Networked version of [Owner::post_tx](struct.Owner.html#method.post_tx). @@ -1852,7 +1848,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn post_tx(&self, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind>; + fn post_tx(&self, tx: TransactionV3, fluff: bool) -> Result<(), Error>; /** Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx). @@ -1908,7 +1904,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 5, true, true, false, false, true); ``` */ - fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind>; + fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), Error>; /** Networked version of [Owner::get_stored_tx](struct.Owner.html#method.get_stored_tx). @@ -1978,7 +1974,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 5, true, true, false, false, false); ``` */ - fn get_stored_tx(&self, tx: &TxLogEntryAPI) -> Result, ErrorKind>; + fn get_stored_tx(&self, tx: &TxLogEntryAPI) -> Result, Error>; /** Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages). @@ -2058,7 +2054,7 @@ pub trait OwnerRpcV2: Sync + Send { # ,false, 0 ,false, false, false, false, true); ``` */ - fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind>; + fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), Error>; /** Networked version of [Owner::scan](struct.Owner.html#method.scan). @@ -2090,7 +2086,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 1, false, false, false, false, true); ``` */ - fn scan(&self, start_height: Option, delete_unconfirmed: bool) -> Result<(), ErrorKind>; + fn scan(&self, start_height: Option, delete_unconfirmed: bool) -> Result<(), Error>; /** Networked version of [Owner::node_height](struct.Owner.html#method.node_height). @@ -2123,7 +2119,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 5, false, false, false, false, true); ``` */ - fn node_height(&self) -> Result; + fn node_height(&self) -> Result; /** Networked version of [Owner::start_updated](struct.Owner.html#method.start_updater). @@ -2153,7 +2149,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn start_updater(&self, frequency: u32) -> Result<(), ErrorKind>; + fn start_updater(&self, frequency: u32) -> Result<(), Error>; /** Networked version of [Owner::stop_updater](struct.Owner.html#method.stop_updater). @@ -2180,7 +2176,7 @@ pub trait OwnerRpcV2: Sync + Send { # , false, 0, false, false, false, false, true); ``` */ - 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). @@ -2210,7 +2206,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn get_updater_messages(&self, count: u32) -> Result, ErrorKind>; + fn get_updater_messages(&self, count: u32) -> Result, Error>; /** Networked version of [Owner::get_mqs_address](struct.Owner.html#method.get_mqs_address). @@ -2242,7 +2238,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn get_mqs_address(&self) -> Result; + fn get_mqs_address(&self) -> Result; /** Networked version of [Owner::get_wallet_public_address](struct.Owner.html#method.get_wallet_public_address). @@ -2274,7 +2270,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn get_wallet_public_address(&self) -> Result; + fn get_wallet_public_address(&self) -> Result; /** Networked version of [Owner::retrieve_payment_proof](struct.Owner.html#method.retrieve_payment_proof). @@ -2368,7 +2364,7 @@ pub trait OwnerRpcV2: Sync + Send { refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result; + ) -> Result; /** Networked version of [Owner::verify_payment_proof](struct.Owner.html#method.verify_payment_proof). @@ -2458,7 +2454,7 @@ pub trait OwnerRpcV2: Sync + Send { ``` */ - fn verify_payment_proof(&self, proof: PaymentProof) -> Result<(bool, bool), ErrorKind>; + fn verify_payment_proof(&self, proof: PaymentProof) -> Result<(bool, bool), Error>; /** Networked version of [Owner::encode_slatepack_message](struct.Owner.html#method.encode_slatepack_message). @@ -2628,7 +2624,7 @@ pub trait OwnerRpcV2: Sync + Send { content: SlatePurpose, recipient: Option, address_index: Option, - ) -> Result; + ) -> Result; /** Networked version of [Owner::decode_slatepack_message](struct.Owner.html#method.decode_slatepack_message). @@ -2803,7 +2799,7 @@ pub trait OwnerRpcV2: Sync + Send { &self, message: String, address_index: Option, - ) -> Result; + ) -> Result; } impl<'a, L, C, K> OwnerRpcV2 for Owner @@ -2812,16 +2808,16 @@ where C: NodeClient + 'static, K: Keychain + 'static, { - fn accounts(&self) -> Result, ErrorKind> { - Owner::accounts(self, None).map_err(|e| e.kind()) + fn accounts(&self) -> Result, Error> { + Owner::accounts(self, None) } - fn create_account_path(&self, label: &String) -> Result { - Owner::create_account_path(self, None, label).map_err(|e| e.kind()) + fn create_account_path(&self, label: &String) -> Result { + Owner::create_account_path(self, None, label) } - fn set_active_account(&self, label: &String) -> Result<(), ErrorKind> { - Owner::set_active_account(self, None, label).map_err(|e| e.kind()) + fn set_active_account(&self, label: &String) -> Result<(), Error> { + Owner::set_active_account(self, None, label) } fn retrieve_outputs( @@ -2829,9 +2825,8 @@ where include_spent: bool, refresh_from_node: bool, tx_id: Option, - ) -> Result<(bool, Vec), ErrorKind> { + ) -> Result<(bool, Vec), Error> { Owner::retrieve_outputs(self, None, include_spent, refresh_from_node, tx_id) - .map_err(|e| e.kind()) } fn retrieve_txs( @@ -2839,30 +2834,27 @@ where refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result<(bool, Vec), ErrorKind> { - Owner::retrieve_txs(self, None, refresh_from_node, tx_id, tx_slate_id) - .map_err(|e| e.kind()) - .map(|(b, tx)| { - ( - b, - tx.iter() - .map(|t| TxLogEntryAPI::from_txlogemtry(t)) - .collect(), - ) - }) + ) -> Result<(bool, Vec), Error> { + Owner::retrieve_txs(self, None, refresh_from_node, tx_id, tx_slate_id).map(|(b, tx)| { + ( + b, + tx.iter() + .map(|t| TxLogEntryAPI::from_txlogemtry(t)) + .collect(), + ) + }) } fn retrieve_summary_info( &self, refresh_from_node: bool, minimum_confirmations: u64, - ) -> Result<(bool, WalletInfo), ErrorKind> { + ) -> Result<(bool, WalletInfo), Error> { Owner::retrieve_summary_info(self, None, refresh_from_node, minimum_confirmations) - .map_err(|e| e.kind()) } - fn init_send_tx(&self, args: InitTxArgs) -> Result { - let slate = Owner::init_send_tx(self, None, &args, 1).map_err(|e| e.kind())?; + fn init_send_tx(&self, args: InitTxArgs) -> Result { + let slate = Owner::init_send_tx(self, None, &args, 1)?; // Return plain slate. If caller don't want sent slate with this API, than probvably caller want // handle the workflow in lower level. @@ -2870,11 +2862,11 @@ where // better to have plain slate so it can be readable. let version = slate.lowest_version(); Ok(VersionedSlate::into_version_plain(slate, version) - .map_err(|e| ErrorKind::SlatepackEncodeError(format!("{}", e)))?) + .map_err(|e| Error::SlatepackEncodeError(format!("{}", e)))?) } - fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result { - let slate = Owner::issue_invoice_tx(self, None, &args).map_err(|e| e.kind())?; + fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result { + let slate = Owner::issue_invoice_tx(self, None, &args)?; let vslate = Owner::encrypt_slate( &self, @@ -2888,8 +2880,7 @@ where .map(|a| a.unwrap()), None, self.doctest_mode, - ) - .map_err(|e| e.kind())?; + )?; Ok(vslate) } @@ -2898,22 +2889,21 @@ where &self, in_slate: VersionedSlate, args: InitTxArgs, - ) -> Result { + ) -> Result { let version = in_slate.version(); let (slate_from, content, sender) = Owner::decrypt_versioned_slate(self, None, in_slate) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; if let Some(content) = &content { if *content != SlatePurpose::InvoiceInitial { - return Err(ErrorKind::SlatepackDecodeError(format!( + return Err(Error::SlatepackDecodeError(format!( "Expecting InvoiceInitial slate content, get {:?}", content ))); } } - let out_slate = - Owner::process_invoice_tx(self, None, &slate_from, &args).map_err(|e| e.kind())?; + let out_slate = Owner::process_invoice_tx(self, None, &slate_from, &args)?; let vslate = Owner::encrypt_slate( &self, @@ -2924,20 +2914,19 @@ where sender, None, self.doctest_mode, - ) - .map_err(|e| e.kind())?; + )?; Ok(vslate) } - fn finalize_tx(&self, in_slate: VersionedSlate) -> Result { + fn finalize_tx(&self, in_slate: VersionedSlate) -> Result { let version = in_slate.version(); let (slate_from, _content, sender) = Owner::decrypt_versioned_slate(self, None, in_slate) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; // Not checking content. If slate good enough to finalize, there is not problem with a content - let out_slate = Owner::finalize_tx(self, None, &slate_from).map_err(|e| e.kind())?; + let out_slate = Owner::finalize_tx(self, None, &slate_from)?; let vslate = Owner::encrypt_slate( &self, @@ -2950,27 +2939,23 @@ where self.doctest_mode, ) .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) + Error::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) })?; Ok(vslate) } - fn tx_lock_outputs( - &self, - slate: VersionedSlate, - participant_id: usize, - ) -> Result<(), ErrorKind> { + fn tx_lock_outputs(&self, slate: VersionedSlate, participant_id: usize) -> Result<(), Error> { let (slate_from, _content, _sender) = Owner::decrypt_versioned_slate(self, None, slate) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; - Owner::tx_lock_outputs(self, None, &slate_from, None, participant_id).map_err(|e| e.kind()) + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; + Owner::tx_lock_outputs(self, None, &slate_from, None, participant_id) } - fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind> { - Owner::cancel_tx(self, None, tx_id, tx_slate_id).map_err(|e| e.kind()) + fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), Error> { + Owner::cancel_tx(self, None, tx_id, tx_slate_id) } - fn get_stored_tx(&self, tx: &TxLogEntryAPI) -> Result, ErrorKind> { + fn get_stored_tx(&self, tx: &TxLogEntryAPI) -> Result, Error> { Owner::get_stored_tx( self, None, @@ -3011,64 +2996,61 @@ where ), ) .map(|x| x.map(TransactionV3::from)) - .map_err(|e| e.kind()) } - fn post_tx(&self, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind> { + fn post_tx(&self, tx: TransactionV3, fluff: bool) -> Result<(), Error> { Owner::post_tx( self, None, &Transaction::try_from(tx).map_err(|e| { - ErrorKind::GenericError(format!("Unable convert V3 transaction, {}", e)) + Error::GenericError(format!("Unable convert V3 transaction, {}", e)) })?, fluff, ) - .map_err(|e| e.kind()) } - fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind> { + fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), Error> { if slate.is_slatepack() { - return Err(ErrorKind::SlatepackDecodeError( + return Err(Error::SlatepackDecodeError( "verify_slate_messages is not applicable for slatepack".to_string(), )); } let slate = slate .into_slate_plain(true) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; - Owner::verify_slate_messages(self, None, &slate).map_err(|e| e.kind()) + Owner::verify_slate_messages(self, None, &slate) } - fn scan(&self, start_height: Option, delete_unconfirmed: bool) -> Result<(), ErrorKind> { - Owner::scan(self, None, start_height, delete_unconfirmed).map_err(|e| e.kind()) + fn scan(&self, start_height: Option, delete_unconfirmed: bool) -> Result<(), Error> { + Owner::scan(self, None, start_height, delete_unconfirmed) } - fn node_height(&self) -> Result { - Owner::node_height(self, None).map_err(|e| e.kind()) + fn node_height(&self) -> Result { + Owner::node_height(self, None) } - fn start_updater(&self, frequency: u32) -> Result<(), ErrorKind> { + fn start_updater(&self, frequency: u32) -> Result<(), Error> { Owner::start_updater(self, None, 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, ErrorKind> { - Owner::get_updater_messages(self, count as usize).map_err(|e| e.kind()) + fn get_updater_messages(&self, count: u32) -> Result, Error> { + Owner::get_updater_messages(self, count as usize) } - fn get_mqs_address(&self) -> Result { - let address = Owner::get_mqs_address(self, None).map_err(|e| e.kind())?; + fn get_mqs_address(&self) -> Result { + let address = Owner::get_mqs_address(self, None)?; let public_proof_address = ProvableAddress::from_pub_key(&address); println!("mqs_address address {}", public_proof_address.public_key); Ok(public_proof_address) } - fn get_wallet_public_address(&self) -> Result { - let address = Owner::get_wallet_public_address(self, None).map_err(|e| e.kind())?; + fn get_wallet_public_address(&self) -> Result { + let address = Owner::get_wallet_public_address(self, None)?; let address = ProvableAddress::from_tor_pub_key(&address); println!("wallet_public_address address {}", address.public_key); Ok(address) @@ -3079,13 +3061,12 @@ where refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result { + ) -> Result { Owner::retrieve_payment_proof(self, None, refresh_from_node, tx_id, tx_slate_id) - .map_err(|e| e.kind()) } - fn verify_payment_proof(&self, proof: PaymentProof) -> Result<(bool, bool), ErrorKind> { - Owner::verify_payment_proof(self, None, &proof).map_err(|e| e.kind()) + fn verify_payment_proof(&self, proof: PaymentProof) -> Result<(bool, bool), Error> { + Owner::verify_payment_proof(self, None, &proof) } fn encode_slatepack_message( @@ -3094,15 +3075,15 @@ where content: SlatePurpose, recipient: Option, address_index: Option, - ) -> Result { + ) -> Result { // Expected Slate in Json (plain) format let slate = slate.into_slate_plain(false).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Expected to get slate in Json format, {}", e)) + Error::SlatepackDecodeError(format!("Expected to get slate in Json format, {}", e)) })?; let recipient: Option = match recipient { Some(recipient) => Some(recipient.tor_public_key().map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Expecting recipient tor address, {}", e)) + Error::SlatepackEncodeError(format!("Expecting recipient tor address, {}", e)) })?), None => None, }; @@ -3116,13 +3097,12 @@ where recipient, address_index, self.doctest_mode, - ) - .map_err(|e| e.kind())?; + )?; if let VersionedSlate::SP(message) = vslate { return Ok(message); } else { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Unable to encode the slate, internal error".to_string(), )); } @@ -3132,16 +3112,14 @@ where &self, message: String, address_index: Option, - ) -> Result { + ) -> Result { let (slate, content, sender, recipient) = - Owner::decrypt_slatepack(&self, None, VersionedSlate::SP(message), address_index) - .map_err(|e| e.kind())?; + Owner::decrypt_slatepack(&self, None, VersionedSlate::SP(message), address_index)?; let slate_version = slate.lowest_version(); - let vslate = VersionedSlate::into_version_plain(slate, slate_version).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to convert slate, {}", e)) - })?; + let vslate = VersionedSlate::into_version_plain(slate, slate_version) + .map_err(|e| Error::SlatepackDecodeError(format!("Unable to convert slate, {}", e)))?; Ok(SlatepackInfo { slate: vslate, diff --git a/api/src/owner_rpc_v3.rs b/api/src/owner_rpc_v3.rs index 35d80ee41..ab209a6e2 100644 --- a/api/src/owner_rpc_v3.rs +++ b/api/src/owner_rpc_v3.rs @@ -22,7 +22,7 @@ use crate::core::global; use crate::keychain::{Identifier, Keychain}; use crate::libwallet::slate_versions::v3::TransactionV3; use crate::libwallet::{ - AcctPathMapping, Amount, BuiltOutput, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, + AcctPathMapping, Amount, BuiltOutput, Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, OutputCommitMapping, PaymentProof, Slate, SlatePurpose, SlateVersion, StatusMessage, TxLogEntry, VersionedSlate, ViewWallet, WalletInfo, WalletLCProvider, }; @@ -38,7 +38,6 @@ use ed25519_dalek::PublicKey as DalekPublicKey; use grin_wallet_libwallet::proof::proofaddress::ProvableAddress; use rand::thread_rng; use std::convert::TryFrom; -use std::error::Error; use std::time::Duration; /// Public definition used to generate Owner jsonrpc api. @@ -83,7 +82,7 @@ pub trait OwnerRpcV3 { # , true, 4, false, false, false, false, true); ``` */ - fn accounts(&self, token: Token) -> Result, ErrorKind>; + fn accounts(&self, token: Token) -> Result, Error>; /** Networked version of [Owner::create_account_path](struct.Owner.html#method.create_account_path). @@ -116,7 +115,7 @@ pub trait OwnerRpcV3 { # ,true, 4, false, false, false, false, true); ``` */ - fn create_account_path(&self, token: Token, label: &String) -> Result; + fn create_account_path(&self, token: Token, label: &String) -> Result; /** Networked version of [Owner::set_active_account](struct.Owner.html#method.set_active_account). @@ -149,7 +148,7 @@ pub trait OwnerRpcV3 { # , true, 4, false, false, false, false, true); ``` */ - 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). @@ -226,7 +225,7 @@ pub trait OwnerRpcV3 { include_spent: bool, refresh_from_node: bool, tx_id: Option, - ) -> Result<(bool, Vec), ErrorKind>; + ) -> Result<(bool, Vec), Error>; /** Networked version of [Owner::retrieve_txs](struct.Owner.html#method.retrieve_txs). @@ -330,7 +329,7 @@ pub trait OwnerRpcV3 { refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result<(bool, Vec), ErrorKind>; + ) -> Result<(bool, Vec), Error>; /** Networked version of [Owner::retrieve_summary_info](struct.Owner.html#method.retrieve_summary_info). @@ -381,7 +380,7 @@ pub trait OwnerRpcV3 { 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). @@ -733,7 +732,7 @@ pub trait OwnerRpcV3 { ``` */ - fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result; + fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result; /** Networked version of [Owner::issue_invoice_tx](struct.Owner.html#method.issue_invoice_tx). @@ -929,7 +928,7 @@ pub trait OwnerRpcV3 { &self, token: Token, args: IssueInvoiceTxArgs, - ) -> Result; + ) -> Result; /** Networked version of [Owner::get_rewind_hash](struct.Owner.html#method.get_rewind_hash). @@ -958,7 +957,7 @@ pub trait OwnerRpcV3 { # ,true, 0, false, false, false, false, false); ``` */ - fn get_rewind_hash(&self, token: Token) -> Result; + fn get_rewind_hash(&self, token: Token) -> Result; /** Networked version of [Owner::scan_rewind_hash](struct.Owner.html#method.scan_rewind_hash). @@ -1038,7 +1037,7 @@ pub trait OwnerRpcV3 { &self, rewind_hash: String, start_height: Option, - ) -> Result; + ) -> Result; /** Networked version of [Owner::process_invoice_tx](struct.Owner.html#method.process_invoice_tx). @@ -1390,7 +1389,7 @@ pub trait OwnerRpcV3 { token: Token, slate: VersionedSlate, args: InitTxArgs, - ) -> Result; + ) -> Result; /** Networked version of [Owner::tx_lock_outputs](struct.Owner.html#method.tx_lock_outputs). @@ -1568,7 +1567,7 @@ pub trait OwnerRpcV3 { token: Token, slate: VersionedSlate, participant_id: usize, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /** Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx). @@ -1927,8 +1926,7 @@ pub trait OwnerRpcV3 { # , true, 5, true, true, false, false, true); ``` */ - fn finalize_tx(&self, token: Token, slate: VersionedSlate) - -> Result; + fn finalize_tx(&self, token: Token, slate: VersionedSlate) -> Result; /** Networked version of [Owner::post_tx](struct.Owner.html#method.post_tx). @@ -1996,7 +1994,7 @@ pub trait OwnerRpcV3 { ``` */ - fn post_tx(&self, token: Token, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind>; + fn post_tx(&self, token: Token, tx: TransactionV3, fluff: bool) -> Result<(), Error>; /** Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx). @@ -2059,7 +2057,7 @@ pub trait OwnerRpcV3 { token: Token, tx_id: Option, tx_slate_id: Option, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /** Networked version of [Owner::get_stored_tx](struct.Owner.html#method.get_stored_tx). @@ -2133,7 +2131,7 @@ pub trait OwnerRpcV3 { &self, token: Token, tx: &TxLogEntryAPI, - ) -> Result, ErrorKind>; + ) -> Result, Error>; /** Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages). @@ -2215,7 +2213,7 @@ pub trait OwnerRpcV3 { # ,true, 0 ,false, false, false, false, true); ``` */ - fn verify_slate_messages(&self, token: Token, slate: VersionedSlate) -> Result<(), ErrorKind>; + fn verify_slate_messages(&self, token: Token, slate: VersionedSlate) -> Result<(), Error>; /** Networked version of [Owner::scan](struct.Owner.html#method.scan). @@ -2253,7 +2251,7 @@ pub trait OwnerRpcV3 { token: Token, start_height: Option, delete_unconfirmed: bool, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /** Networked version of [Owner::node_height](struct.Owner.html#method.node_height). @@ -2287,7 +2285,7 @@ pub trait OwnerRpcV3 { # , true, 5, false, false, false, false, true); ``` */ - fn node_height(&self, token: Token) -> Result; + fn node_height(&self, token: Token) -> Result; /** Initializes the secure JSON-RPC API. This function must be called and a shared key @@ -2341,7 +2339,7 @@ pub trait OwnerRpcV3 { */ - fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result; + fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result; /** Networked version of [Owner::get_top_level_directory](struct.Owner.html#method.get_top_level_directory). @@ -2371,7 +2369,7 @@ pub trait OwnerRpcV3 { ``` */ - fn get_top_level_directory(&self) -> Result; + fn get_top_level_directory(&self) -> Result; /** Networked version of [Owner::set_top_level_directory](struct.Owner.html#method.set_top_level_directory). @@ -2401,7 +2399,7 @@ pub trait OwnerRpcV3 { ``` */ - 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). @@ -2478,7 +2476,7 @@ pub trait OwnerRpcV3 { logging_config: Option, tor_config: Option, mqs_config: Option, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /** Networked version of [Owner::create_wallet](struct.Owner.html#method.create_wallet). @@ -2517,7 +2515,7 @@ pub trait OwnerRpcV3 { mnemonic: Option, mnemonic_length: u32, password: String, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /** Networked version of [Owner::open_wallet](struct.Owner.html#method.open_wallet). @@ -2548,7 +2546,7 @@ pub trait OwnerRpcV3 { ``` */ - fn open_wallet(&self, name: Option, password: String) -> Result; + fn open_wallet(&self, name: Option, password: String) -> Result; /** Networked version of [Owner::close_wallet](struct.Owner.html#method.close_wallet). @@ -2578,7 +2576,7 @@ pub trait OwnerRpcV3 { ``` */ - fn close_wallet(&self, name: Option) -> Result<(), ErrorKind>; + fn close_wallet(&self, name: Option) -> Result<(), Error>; /** Networked version of [Owner::get_mnemonic](struct.Owner.html#method.get_mnemonic). @@ -2609,7 +2607,7 @@ pub trait OwnerRpcV3 { ``` */ - fn get_mnemonic(&self, name: Option, password: String) -> Result; + fn get_mnemonic(&self, name: Option, password: String) -> Result; /** Networked version of [Owner::change_password](struct.Owner.html#method.change_password). @@ -2640,12 +2638,7 @@ pub trait OwnerRpcV3 { # , true, 0, false, false, false, false, true); ``` */ - fn change_password( - &self, - name: Option, - old: String, - new: String, - ) -> Result<(), ErrorKind>; + fn change_password(&self, name: Option, old: String, new: String) -> Result<(), Error>; /** Networked version of [Owner::delete_wallet](struct.Owner.html#method.delete_wallet). @@ -2674,7 +2667,7 @@ pub trait OwnerRpcV3 { # , true, 0, false, false, false, false, true); ``` */ - fn delete_wallet(&self, name: Option) -> Result<(), ErrorKind>; + fn delete_wallet(&self, name: Option) -> Result<(), Error>; /** Networked version of [Owner::start_updated](struct.Owner.html#method.start_updater). @@ -2705,7 +2698,7 @@ pub trait OwnerRpcV3 { ``` */ - 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). @@ -2732,7 +2725,7 @@ pub trait OwnerRpcV3 { # , true, 0, false, false, false, false, true); ``` */ - 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). @@ -2762,7 +2755,7 @@ pub trait OwnerRpcV3 { ``` */ - fn get_updater_messages(&self, count: u32) -> Result, ErrorKind>; + fn get_updater_messages(&self, count: u32) -> Result, Error>; /** Networked version of [Owner::get_mqs_address](struct.Owner.html#method.get_mqs_address). @@ -2796,7 +2789,7 @@ pub trait OwnerRpcV3 { ``` */ - fn get_mqs_address(&self, token: Token) -> Result; + fn get_mqs_address(&self, token: Token) -> Result; /** Networked version of [Owner::get_wallet_public_address](struct.Owner.html#method.get_wallet_public_address). @@ -2830,7 +2823,7 @@ pub trait OwnerRpcV3 { ``` */ - fn get_wallet_public_address(&self, token: Token) -> Result; + fn get_wallet_public_address(&self, token: Token) -> Result; /** Networked version of [Owner::retrieve_payment_proof](struct.Owner.html#method.retrieve_payment_proof). @@ -2927,7 +2920,7 @@ pub trait OwnerRpcV3 { refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result; + ) -> Result; /** Networked version of [Owner::verify_payment_proof](struct.Owner.html#method.verify_payment_proof). @@ -3024,7 +3017,7 @@ pub trait OwnerRpcV3 { &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). @@ -3058,7 +3051,7 @@ pub trait OwnerRpcV3 { # , true, 0, false, false, false, false, true); ``` */ - fn set_tor_config(&self, tor_config: Option) -> Result<(), ErrorKind>; + fn set_tor_config(&self, tor_config: Option) -> Result<(), Error>; /** Networked version of [Owner::build_output](struct.Owner.html#method.build_output). @@ -3102,7 +3095,7 @@ pub trait OwnerRpcV3 { token: Token, features: OutputFeatures, amount: Amount, - ) -> Result; + ) -> Result; /** Networked version of [Owner::encode_slatepack_message](struct.Owner.html#method.encode_slatepack_message). @@ -3274,7 +3267,7 @@ pub trait OwnerRpcV3 { content: SlatePurpose, recipient: Option, address_index: Option, - ) -> Result; + ) -> Result; /** Networked version of [Owner::decode_slatepack_message](struct.Owner.html#method.decode_slatepack_message). @@ -3452,7 +3445,7 @@ pub trait OwnerRpcV3 { token: Token, message: String, address_index: Option, - ) -> Result; + ) -> Result; } impl OwnerRpcV3 for Owner @@ -3461,18 +3454,16 @@ where C: NodeClient + 'static, K: Keychain + 'static, { - fn accounts(&self, token: Token) -> Result, ErrorKind> { - Owner::accounts(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind()) + fn accounts(&self, token: Token) -> Result, Error> { + Owner::accounts(self, (&token.keychain_mask).as_ref()) } - fn create_account_path(&self, token: Token, label: &String) -> Result { + fn create_account_path(&self, token: Token, label: &String) -> Result { 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( @@ -3481,7 +3472,7 @@ where include_spent: bool, refresh_from_node: bool, tx_id: Option, - ) -> Result<(bool, Vec), ErrorKind> { + ) -> Result<(bool, Vec), Error> { Owner::retrieve_outputs( self, (&token.keychain_mask).as_ref(), @@ -3489,7 +3480,6 @@ where refresh_from_node, tx_id, ) - .map_err(|e| e.kind()) } fn retrieve_txs( @@ -3498,7 +3488,7 @@ where refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result<(bool, Vec), ErrorKind> { + ) -> Result<(bool, Vec), Error> { Owner::retrieve_txs( self, (&token.keychain_mask).as_ref(), @@ -3506,7 +3496,6 @@ where tx_id, tx_slate_id, ) - .map_err(|e| e.kind()) .map(|(b, tx)| { ( b, @@ -3522,35 +3511,32 @@ 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 { - let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), &args, 1) - .map_err(|e| e.kind())?; + fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result { + let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), &args, 1)?; // Return plain slate. If caller don't want sent slate with this API, than probvably caller want // handle the workflow in lower level. // If caller did send with thius API - then the slate is just for logging. For logging it is // better to have plain slate so it can be readable. let version = slate.lowest_version(); Ok(VersionedSlate::into_version_plain(slate, version) - .map_err(|e| ErrorKind::SlatepackEncodeError(format!("{}", e)))?) + .map_err(|e| Error::SlatepackEncodeError(format!("{}", e)))?) } fn issue_invoice_tx( &self, token: Token, args: IssueInvoiceTxArgs, - ) -> Result { - let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), &args) - .map_err(|e| e.kind())?; + ) -> Result { + let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), &args)?; // Invoice slate respond does a slatepack encoding if recipient is defined. @@ -3568,7 +3554,7 @@ where self.doctest_mode, ) .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) + Error::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) })?; Ok(res_slate) } @@ -3578,15 +3564,15 @@ where token: Token, in_slate: VersionedSlate, args: InitTxArgs, - ) -> Result { + ) -> Result { let version = in_slate.version(); let (slate_from, content, sender) = Owner::decrypt_versioned_slate(self, (&token.keychain_mask).as_ref(), in_slate) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; if let Some(content) = &content { if *content != SlatePurpose::InvoiceInitial { - return Err(ErrorKind::SlatepackDecodeError(format!( + return Err(Error::SlatepackDecodeError(format!( "Expecting InvoiceInitial slate content, get {:?}", content ))); @@ -3594,8 +3580,7 @@ where } let out_slate = - Owner::process_invoice_tx(self, (&token.keychain_mask).as_ref(), &slate_from, &args) - .map_err(|e| e.kind())?; + Owner::process_invoice_tx(self, (&token.keychain_mask).as_ref(), &slate_from, &args)?; let res_slate = Owner::encrypt_slate( self, @@ -3608,23 +3593,18 @@ where self.doctest_mode, ) .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) + Error::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) })?; Ok(res_slate) } - fn finalize_tx( - &self, - token: Token, - in_slate: VersionedSlate, - ) -> Result { + fn finalize_tx(&self, token: Token, in_slate: VersionedSlate) -> Result { let version = in_slate.version(); let (slate_from, _content, sender) = Owner::decrypt_versioned_slate(self, (&token.keychain_mask).as_ref(), in_slate) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; - let out_slate = Owner::finalize_tx(self, (&token.keychain_mask).as_ref(), &slate_from) - .map_err(|e| e.kind())?; + let out_slate = Owner::finalize_tx(self, (&token.keychain_mask).as_ref(), &slate_from)?; let res_slate = Owner::encrypt_slate( self, @@ -3637,7 +3617,7 @@ where self.doctest_mode, ) .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) + Error::SlatepackEncodeError(format!("Unable to encode the slatepack, {}", e)) })?; Ok(res_slate) } @@ -3647,10 +3627,10 @@ where token: Token, in_slate: VersionedSlate, participant_id: usize, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let (slate_from, _content, _sender) = Owner::decrypt_versioned_slate(self, (&token.keychain_mask).as_ref(), in_slate) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; Owner::tx_lock_outputs( self, @@ -3659,7 +3639,6 @@ where None, // RPC doesn't support address participant_id, ) - .map_err(|e| e.kind()) } fn cancel_tx( @@ -3667,16 +3646,15 @@ where token: Token, tx_id: Option, tx_slate_id: Option, - ) -> 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( &self, token: Token, tx: &TxLogEntryAPI, - ) -> Result, ErrorKind> { + ) -> Result, Error> { Owner::get_stored_tx( self, (&token.keychain_mask).as_ref(), @@ -3717,45 +3695,42 @@ where ), ) .map(|x| x.map(TransactionV3::from)) - .map_err(|e| e.kind()) } - fn post_tx(&self, token: Token, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind> { + fn post_tx(&self, token: Token, tx: TransactionV3, fluff: bool) -> Result<(), Error> { Owner::post_tx( self, (&token.keychain_mask).as_ref(), &Transaction::try_from(tx).map_err(|e| { - ErrorKind::GenericError(format!("Unable convert V3 transaction, {}", e)) + Error::GenericError(format!("Unable convert V3 transaction, {}", e)) })?, fluff, ) - .map_err(|e| e.kind()) } - fn verify_slate_messages(&self, token: Token, slate: VersionedSlate) -> Result<(), ErrorKind> { + fn verify_slate_messages(&self, token: Token, slate: VersionedSlate) -> Result<(), Error> { if slate.is_slatepack() { - return Err(ErrorKind::SlatepackDecodeError( + return Err(Error::SlatepackDecodeError( "verify_slate_messages is not applicable for slatepack".to_string(), )); } let slate = slate .into_slate_plain(true) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("{}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("{}", e)))?; Owner::verify_slate_messages(self, (&token.keychain_mask).as_ref(), &Slate::from(slate)) - .map_err(|e| e.kind()) } - fn get_rewind_hash(&self, token: Token) -> Result { - Owner::get_rewind_hash(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind()) + fn get_rewind_hash(&self, token: Token) -> Result { + Owner::get_rewind_hash(self, (&token.keychain_mask).as_ref()) } fn scan_rewind_hash( &self, rewind_hash: String, start_height: Option, - ) -> Result { - Owner::scan_rewind_hash(self, rewind_hash, start_height).map_err(|e| e.kind()) + ) -> Result { + Owner::scan_rewind_hash(self, rewind_hash, start_height) } fn scan( @@ -3763,24 +3738,23 @@ where token: Token, start_height: Option, 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 { - Owner::node_height(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind()) + fn node_height(&self, token: Token) -> Result { + Owner::node_height(self, (&token.keychain_mask).as_ref()) } // we have to use e.description because of the bug at rust-secp256k1-zkp #[allow(deprecated)] - fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result { + fn init_secure_api(&self, ecdh_pubkey: ECDHPubkey) -> Result { let secp_inst = static_secp_instance(); let secp = secp_inst.lock(); let sec_key = SecretKey::new(&secp, &mut thread_rng()); @@ -3788,18 +3762,18 @@ where let mut shared_pubkey = ecdh_pubkey.ecdh_pubkey; shared_pubkey .mul_assign(&secp, &sec_key) - .map_err(|e| ErrorKind::Secp(format!("{}", e.description())))?; + .map_err(|e| Error::Secp(format!("{}", e)))?; let x_coord = shared_pubkey.serialize_vec(&secp, true); let shared_key = SecretKey::from_slice(&secp, &x_coord[1..]) - .map_err(|e| ErrorKind::Secp(format!("{}", e.description())))?; + .map_err(|e| Error::Secp(format!("{}", e)))?; { let mut s = self.shared_key.lock(); *s = Some(shared_key); } let pub_key = PublicKey::from_secret_key(&secp, &sec_key) - .map_err(|e| ErrorKind::Secp(format!("{}", e.description())))?; + .map_err(|e| Error::Secp(format!("{}", e)))?; Ok(ECDHPubkey { ecdh_pubkey: pub_key, @@ -3808,12 +3782,12 @@ where #[warn(deprecated)] - fn get_top_level_directory(&self) -> Result { - Owner::get_top_level_directory(self).map_err(|e| e.kind()) + fn get_top_level_directory(&self) -> Result { + 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( @@ -3823,7 +3797,7 @@ where logging_config: Option, tor_config: Option, mqs_config: Option, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { Owner::create_config( self, &chain_type, @@ -3832,7 +3806,6 @@ where tor_config, mqs_config, ) - .map_err(|e| e.kind()) } fn create_wallet( @@ -3841,7 +3814,7 @@ where mnemonic: Option, 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)), @@ -3855,36 +3828,28 @@ where ZeroingString::from(password), None, ) - .map_err(|e| e.kind()) } - fn open_wallet(&self, name: Option, password: String) -> Result { + fn open_wallet(&self, name: Option, password: String) -> Result { let n = name.as_ref().map(|s| s.as_str()); - let sec_key = Owner::open_wallet(self, n, ZeroingString::from(password), true, None) - .map_err(|e| e.kind())?; + let sec_key = Owner::open_wallet(self, n, ZeroingString::from(password), true, None)?; Ok(Token { keychain_mask: sec_key, }) } - fn close_wallet(&self, name: Option) -> Result<(), ErrorKind> { + fn close_wallet(&self, name: Option) -> 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, password: String) -> Result { + fn get_mnemonic(&self, name: Option, password: String) -> Result { let n = name.as_ref().map(|s| s.as_str()); - let res = Owner::get_mnemonic(self, n, ZeroingString::from(password), None) - .map_err(|e| e.kind())?; + let res = Owner::get_mnemonic(self, n, ZeroingString::from(password), None)?; Ok((&*res).to_string()) } - fn change_password( - &self, - name: Option, - old: String, - new: String, - ) -> Result<(), ErrorKind> { + fn change_password(&self, name: Option, old: String, new: String) -> Result<(), Error> { let n = name.as_ref().map(|s| s.as_str()); Owner::change_password( self, @@ -3893,42 +3858,38 @@ where ZeroingString::from(new), None, ) - .map_err(|e| e.kind()) } - fn delete_wallet(&self, name: Option) -> Result<(), ErrorKind> { + fn delete_wallet(&self, name: Option) -> 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, ErrorKind> { - Owner::get_updater_messages(self, count as usize).map_err(|e| e.kind()) + fn get_updater_messages(&self, count: u32) -> Result, Error> { + Owner::get_updater_messages(self, count as usize) } - fn get_mqs_address(&self, token: Token) -> Result { - let address = - Owner::get_mqs_address(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind())?; + fn get_mqs_address(&self, token: Token) -> Result { + let address = Owner::get_mqs_address(self, (&token.keychain_mask).as_ref())?; let public_proof_address = ProvableAddress::from_pub_key(&address); println!("mqs_address address {}", public_proof_address.public_key); Ok(public_proof_address) } - fn get_wallet_public_address(&self, token: Token) -> Result { - let address = Owner::get_wallet_public_address(self, (&token.keychain_mask).as_ref()) - .map_err(|e| e.kind())?; + fn get_wallet_public_address(&self, token: Token) -> Result { + let address = Owner::get_wallet_public_address(self, (&token.keychain_mask).as_ref())?; let address = ProvableAddress::from_tor_pub_key(&address); println!("wallet_public_address address {}", address.public_key); Ok(address) @@ -3940,7 +3901,7 @@ where refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, - ) -> Result { + ) -> Result { Owner::retrieve_payment_proof( self, (&token.keychain_mask).as_ref(), @@ -3948,19 +3909,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) -> Result<(), ErrorKind> { + fn set_tor_config(&self, tor_config: Option) -> Result<(), Error> { Owner::set_tor_config(self, tor_config); Ok(()) } @@ -3970,9 +3929,8 @@ where token: Token, features: OutputFeatures, amount: Amount, - ) -> Result { + ) -> Result { Owner::build_output(self, (&token.keychain_mask).as_ref(), features, amount.0) - .map_err(|e| e.kind()) } fn encode_slatepack_message( @@ -3982,15 +3940,15 @@ where content: SlatePurpose, recipient: Option, address_index: Option, - ) -> Result { + ) -> Result { // Expected Slate in Json (plain) format let slate = slate.into_slate_plain(false).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Expected to get slate in Json format, {}", e)) + Error::SlatepackDecodeError(format!("Expected to get slate in Json format, {}", e)) })?; let recipient: Option = match recipient { Some(recipient) => Some(recipient.tor_public_key().map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Expecting recipient tor address, {}", e)) + Error::SlatepackEncodeError(format!("Expecting recipient tor address, {}", e)) })?), None => None, }; @@ -4004,13 +3962,12 @@ where recipient, address_index, self.doctest_mode, - ) - .map_err(|e| e.kind())?; + )?; if let VersionedSlate::SP(message) = vslate { return Ok(message); } else { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Unable to encode the slate, internal error".to_string(), )); } @@ -4021,20 +3978,18 @@ where token: Token, message: String, address_index: Option, - ) -> Result { + ) -> Result { let (slate, content, sender, recipient) = Owner::decrypt_slatepack( &self, (&token.keychain_mask).as_ref(), VersionedSlate::SP(message), address_index, - ) - .map_err(|e| e.kind())?; + )?; let slate_version = slate.lowest_version(); - let vslate = VersionedSlate::into_version_plain(slate, slate_version).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to convert slate, {}", e)) - })?; + let vslate = VersionedSlate::into_version_plain(slate, slate_version) + .map_err(|e| Error::SlatepackDecodeError(format!("Unable to convert slate, {}", e)))?; Ok(SlatepackInfo { slate: vslate, diff --git a/api/src/types.rs b/api/src/types.rs index 3b18f95d5..78e4ae293 100644 --- a/api/src/types.rs +++ b/api/src/types.rs @@ -14,7 +14,7 @@ use crate::core::libtx::secp_ser; use crate::keychain::Identifier; use crate::libwallet::dalek_ser; -use crate::libwallet::{Error, ErrorKind}; +use crate::libwallet::Error; use crate::libwallet::{ ParticipantMessages, StoredProofInfo, TxLogEntry, TxLogEntryType, VersionedSlate, }; @@ -86,7 +86,7 @@ impl EncryptedBody { pub fn from_json(json_in: &Value, enc_key: &SecretKey) -> Result { let mut to_encrypt = serde_json::to_string(&json_in) .map_err(|e| { - ErrorKind::APIEncryption(format!("EncryptedBody Enc: Unable to encode JSON, {}", e)) + Error::APIEncryption(format!("EncryptedBody Enc: Unable to encode JSON, {}", e)) })? .as_bytes() .to_vec(); @@ -102,11 +102,10 @@ impl EncryptedBody { &mut to_encrypt, ); if let Err(e) = res { - return Err(ErrorKind::APIEncryption(format!( + return Err(Error::APIEncryption(format!( "EncryptedBody: encryption failed, {}", e - )) - .into()); + ))); } Ok(EncryptedBody { @@ -118,7 +117,7 @@ impl EncryptedBody { /// return serialize JSON self pub fn as_json_value(&self) -> Result { let res = serde_json::to_value(self).map_err(|e| { - ErrorKind::APIEncryption(format!("EncryptedBody: JSON serialization failed, {}", e)) + Error::APIEncryption(format!("EncryptedBody: JSON serialization failed, {}", e)) })?; Ok(res) } @@ -127,7 +126,7 @@ impl EncryptedBody { pub fn as_json_str(&self) -> Result { let res = self.as_json_value()?; let res = serde_json::to_string(&res).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedBody: JSON String serialization failed, {}", e )) @@ -138,24 +137,23 @@ impl EncryptedBody { /// Return original request pub fn decrypt(&self, dec_key: &SecretKey) -> Result { let mut to_decrypt = base64::decode(&self.body_enc).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedBody Dec: Encrypted request contains invalid Base64, {}", e )) })?; let nonce = from_hex(&self.nonce).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedBody Dec: Encrypted request contains invalid nonce, {}", e )) })?; if nonce.len() < 12 { - return Err(ErrorKind::APIEncryption( + return Err(Error::APIEncryption( "EncryptedBody Dec: Invalid Nonce length".to_string(), - ) - .into()); + )); } let mut n = [0u8; 12]; n.copy_from_slice(&nonce[0..12]); @@ -165,20 +163,18 @@ impl EncryptedBody { opening_key .open_in_place(aead::Nonce::assume_unique_for_key(n), aad, &mut to_decrypt) .map_err(|e| { - ErrorKind::APIEncryption(format!("EncryptedBody: decryption failed, {}", e)) + Error::APIEncryption(format!("EncryptedBody: decryption failed, {}", e)) })?; for _ in 0..aead::AES_256_GCM.tag_len() { to_decrypt.pop(); } - let decrypted = String::from_utf8(to_decrypt).map_err(|_| { - ErrorKind::APIEncryption("EncryptedBody Dec: Invalid UTF-8".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(|e| { - ErrorKind::APIEncryption(format!("EncryptedBody Dec: Invalid JSON, {}", e)) - })?) + Ok(serde_json::from_str(&decrypted) + .map_err(|e| Error::APIEncryption(format!("EncryptedBody Dec: Invalid JSON, {}", e)))?) } } @@ -209,7 +205,7 @@ impl EncryptedRequest { /// return serialize JSON self pub fn as_json_value(&self) -> Result { let res = serde_json::to_value(self).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedRequest: JSON serialization failed, {}", e )) @@ -221,7 +217,7 @@ impl EncryptedRequest { pub fn as_json_str(&self) -> Result { let res = self.as_json_value()?; let res = serde_json::to_string(&res).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedRequest: JSON String serialization failed, {}", e )) @@ -264,7 +260,7 @@ impl EncryptedResponse { /// return serialize JSON self pub fn as_json_value(&self) -> Result { let res = serde_json::to_value(self).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedResponse: JSON serialization failed, {}", e )) @@ -276,7 +272,7 @@ impl EncryptedResponse { pub fn as_json_str(&self) -> Result { let res = self.as_json_value()?; let res = serde_json::to_string(&res).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedResponse: JSON String serialization failed, {}", e )) @@ -288,8 +284,8 @@ impl EncryptedResponse { pub fn decrypt(&self, dec_key: &SecretKey) -> Result { self.result .get("Ok") - .ok_or(ErrorKind::GenericError(format!( - "Not found expetced 'OK' value at result" + .ok_or(Error::GenericError(format!( + "Not found expetced 'OK' value at response" )))? .decrypt(dec_key) } @@ -332,7 +328,7 @@ impl EncryptionErrorResponse { /// return serialized JSON self pub fn as_json_value(&self) -> Value { let res = serde_json::to_value(self).map_err(|e| { - ErrorKind::APIEncryption(format!( + Error::APIEncryption(format!( "EncryptedResponse: JSON serialization failed, {}", e )) diff --git a/config/Cargo.toml b/config/Cargo.toml index e05f21d60..c0fd32230 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -12,11 +12,10 @@ edition = "2018" [dependencies] rand = "0.6" serde = "1" -failure = "0.1" -failure_derive = "0.1" dirs = "2.0" toml = "0.5" serde_derive = "1" +thiserror = "1" grin_wallet_util = { path = "../util", version = "5.1.0" } diff --git a/config/src/types.rs b/config/src/types.rs index f9c2899b2..2fa0dfb3f 100644 --- a/config/src/types.rs +++ b/config/src/types.rs @@ -14,7 +14,6 @@ //! Public types for config modules -use failure::Fail; use std::fmt; use std::io; use std::path::PathBuf; @@ -189,36 +188,30 @@ impl WalletConfig { } /// Error type wrapping config errors. -#[derive(Debug, Fail)] +#[derive(Debug, thiserror::Error)] pub enum ConfigError { /// Error with parsing of config file (file_name, message) - #[fail(display = "Error parsing configuration file at {}, {}", _0, _1)] + #[error("Error parsing configuration file at {0}, {1}")] ParseError(String, String), /// Error with fileIO while reading config file /// (file_name, message) - #[fail(display = "Config IO error, {}", _0)] - FileIOError(String), + #[error("Config IO error, {0}")] + FileIOError(#[from] io::Error), /// No file found (file_name) - #[fail(display = "Configuration file not found: {}", _0)] + #[error("Configuration file not found: {0}")] FileNotFoundError(String), /// Error serializing config values - #[fail(display = "Error serializing configuration, {}", _0)] + #[error("Error serializing configuration, {0}")] SerializationError(String), /// Path doesn't exist - #[fail(display = "Not found expected path {}", _0)] + #[error("Not found expected path {0}")] PathNotFoundError(String), } -impl From for ConfigError { - fn from(error: io::Error) -> ConfigError { - ConfigError::FileIOError(format!("Error loading config file, {}", error)) - } -} - /// Tor configuration #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct TorConfig { diff --git a/controller/Cargo.toml b/controller/Cargo.toml index e85857085..b43fff035 100644 --- a/controller/Cargo.toml +++ b/controller/Cargo.toml @@ -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.4" +thiserror = "1" qr_code = "1.1.0" colored = "1.6" x25519-dalek = "0.6" diff --git a/controller/src/command.rs b/controller/src/command.rs index c0dfffb89..22525514a 100644 --- a/controller/src/command.rs +++ b/controller/src/command.rs @@ -18,7 +18,7 @@ use crate::api::TLSConfig; use crate::apiwallet::Owner; use crate::config::{MQSConfig, TorConfig, WalletConfig, WALLET_CONFIG_FILE_NAME}; use crate::core::{core, global}; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::impls::{create_sender, SlateGetter as _}; use crate::impls::{PathToSlateGetter, PathToSlatePutter, SlatePutter}; use crate::keychain; @@ -213,7 +213,6 @@ where } Err(e) => { error!("View wallet check failed: {}", e); - error!("Backtrace: {}", e.backtrace().unwrap()); Err(e.into()) } } @@ -271,7 +270,7 @@ where let r = t.join(); if let Err(_) = r { error!("Error starting http listener"); - return Err(ErrorKind::ListenerError.into()); + return Err(Error::ListenerError); } } } @@ -287,13 +286,14 @@ where ) .map_err(|e| { error!("Unable to start mwcmqs listener, {}", e); - Error::from(ErrorKind::ListenerError) + Error::from(Error::ListenerError) })?; } method => { - return Err( - ErrorKind::ArgumentError(format!("No listener for method '{}'", method)).into(), - ); + return Err(Error::ArgumentError(format!( + "No listener for method '{}'", + method + ))); } }; Ok(()) @@ -337,7 +337,7 @@ where config.owner_api_include_foreign, Some(tor_config.clone()), ) - .map_err(|e| ErrorKind::LibWallet(format!("Unable to start Listener, {}", e)))?; + .map_err(|e| Error::LibWallet(format!("Unable to start Listener, {}", e)))?; Ok(()) } @@ -367,7 +367,7 @@ where if let Err(e) = res { let err_str = format!("Error listing accounts: {}", e); error!("{}", err_str); - return Err(ErrorKind::LibWallet(err_str).into()); + return Err(Error::LibWallet(err_str)); } } else { let label = args.create.unwrap(); @@ -381,7 +381,7 @@ where thread::sleep(Duration::from_millis(200)); let err_str = format!("Error creating account '{}': {}", label, e); error!("{}", err_str); - return Err(ErrorKind::LibWallet(err_str).into()); + return Err(Error::LibWallet(err_str)); } } Ok(()) @@ -501,7 +501,7 @@ where mqs_config_unwrapped = s; } None => { - return Err(ErrorKind::MQSConfig(format!("NO MQS config!")).into()); + return Err(Error::MQSConfig(format!("NO MQS config!"))); } } @@ -551,11 +551,10 @@ where } Err(e) => { info!("Tx not created: {}", e); - return Err(ErrorKind::LibWallet(format!( + return Err(Error::LibWallet(format!( "Unable to create send slate , {}", e - )) - .into()); + ))); } }; @@ -584,10 +583,9 @@ where "file" | "slatepack" => { let dest: Option = if args.dest.is_empty() { if args.method == "file" { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "Please specify destination for file".to_string(), - ) - .into()); + )); } None } else { @@ -604,7 +602,7 @@ where ) .put_tx(&slate, Some(&slatepack_secret), false, &secp) .map_err(|e| { - ErrorKind::IO(format!("Unable to store the file at {}, {}", args.dest, e)) + Error::IO(format!("Unable to store the file at {}, {}", args.dest, e)) })?; api.tx_lock_outputs(m, &slate, Some(String::from("file")), 0)?; @@ -648,10 +646,9 @@ where } _ => { if sender_info.is_none() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Internal error. Sender not created".to_string(), - ) - .into()); + )); } let (sender, wallet_info) = sender_info.unwrap(); @@ -688,7 +685,7 @@ where } Err(e) => { error!("Tx sent fail: {}", e); - return Err(ErrorKind::LibWallet(format!("Unable to post slate, {}", e)).into()); + return Err(Error::LibWallet(format!("Unable to post slate, {}", e))); } } } @@ -726,19 +723,19 @@ where ); let mut output = File::create(out_file_name.clone()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to create slate backup file {}, {}", out_file_name, e )) })?; output.write_all(&slate_str.as_bytes()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to store slate backup data into file {}, {}", out_file_name, e )) })?; output.sync_all().map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to sync data for file {}, {}", out_file_name, e )) @@ -822,10 +819,9 @@ where &secp, )?, None => { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "Please specify 'file' or 'content' argument".to_string(), - ) - .into()) + )) } }, }; @@ -833,18 +829,18 @@ where let (mut slate, sender, _recipient, content, slatepack_format) = slate_pkg.to_slate()?; if !(content == SlatePurpose::FullSlate || content == SlatePurpose::SendInitial) { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Wrong slate content. Expecting SendInitial, get {:?}", content - )) - .into()); + ))); } if let Err(e) = api.verify_slate_messages(&slate) { error!("Error validating participant messages: {}", e); - return Err( - ErrorKind::LibWallet(format!("Unable to validate slate messages, {}", e)).into(), - ); + return Err(Error::LibWallet(format!( + "Unable to validate slate messages, {}", + e + ))); } slate = api.receive_tx( &slate, @@ -928,10 +924,9 @@ where &secp, )?, None => { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "Please specify 'file' or 'content' argument".to_string(), - ) - .into()) + )) } }, }; @@ -1006,7 +1001,7 @@ where let keychain = w.keychain(m)?; let slatepack_secret = proofaddress::payment_proof_address_secret(&keychain, None)?; let slatepack_secret = DalekSecretKey::from_bytes(&slatepack_secret.0) - .map_err(|e| ErrorKind::GenericError(format!("Unable to build secret, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable to build secret, {}", e)))?; let (height, _, _) = w.w2n_client().get_chain_tip()?; (slatepack_secret, height, keychain.secp().clone()) }; @@ -1024,10 +1019,9 @@ where &secp, )?, None => { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "Please specify 'file' or 'content' argument".to_string(), - ) - .into()) + )) } }, }; @@ -1048,11 +1042,10 @@ where if is_invoice { if !(content == SlatePurpose::FullSlate || content == SlatePurpose::InvoiceResponse) { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Wrong slate content. Expecting InvoiceResponse, get {:?}", content - )) - .into()); + ))); } let km = match keychain_mask.as_ref() { @@ -1062,32 +1055,29 @@ where controller::foreign_single_use(owner_api.wallet_inst.clone(), km, |api| { if let Err(e) = api.verify_slate_messages(&slate) { error!("Error validating participant messages: {}", e); - return Err(ErrorKind::LibWallet(format!( + return Err(Error::LibWallet(format!( "Unable to validate slate messages, {}", e - )) - .into()); + ))); } slate = api.finalize_invoice_tx(&slate)?; Ok(()) })?; } else { if !(content == SlatePurpose::FullSlate || content == SlatePurpose::SendResponse) { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Wrong slate content. Expecting SendResponse, get {:?}", content - )) - .into()); + ))); } controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { if let Err(e) = api.verify_slate_messages(m, &slate) { error!("Error validating participant messages: {}", e); - return Err(ErrorKind::LibWallet(format!( + return Err(Error::LibWallet(format!( "Unable to validate slate messages, {}", e - )) - .into()); + ))); } slate = api.finalize_tx(m, &slate)?; Ok(()) @@ -1106,7 +1096,7 @@ where } Err(e) => { error!("Tx not sent: {}", e); - return Err(ErrorKind::LibWallet(format!("Unable to post slate, {}", e)).into()); + return Err(Error::LibWallet(format!("Unable to post slate, {}", e))); } } })?; @@ -1119,10 +1109,8 @@ where let w = w_lock.lc_provider()?.wallet_inst()?; let keychain = w.keychain(m)?; let slatepack_secret = proofaddress::payment_proof_address_secret(&keychain, None)?; - let slatepack_secret = - DalekSecretKey::from_bytes(&slatepack_secret.0).map_err(|e| { - ErrorKind::GenericError(format!("Unable to build secret, {}", e)) - })?; + let slatepack_secret = DalekSecretKey::from_bytes(&slatepack_secret.0) + .map_err(|e| Error::GenericError(format!("Unable to build secret, {}", e)))?; (slatepack_secret, keychain.secp().clone()) }; @@ -1277,11 +1265,10 @@ where let (slate, sender_pk, _recepient, content, _encrypted) = slate_pkg.to_slate()?; if !(content == SlatePurpose::FullSlate || content == SlatePurpose::InvoiceInitial) { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Wrong slate content. Expecting InvoiceInitial, get {:?}", content - )) - .into()); + ))); } let wallet_inst = owner_api.wallet_inst.clone(); @@ -1318,11 +1305,10 @@ where }; if let Err(e) = api.verify_slate_messages(m, &slate) { error!("Error validating participant messages: {}", e); - return Err(ErrorKind::LibWallet(format!( + return Err(Error::LibWallet(format!( "Unable to validate slate messages, {}", e - )) - .into()); + ))); } let result = api.process_invoice_tx(m, &slate, &init_args); let mut slate = match result { @@ -1337,9 +1323,10 @@ where } Err(e) => { info!("Tx not created: {}", e); - return Err( - ErrorKind::LibWallet(format!("Unable to process invoice, {}", e)).into(), - ); + return Err(Error::LibWallet(format!( + "Unable to process invoice, {}", + e + ))); } }; @@ -1643,16 +1630,16 @@ where } Some(f) => { let mut tx_file = File::create(f.clone()).map_err(|e| { - ErrorKind::IO(format!("Unable to create tx dump file {}, {}", f, e)) + Error::IO(format!("Unable to create tx dump file {}, {}", f, e)) })?; let tx_as_str = json::to_string(&stored_tx).map_err(|e| { - ErrorKind::GenericError(format!("Unable convert Tx to Json, {}", e)) + Error::GenericError(format!("Unable convert Tx to Json, {}", e)) })?; tx_file.write_all(tx_as_str.as_bytes()).map_err(|e| { - ErrorKind::IO(format!("Unable to save tx to the file {}, {}", f, e)) + Error::IO(format!("Unable to save tx to the file {}, {}", f, e)) })?; tx_file.sync_all().map_err(|e| { - ErrorKind::IO(format!("Unable to save tx to the file {}, {}", f, e)) + Error::IO(format!("Unable to save tx to the file {}, {}", f, e)) })?; info!("Dumped transaction data for tx {} to {}", args.id, f); return Ok(()); @@ -1688,11 +1675,10 @@ where } Err(e) => { error!("TX Cancellation failed: {}", e); - Err(ErrorKind::LibWallet(format!( + Err(Error::LibWallet(format!( "Unable to cancel Transaction {}, {}", args.tx_id_string, e - )) - .into()) + ))) } } })?; @@ -1734,8 +1720,7 @@ where } Err(e) => { error!("Wallet check failed: {}", e); - error!("Backtrace: {}", e.backtrace().unwrap()); - Err(ErrorKind::LibWallet(format!("Wallet check failed, {}", e)).into()) + Err(Error::LibWallet(format!("Wallet check failed, {}", e))) } } })?; @@ -1793,7 +1778,7 @@ where Ok(p) => { // actually export proof let mut proof_file = File::create(args.output_file.clone()).map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to create file {}, {}", args.output_file, e )) @@ -1801,27 +1786,23 @@ where proof_file .write_all(json::to_string_pretty(&p).unwrap().as_bytes()) .map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to save the proof file {}, {}", args.output_file, e )) })?; proof_file.sync_all().map_err(|e| { - ErrorKind::GenericError(format!( - "Unable to save file {}, {}", - args.output_file, e - )) + Error::GenericError(format!("Unable to save file {}, {}", args.output_file, e)) })?; warn!("Payment proof exported to {}", args.output_file); Ok(()) } Err(e) => { error!("Proof export failed: {}", e); - return Err(ErrorKind::GenericError(format!( + return Err(Error::GenericError(format!( "Unable to retrieve payment proof, {}", e - )) - .into()); + ))); } } })?; @@ -1856,15 +1837,15 @@ where if !path.exists() { let msg = format!("Unable to open payment proof file at {}", args.input_file); error!("{}", msg); - return Err(ErrorKind::LibWallet(msg).into()); + return Err(Error::LibWallet(msg)); } let mut file = File::open(path) - .map_err(|e| ErrorKind::LibWallet(format!("Unable to open proof data, {}", e)))?; + .map_err(|e| Error::LibWallet(format!("Unable to open proof data, {}", e)))?; let mut proof = String::new(); file.read_to_string(&mut proof) - .map_err(|e| ErrorKind::LibWallet(format!("Unable to read proof data, {}", e)))?; + .map_err(|e| Error::LibWallet(format!("Unable to read proof data, {}", e)))?; let tx_pf: TxProof = serde_json::from_str(&proof) - .map_err(|e| ErrorKind::LibWallet(format!("Unable to deserialize proof data, {}", e)))?; + .map_err(|e| Error::LibWallet(format!("Unable to deserialize proof data, {}", e)))?; let secp_inst = static_secp_instance(); let secp = secp_inst.lock(); @@ -1878,7 +1859,7 @@ where } Err(e) => { error!("Unable to verify proof. {}", e); - Err(ErrorKind::LibWallet(format!("Proof not valid: {}", e)).into()) + Err(Error::LibWallet(format!("Proof not valid: {}", e))) } } } @@ -1902,7 +1883,7 @@ where } Err(e) => { error!("Wallet Data dump failed: {}", e); - Err(ErrorKind::LibWallet(format!("Wallet Data dump failed, {}", e)).into()) + Err(Error::LibWallet(format!("Wallet Data dump failed, {}", e))) } } })?; @@ -1922,22 +1903,19 @@ where match args.buyer_communication_method.as_str() { "mwcmqs" => { // Validating destination address - let _ = MWCMQSAddress::from_str(&args.buyer_communication_address).map_err(|e| { - ErrorKind::ArgumentError(format!("Invalid destination address, {}", e)) - })?; + let _ = MWCMQSAddress::from_str(&args.buyer_communication_address) + .map_err(|e| Error::ArgumentError(format!("Invalid destination address, {}", e)))?; } "tor" => { - let _ = validate_tor_address(&args.buyer_communication_address).map_err(|e| { - ErrorKind::ArgumentError(format!("Invalid destination address, {}", e)) - })?; + let _ = validate_tor_address(&args.buyer_communication_address) + .map_err(|e| Error::ArgumentError(format!("Invalid destination address, {}", e)))?; } "file" => (), // not validating the fine name. Files are secondary and testing method. _ => { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Invalid communication method '{}'. Valid methods: mwcmqs, tor, file", args.buyer_communication_method - )) - .into()) + ))) } } @@ -1950,7 +1928,10 @@ where } Err(e) => { error!("Unable to start Swap trade: {}", e); - Err(ErrorKind::LibWallet(format!("Unable to start Swap trade: {}", e)).into()) + Err(Error::LibWallet(format!( + "Unable to start Swap trade: {}", + e + ))) } } })?; @@ -1976,11 +1957,10 @@ where } Err(e) => { error!("Unable to create a Swap trade from message {}: {}", file, e); - Err(ErrorKind::LibWallet(format!( + Err(Error::LibWallet(format!( "Unable to create a Swap trade from message {}: {}", file, e - )) - .into()) + ))) } } })?; @@ -2258,12 +2238,15 @@ where } Err(e) => { error!("Unable to List Swap trades: {}", e); - Err(ErrorKind::LibWallet(format!("Unable to List Swap trades: {}", e)).into()) + Err(Error::LibWallet(format!( + "Unable to List Swap trades: {}", + e + ))) } } } SwapSubcommand::Delete => { - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; let result = owner_swap::swap_delete(wallet_inst, keychain_mask, &swap_id); @@ -2274,43 +2257,42 @@ where } Err(e) => { error!("Unable to delete Swap {}: {}", swap_id, e); - Err( - ErrorKind::LibWallet(format!("Unable to delete Swap {}: {}", swap_id, e)) - .into(), - ) + Err(Error::LibWallet(format!( + "Unable to delete Swap {}: {}", + swap_id, e + ))) } } } SwapSubcommand::Adjust => { - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; // Checking parameters here. We can't do that at libwallet side if let Some(method) = args.method.clone() { - let destination = args.destination.clone().ok_or(ErrorKind::ArgumentError( + let destination = args.destination.clone().ok_or(Error::ArgumentError( "Please specify '--dest' parameter as well".to_string(), ))?; match method.as_str() { "mwcmqs" => { // Validating destination address let _ = MWCMQSAddress::from_str(&destination).map_err(|e| { - ErrorKind::ArgumentError(format!("Invalid destination address, {}", e)) + Error::ArgumentError(format!("Invalid destination address, {}", e)) })?; } "tor" => { // Validating tor address let _ = validate_tor_address(&destination).map_err(|e| { - ErrorKind::ArgumentError(format!("Invalid destination address, {}", e)) + Error::ArgumentError(format!("Invalid destination address, {}", e)) })?; } "file" => (), _ => { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Unknown communication method value '{}'", method - )) - .into()); + ))); } } } @@ -2345,11 +2327,10 @@ where } Err(e) => { error!("Unable to adjust the Swap {}: {}", swap_id, e); - return Err(ErrorKind::LibWallet(format!( + return Err(Error::LibWallet(format!( "Unable to adjust Swap {}: {}", swap_id, e - )) - .into()); + ))); } } } @@ -2361,7 +2342,7 @@ where Ok(()) } SwapSubcommand::Check => { - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; let result = owner_swap::swap_get(wallet_inst.clone(), keychain_mask, &swap_id); @@ -2424,7 +2405,7 @@ where println!("JSON: {}", item.to_string()); return Ok(()); } else { - return Err(Error::from(e)); + return Err(e.into()); } } }; @@ -2533,21 +2514,21 @@ where } Err(e) => { error!("Unable to retrieve Swap {}: {}", swap_id, e); - Err( - ErrorKind::LibWallet(format!("Unable to retrieve Swap {}: {}", swap_id, e)) - .into(), - ) + Err(Error::LibWallet(format!( + "Unable to retrieve Swap {}: {}", + swap_id, e + ))) } } } SwapSubcommand::Process => { - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; if args.method.is_some() || args.destination.is_some() { - return Err(ErrorKind::ArgumentError( - "swap --process doesn't accept 'method' or 'dest' parameters, instead it is using parameters associated with this swap trade.".to_string()).into()); + return Err(Error::ArgumentError( + "swap --process doesn't accept 'method' or 'dest' parameters, instead it is using parameters associated with this swap trade.".to_string())); } // Creating message delivery transport as a closure @@ -2558,7 +2539,10 @@ where let message_sender = move |swap_message: message::Message, method: String, dest: String| - -> Result<(bool, String), crate::libwallet::Error> { + -> Result< + (bool, String), + grin_wallet_libwallet::swap::Error, + > { let destination_str = format!("{} {}", method, dest); let from_address; @@ -2575,7 +2559,7 @@ where true, ) .map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( + grin_wallet_libwallet::swap::Error::MessageSender(format!( "Unable to start mwcmqs listener, {}", e )) @@ -2583,13 +2567,13 @@ where thread::sleep(Duration::from_millis(2000)); } from_address = grin_wallet_impls::adapters::get_mwcmqs_brocker() - .ok_or(crate::libwallet::ErrorKind::SwapError( + .ok_or(grin_wallet_libwallet::swap::Error::MessageSender( "Unable to start mwcmqs listener".to_string(), ))? .0 .get_publisher_address() .map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( + grin_wallet_libwallet::swap::Error::MessageSender(format!( "Unable to get publisher address {}", e )) @@ -2621,7 +2605,7 @@ where thread::sleep(Duration::from_millis(2000)); } from_address = tor::status::get_tor_address().ok_or( - crate::libwallet::ErrorKind::GenericError( + grin_wallet_libwallet::swap::Error::MessageSender( "Tor is not running".to_string(), ), )?; @@ -2629,9 +2613,14 @@ where "file" => { // File, let's process it here let msg_str = swap_message.to_json()?; - let mut file = File::create(dest.clone())?; + let mut file = File::create(dest.clone()).map_err(|e| { + grin_wallet_libwallet::swap::Error::MessageSender(format!( + "Unable to create file {}, {}", + dest, e + )) + })?; file.write_all(msg_str.as_bytes()).map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( + grin_wallet_libwallet::swap::Error::MessageSender(format!( "Unable to store message data to the destination file, {}", e )) @@ -2641,10 +2630,8 @@ where } _ => { error!("Please specify a method (mwcmqs, tor, or file) for transporting swap messages to the other party with whom you're doing the swap!"); - return Err(crate::libwallet::Error::from( - crate::libwallet::ErrorKind::SwapError( - "Expected 'method' argument is not found".to_string(), - ), + return Err(grin_wallet_libwallet::swap::Error::MessageSender( + "Expected 'method' argument is not found".to_string(), )); } } @@ -2657,7 +2644,7 @@ where &tor_config2, ) .map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( + grin_wallet_libwallet::swap::Error::MessageSender(format!( "Unable to create message sender, {}", e )) @@ -2671,13 +2658,13 @@ where let ack = sender .send_swap_message(&swap_message, &secp) .map_err(|e| { - ErrorKind::LibWallet(format!( + grin_wallet_libwallet::swap::Error::MessageSender(format!( "Failure in sending swap message {} by {}: {}", swap_id2, method, e )) }) .map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( + grin_wallet_libwallet::swap::Error::MessageSender(format!( "Unable to deliver the message, {}", e )) @@ -2712,10 +2699,10 @@ where } Err(e) => { error!("Unable to process Swap {}: {}", swap_id, e); - Err( - ErrorKind::LibWallet(format!("Unable to process Swap {}: {}", swap_id, e)) - .into(), - ) + Err(Error::LibWallet(format!( + "Unable to process Swap {}: {}", + swap_id, e + ))) } } } @@ -2724,13 +2711,13 @@ where // For auto swap --json_format is a trigger for a one shot action. let one_shot = args.json_format; - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; if args.method.is_some() || args.destination.is_some() { - return Err(ErrorKind::ArgumentError( - "swap --autoswap doesn't accept 'method' or 'dest' parameters, instead it is using parameters associated with this swap trade.".to_string()).into()); + return Err(Error::ArgumentError( + "swap --autoswap doesn't accept 'method' or 'dest' parameters, instead it is using parameters associated with this swap trade.".to_string())); } let swap = owner_swap::swap_get(wallet_inst.clone(), keychain_mask, &swap_id)?; @@ -2746,7 +2733,7 @@ where match swap.communication_method.as_str() { "mwcmqs" => { if grin_wallet_impls::adapters::get_mwcmqs_brocker().is_some() { - return Err(ErrorKind::GenericError("mwcmqs listener is already running, there is no need to specify '--start_listener' parameter".to_string()).into()); + return Err(Error::GenericError("mwcmqs listener is already running, there is no need to specify '--start_listener' parameter".to_string())); } // Startting MQS @@ -2758,14 +2745,14 @@ where true, ) .map_err(|e| { - ErrorKind::LibWallet(format!("Unable to start mwcmqs listener, {}", e)) + Error::LibWallet(format!("Unable to start mwcmqs listener, {}", e)) })?; thread::sleep(Duration::from_millis(2000)); } "tor" => { // Checking is foreign API is running. It dont't important if it is tor or http. if controller::is_foreign_api_running() { - return Err(ErrorKind::GenericError("tor or http listener is already running, there is no need to specify '--start_listener' parameter".to_string()).into()); + return Err(Error::GenericError("tor or http listener is already running, there is no need to specify '--start_listener' parameter".to_string())); } // Starting tor @@ -2792,11 +2779,10 @@ where thread::sleep(Duration::from_millis(2000)); } _ => { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Auto Swap doesn't support communication method {}", swap.communication_method - )) - .into()); + ))); } } } @@ -2807,48 +2793,43 @@ where "mwcmqs" => { // Validating destination address let _ = MWCMQSAddress::from_str(&swap.communication_address).map_err(|e| { - ErrorKind::ArgumentError(format!("Invalid destination address, {}", e)) + Error::ArgumentError(format!("Invalid destination address, {}", e)) })?; if grin_wallet_impls::adapters::get_mwcmqs_brocker().is_none() { - return Err(ErrorKind::GenericError("mqcmqs listener is not running. Please start it with 'listen' command or '--start_listener' argument".to_string()).into()); + return Err(Error::GenericError("mqcmqs listener is not running. Please start it with 'listen' command or '--start_listener' argument".to_string())); } from_address = grin_wallet_impls::adapters::get_mwcmqs_brocker() - .ok_or(ErrorKind::GenericError( + .ok_or(Error::GenericError( "Unable to start mwcmqs listener".to_string(), ))? .0 .get_publisher_address() .map_err(|e| { - ErrorKind::GenericError(format!( - "Unable to get publisher address {}", - e - )) + Error::GenericError(format!("Unable to get publisher address {}", e)) })? .get_full_name(); } "tor" => { // Validating tor address let _ = validate_tor_address(&swap.communication_address).map_err(|e| { - ErrorKind::ArgumentError(format!("Invalid destination address, {}", e)) + Error::ArgumentError(format!("Invalid destination address, {}", e)) })?; if !controller::is_foreign_api_running() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Foreign API is not active and tor listener is not running." .to_string(), - ) - .into()); + )); } from_address = tor::status::get_tor_address() - .ok_or(ErrorKind::GenericError("Tor is not running".to_string()))?; + .ok_or(Error::GenericError("Tor is not running".to_string()))?; } _ => { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Auto Swap doesn't support communication method {}", swap.communication_method - )) - .into()); + ))); } } @@ -2856,39 +2837,40 @@ where let apisecret = args.apisecret.clone(); let swap_id2 = swap_id.clone(); let tor_config2 = tor_config.clone(); - let message_sender = move |swap_message: message::Message, - method: String, - destination: String| - -> Result<(bool, String), crate::libwallet::Error> { - // File is processed, the online send will be handled here - let sender = create_swap_message_sender( - method.as_str(), - destination.as_str(), - &apisecret, - &tor_config2, - ) - .map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( - "Unable to create message sender, {}", - e - )) - })?; - - let mut swap_message = swap_message; - if let message::Update::Offer(offer_update) = &mut swap_message.inner { - offer_update.from_address = from_address; - } - - let ack = sender - .send_swap_message(&swap_message, &secp) + let message_sender = + move |swap_message: message::Message, + method: String, + destination: String| + -> Result<(bool, String), grin_wallet_libwallet::swap::Error> { + // File is processed, the online send will be handled here + let sender = create_swap_message_sender( + method.as_str(), + destination.as_str(), + &apisecret, + &tor_config2, + ) .map_err(|e| { - crate::libwallet::ErrorKind::SwapError(format!( - "Unable to deliver the message {} by {}: {}", - swap_id2, method, e + grin_wallet_libwallet::swap::Error::MessageSender(format!( + "Unable to create message sender, {}", + e )) })?; - Ok((ack, format!("{} {}", method, destination))) - }; + + let mut swap_message = swap_message; + if let message::Update::Offer(offer_update) = &mut swap_message.inner { + offer_update.from_address = from_address; + } + + let ack = sender + .send_swap_message(&swap_message, &secp) + .map_err(|e| { + grin_wallet_libwallet::swap::Error::MessageSender(format!( + "Unable to deliver the message {} by {}: {}", + swap_id2, method, e + )) + })?; + Ok((ack, format!("{} {}", method, destination))) + }; // Calling mostly for params and environment validation. Also it is a nice chance to print the status of the deal that will be started let (mut prev_state, mut prev_action, mut prev_journal_len) = { @@ -2937,7 +2919,7 @@ where swap.secondary_currency .validate_address(addr) .map_err(|e| { - ErrorKind::ArgumentError(format!( + Error::ArgumentError(format!( "Invalid secondary currency address {}, {}", addr, e )) @@ -2947,11 +2929,10 @@ where if swap.get_secondary_address().is_empty() && swap.secondary_currency.is_btc_family() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Please define buyer_refund_address for automated swap" .to_string(), - ) - .into()); + )); } } } @@ -3174,11 +3155,10 @@ where let r = t.join(); if let Err(_) = r { error!("Error during running autoswap thread for {}", swap_id); - return Err(ErrorKind::LibWallet(format!( + return Err(Error::LibWallet(format!( "Error during running autoswap thread for {}", swap_id - )) - .into()); + ))); } } } @@ -3190,7 +3170,7 @@ where println!("This command is going to stop all the ongoing auto-swap threads. You can continue with the swap manually by entering commands step by step."); println!("Do you want to continue? Please answer Yes/No"); input.read_line(&mut answer).map_err(|e| { - ErrorKind::LibWallet(format!( + Error::LibWallet(format!( "Invalid answer to terminating the auto swap threads, {}", e )) @@ -3203,7 +3183,7 @@ where Ok(()) } SwapSubcommand::Dump => { - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; let result = owner_swap::swap_dump(wallet_inst, keychain_mask, &swap_id); @@ -3217,31 +3197,30 @@ where "Unable to dump the content of the swap file {}.swap: {}", swap_id, e ); - Err(ErrorKind::LibWallet(format!( + Err(Error::LibWallet(format!( "Unable to dump the content of the swap file {}.swap: {}", swap_id, e - )) - .into()) + ))) } } } SwapSubcommand::TradeExport => { - let swap_id = args.swap_id.ok_or(ErrorKind::ArgumentError( + let swap_id = args.swap_id.ok_or(Error::ArgumentError( "Not found expected 'swap_id' argument".to_string(), ))?; - let file_name = args.destination.ok_or(ErrorKind::ArgumentError( + let file_name = args.destination.ok_or(Error::ArgumentError( "Not found expected file name for the exported data".to_string(), ))?; trades::export_trade(swap_id.as_str(), file_name.as_str()) - .map_err(|e| ErrorKind::LibWallet(format!("Unable to export trade data, {}", e)))?; + .map_err(|e| Error::LibWallet(format!("Unable to export trade data, {}", e)))?; println!("Swap trade is exported to {}", file_name); Ok(()) } SwapSubcommand::TradeImport => { - let trade_file_name = args.destination.ok_or(ErrorKind::ArgumentError( + let trade_file_name = args.destination.ok_or(Error::ArgumentError( "Not found expected file name for the exported data".to_string(), ))?; @@ -3277,10 +3256,9 @@ where return Ok(()); } _ => { - return Err(ErrorKind::LibWallet( + return Err(Error::LibWallet( "Ethereum Get Wallet Info failed!".to_string(), - ) - .into()); + )); } } } @@ -3306,19 +3284,16 @@ where return Ok(()); } Err(e) => match e { - grin_wallet_libwallet::swap::ErrorKind::EthBalanceNotEnough => Err( - ErrorKind::LibWallet("Not Enough Ether to transfer/gas".to_string()).into(), + grin_wallet_libwallet::swap::Error::EthBalanceNotEnough => Err( + Error::LibWallet("Not Enough Ether to transfer/gas".to_string()), ), - grin_wallet_libwallet::swap::ErrorKind::ERC20TokenBalanceNotEnough(_error) => { - Err(ErrorKind::LibWallet(format!( + grin_wallet_libwallet::swap::Error::ERC20TokenBalanceNotEnough(_error) => { + Err(Error::LibWallet(format!( "Not Enough ERC-20 Token: {} to transfer", currency - )) - .into()) - } - _ => { - Err(ErrorKind::LibWallet("Unknown Ethereum Chain Error".to_string()).into()) + ))) } + _ => Err(Error::LibWallet("Unknown Ethereum Chain Error".to_string())), }, } } @@ -3405,22 +3380,20 @@ where } IntegritySubcommand::Create => { if args.fee.is_empty() { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "Please specify comma separated integrity fee that you need to activate" .to_string(), - ) - .into()); + )); } let min_fee = args.fee.iter().min().unwrap_or(&0); let min_integrity_fee = global::get_accept_fee_base() * libp2p_connection::INTEGRITY_FEE_MIN_X; if *min_fee < min_integrity_fee { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "The minimal accepted integrity fee is {} MWC", amount_to_hr_string(min_integrity_fee, true) - )) - .into()); + ))); } let max_fee = args.fee.iter().max().unwrap_or(&0); @@ -3570,10 +3543,7 @@ where for addr in libp2p_peers.libp2p_peers { libp2p_connection::add_new_peer(&PeerAddr::Onion(addr.clone())) .map_err(|e| { - ErrorKind::GenericError(format!( - "Failed to add libp2p peer, {}", - e - )) + Error::GenericError(format!("Failed to add libp2p peer, {}", e)) })?; if !args.json { println!("Joining the node peer at {}", addr); @@ -3583,10 +3553,7 @@ where for addr in libp2p_peers.node_peers { libp2p_connection::add_new_peer(&PeerAddr::Onion(addr.clone())) .map_err(|e| { - ErrorKind::GenericError(format!( - "Failed to add libp2p peer, {}", - e - )) + Error::GenericError(format!("Failed to add libp2p peer, {}", e)) })?; if !args.json { println!("Joining the node peer at {}", addr); @@ -3612,7 +3579,7 @@ where if seed.ends_with("onion") { libp2p_connection::add_new_peer(&PeerAddr::Onion(seed.to_string())) .map_err(|e| { - ErrorKind::GenericError(format!("Failed to add libp2p peer, {}", e)) + Error::GenericError(format!("Failed to add libp2p peer, {}", e)) })?; } } @@ -3744,26 +3711,24 @@ where if args.publish_message.is_some() { let publish_message = args.publish_message.unwrap(); - let publish_topic = args.publish_topic.ok_or(ErrorKind::ArgumentError( + let publish_topic = args.publish_topic.ok_or(Error::ArgumentError( "Please specify publish topic".to_string(), ))?; - let publish_interval = args.publish_interval.ok_or(ErrorKind::ArgumentError( + let publish_interval = args.publish_interval.ok_or(Error::ArgumentError( "Please specify message publishing interval value".to_string(), ))?; if publish_interval < 60 { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "Message publishing interval minimal value is 60 seconds".to_string(), - ) - .into()); + )); } let min_fee = global::get_accept_fee_base() * libp2p_connection::INTEGRITY_FEE_MIN_X; let fee = args.fee.unwrap_or(min_fee); if fee < min_fee { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Please specify fee higher than minimal integrity fee {}", amount_to_hr_string(min_fee, true) - )) - .into()); + ))); } // Let's check if message already running, so we can reuse integrity context @@ -3802,11 +3767,10 @@ where context = if args.fee_uuid.is_some() { let fee_uuid = args.fee_uuid.clone().unwrap(); if used_ctx_uuid.contains(&fee_uuid) { - return Err(ErrorKind::GenericError(format!( + return Err(Error::GenericError(format!( "Fee uuid {} is already used for another transaction", fee_uuid - )) - .into()); + ))); } fee_transaction .iter() @@ -3827,20 +3791,19 @@ where } if context.is_none() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Not found integrity context with paid fee".to_string(), - ) - .into()); + )); } let mkt_message = serde_json::from_str::(&publish_message).map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to parse the message {}, {}", publish_message, e )) })?; - let offer_id = mkt_message["id"].as_str().ok_or(ErrorKind::GenericError( + let offer_id = mkt_message["id"].as_str().ok_or(Error::GenericError( "Not found expected offer id".to_string(), ))?; @@ -3867,11 +3830,10 @@ where let uuid = match Uuid::parse_str(&withdraw_message_id) { Ok(uuid) => uuid, Err(e) => { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Unable to parse withdraw_message_id UUID value, {}", e - )) - .into()) + ))) } }; owner_swap::remove_published_offer(&uuid); @@ -3990,10 +3952,9 @@ where K: keychain::Keychain + 'static, { if !controller::is_foreign_api_running() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "TOR is not running. Please start tor listener for your wallet".to_string(), - ) - .into()); + )); } let dest = validate_tor_address(&args.tor_address)?; @@ -4008,7 +3969,7 @@ where tor_config.bridge.clone(), tor_config.proxy.clone(), ) - .map_err(|e| ErrorKind::GenericError(format!("Unable to create HTTP client to send, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable to create HTTP client to send, {}", e)))?; let tor_pk = owner::get_wallet_public_address(wallet_inst.clone(), keychain_mask)?; let tor_addr = ProvableAddress::from_tor_pub_key(&tor_pk); @@ -4037,10 +3998,9 @@ where K: keychain::Keychain + 'static, { if !controller::is_foreign_api_running() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "TOR is not running. Please start tor listener for your wallet".to_string(), - ) - .into()); + )); } let tor_pk = owner::get_wallet_public_address(wallet_inst.clone(), keychain_mask)?; diff --git a/controller/src/controller.rs b/controller/src/controller.rs index 1fc79529d..4d6e16e4d 100644 --- a/controller/src/controller.rs +++ b/controller/src/controller.rs @@ -20,7 +20,7 @@ use crate::libwallet::{ }; use crate::util::secp::key::SecretKey; use crate::util::{from_hex, to_base64, Mutex}; -use crate::{Error, ErrorKind}; +use crate::Error; use futures::channel::oneshot; use grin_wallet_api::JsonId; use grin_wallet_config::types::{TorBridgeConfig, TorProxyConfig}; @@ -102,7 +102,7 @@ fn check_middleware( } if let Some(s) = slate { if bhv > 3 && s.version_info.block_header_version < GRIN_BLOCK_HEADER_VERSION { - Err(crate::libwallet::ErrorKind::Compatibility( + Err(crate::libwallet::Error::Compatibility( "Incoming Slate is not compatible with this wallet. \ Please upgrade the node or use a different one." .into(), @@ -130,11 +130,10 @@ where let lc = w_lock.lc_provider()?; let w_inst = lc.wallet_inst()?; let k = w_inst.keychain((&mask).as_ref())?; - let sec_key = proofaddress::payment_proof_address_dalek_secret(&k, None).map_err(|e| { - ErrorKind::TorConfig(format!("Unable to build key for onion address, {}", e)) - })?; + let sec_key = proofaddress::payment_proof_address_dalek_secret(&k, None) + .map_err(|e| Error::TorConfig(format!("Unable to build key for onion address, {}", e)))?; let onion_addr = OnionV3Address::from_private(sec_key.as_bytes()) - .map_err(|e| ErrorKind::GenericError(format!("Unable to build Onion address, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable to build Onion address, {}", e)))?; Ok(format!("{}", onion_addr)) } @@ -168,30 +167,29 @@ where format!("{}/tor/listener", lc.get_top_level_directory()?) }; - let sec_key = proofaddress::payment_proof_address_secret(&k, None).map_err(|e| { - ErrorKind::TorConfig(format!("Unable to build key for onion address, {}", e)) - })?; + let sec_key = proofaddress::payment_proof_address_secret(&k, None) + .map_err(|e| Error::TorConfig(format!("Unable to build key for onion address, {}", e)))?; let onion_address = OnionV3Address::from_private(&sec_key.0) - .map_err(|e| ErrorKind::TorConfig(format!("Unable to build onion address, {}", e)))?; + .map_err(|e| Error::TorConfig(format!("Unable to build onion address, {}", e)))?; let mut hm_tor_bridge: HashMap = HashMap::new(); let mut tor_timeout = 200; if bridge.bridge_line.is_some() { tor_timeout = 300; let bridge_config = tor_bridge::TorBridge::try_from(bridge) - .map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?; + .map_err(|e| Error::TorConfig(format!("{}", e)))?; hm_tor_bridge = bridge_config .to_hashmap() - .map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?; + .map_err(|e| Error::TorConfig(format!("{}", e)))?; } let mut hm_tor_poxy: HashMap = 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)))?; hm_tor_poxy = proxy_config .to_hashmap() - .map_err(|e| ErrorKind::TorConfig(format!("{}", e.kind()).into()))?; + .map_err(|e| Error::TorConfig(format!("{}", e)))?; } warn!( @@ -209,7 +207,7 @@ where hm_tor_bridge, hm_tor_poxy, ) - .map_err(|e| ErrorKind::TorConfig(format!("Failed to configure tor, {}", e).into()))?; + .map_err(|e| Error::TorConfig(format!("Failed to configure tor, {}", e)))?; // Start TOR process let tor_path = format!("{}/torrc", tor_dir); process @@ -218,9 +216,7 @@ where .timeout(tor_timeout) .completion_percent(100) .launch() - .map_err(|e| { - ErrorKind::TorProcess(format!("Unable to start tor at {}, {}", tor_path, e).into()) - })?; + .map_err(|e| Error::TorProcess(format!("Unable to start tor at {}, {}", tor_path, e)))?; tor::status::set_tor_address(Some(format!("{}", onion_address))); @@ -247,10 +243,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, None), keychain_mask)? @@ -384,16 +379,16 @@ where //TODO: this needs to be changed to properly figure out if this slate is an invoice or a send if slate.tx_or_err()?.inputs().len() == 0 { // mwc-wallet doesn't support invoices - Err(ErrorKind::DoesNotAcceptInvoices)?; + Err(Error::DoesNotAcceptInvoices)?; // reject by default unless wallet is set to auto accept invoices under a certain threshold let max_auto_accept_invoice = self .max_auto_accept_invoice - .ok_or(ErrorKind::DoesNotAcceptInvoices)?; + .ok_or(Error::DoesNotAcceptInvoices)?; if slate.amount > max_auto_accept_invoice { - Err(ErrorKind::InvoiceAmountTooBig(slate.amount))?; + Err(Error::InvoiceAmountTooBig(slate.amount))?; } if global::is_mainnet() { @@ -456,7 +451,7 @@ where let s = foreign_api .receive_tx(slate, Some(from.get_full_name()), dest_acct_name, None) .map_err(|e| { - ErrorKind::LibWallet(format!( + Error::LibWallet(format!( "Unable to process incoming slate, receive_tx failed, {}", e )) @@ -509,7 +504,7 @@ where let mask = self.keychain_mask.lock().clone(); let msg_str = serde_json::to_string(&swapmessage).map_err(|e| { - ErrorKind::ProcessSwapMessageError(format!( + Error::ProcessSwapMessageError(format!( "Error in processing incoming swap message from mqs, {}", e )) @@ -640,7 +635,7 @@ where //start mwcmqs listener start_mwcmqs_listener(wallet, mqs_config, wait_for_thread, keychain_mask, true) - .map_err(|e| ErrorKind::GenericError(format!("cannot start mqs listener, {}", e)).into()) + .map_err(|e| Error::GenericError(format!("cannot start mqs listener, {}", e))) } /// Start the mqs listener @@ -657,9 +652,9 @@ where K: Keychain + 'static, { if grin_wallet_impls::adapters::get_mwcmqs_brocker().is_some() { - return Err( - ErrorKind::GenericError("mwcmqs listener is already running".to_string()).into(), - ); + return Err(Error::GenericError( + "mwcmqs listener is already running".to_string(), + )); } // make sure wallet is not locked, if it is try to unlock with no passphrase @@ -720,7 +715,7 @@ where panic!("{}", err_str); } }) - .map_err(|e| ErrorKind::GenericError(format!("Unable to start mwcmqs broker, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable to start mwcmqs broker, {}", e)))?; // Publishing this running MQS service crate::impls::init_mwcmqs_access_data(mwcmqs_publisher.clone(), mwcmqs_subscriber.clone()); @@ -756,14 +751,14 @@ where } if *OWNER_API_RUNNING.read().unwrap() { - return Err( - ErrorKind::GenericError("Owner API is already up and running".to_string()).into(), - ); + return Err(Error::GenericError( + "Owner API is already up and running".to_string(), + )); } if running_foreign && *FOREIGN_API_RUNNING.read().unwrap() { - return Err( - ErrorKind::GenericError("Foreign API is already up and running".to_string()).into(), - ); + return Err(Error::GenericError( + "Foreign API is already up and running".to_string(), + )); } //I don't know why but it seems the warn message in controller.rs will get printed to console. @@ -790,15 +785,11 @@ where router .add_route("/v2/owner", Arc::new(api_handler_v2)) - .map_err(|e| { - ErrorKind::GenericError(format!("Router failed to add route /v2/owner, {}", e)) - })?; + .map_err(|e| Error::GenericError(format!("Router failed to add route /v2/owner, {}", e)))?; router .add_route("/v3/owner", Arc::new(api_handler_v3)) - .map_err(|e| { - ErrorKind::GenericError(format!("Router failed to add route /v3/owner, {}", e)) - })?; + .map_err(|e| Error::GenericError(format!("Router failed to add route /v3/owner, {}", e)))?; // If so configured, add the foreign API to the same port if running_foreign { @@ -807,7 +798,7 @@ where router .add_route("/v2/foreign", Arc::new(foreign_api_handler_v2)) .map_err(|e| { - ErrorKind::GenericError(format!("Router failed to add route /v2/foreign, {}", e)) + Error::GenericError(format!("Router failed to add route /v2/foreign, {}", e)) })?; } let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) = @@ -817,7 +808,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) - .map_err(|e| ErrorKind::GenericError(format!("API thread failed to start, {}", e)))?; + .map_err(|e| Error::GenericError(format!("API thread failed to start, {}", e)))?; warn!("HTTP Owner listener started."); *OWNER_API_RUNNING.write().unwrap() = true; @@ -827,7 +818,7 @@ where let res = api_thread .join() - .map_err(|e| ErrorKind::GenericError(format!("API thread panicked :{:?}", e)).into()); + .map_err(|e| Error::GenericError(format!("API thread panicked :{:?}", e))); *OWNER_API_RUNNING.write().unwrap() = false; if running_foreign { @@ -857,7 +848,7 @@ where }; let tor_addr: SocketAddrV4 = socks_proxy_addr.parse().map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to parse tor socks address {}, {}", socks_proxy_addr, e )) @@ -959,9 +950,7 @@ where } } }) - .map_err(|e| { - ErrorKind::GenericError(format!("Unable to start libp2p_node server, {}", e)) - })?; + .map_err(|e| Error::GenericError(format!("Unable to start libp2p_node server, {}", e)))?; Ok(()) } @@ -986,9 +975,9 @@ where K: Keychain + 'static, { if *FOREIGN_API_RUNNING.read().unwrap() { - return Err( - ErrorKind::GenericError("Foreign API is already up and running".to_string()).into(), - ); + return Err(Error::GenericError( + "Foreign API is already up and running".to_string(), + )); } // Check if wallet has been opened first, get slatepack public key @@ -1031,7 +1020,7 @@ where router .add_route("/v2/foreign", Arc::new(api_handler_v2)) .map_err(|e| { - ErrorKind::GenericError(format!("Router failed to add route /v2/foreign, {}", e)) + Error::GenericError(format!("Router failed to add route /v2/foreign, {}", e)) })?; let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) = @@ -1042,7 +1031,7 @@ where let api_thread = apis // Assuming you have a variable `channel_pair` of the required type .start(socket_addr, router, tls_config, api_chan) - .map_err(|e| ErrorKind::GenericError(format!("API thread failed to start, {}", e)))?; + .map_err(|e| Error::GenericError(format!("API thread failed to start, {}", e)))?; warn!("HTTP Foreign listener started."); @@ -1078,7 +1067,7 @@ where let res = api_thread .join() - .map_err(|e| ErrorKind::GenericError(format!("API thread panicked :{:?}", e)).into()); + .map_err(|e| Error::GenericError(format!("API thread panicked :{:?}", e))); *FOREIGN_API_RUNNING.write().unwrap() = false; @@ -1292,7 +1281,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)) @@ -1315,7 +1304,7 @@ impl OwnerV3Helpers { } 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!("Encryption Error: {}", e.kind())) + EncryptionErrorResponse::new(1, -32003, &format!("Encryption Error: {}", e)) .as_json_value() })?; let res = enc_res.as_json_value().map_err(|e| { @@ -1705,8 +1694,8 @@ where { let body = body::to_bytes(req.into_body()) .await - .map_err(|e| ErrorKind::GenericError(format!("Failed to read request, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Failed to read request, {}", e)))?; 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))) } diff --git a/controller/src/error.rs b/controller/src/error.rs index d151e88d5..ad43ddd6f 100644 --- a/controller/src/error.rs +++ b/controller/src/error.rs @@ -18,238 +18,131 @@ use crate::core::core::transaction; 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, -} /// 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, {}", _0)] - LibTX(libtx::Error), + #[error("LibTx Error, {0}")] + LibTX(#[from] libtx::Error), /// Impls error - #[fail(display = "Impls Error, {}", _0)] - Impls(impls::ErrorKind), + #[error("Impls Error, {0}")] + Impls(#[from] impls::Error), /// LibWallet Error - #[fail(display = "LibWallet Error, {}", _0)] + #[error("LibWallet Error, {0}")] LibWallet(String), + /// Swap Error + #[error("Swap error, {0}")] + SwapError(String), + /// Keychain error - #[fail(display = "Keychain error, {}", _0)] - Keychain(keychain::Error), + #[error("Keychain error, {0}")] + Keychain(#[from] keychain::Error), /// Transaction Error - #[fail(display = "Transaction error, {}", _0)] - Transaction(transaction::Error), + #[error("Transaction error, {0}")] + Transaction(#[from] transaction::Error), /// Secp Error - #[fail(display = "Secp error, {}", _0)] + #[error("Secp error, {0}")] Secp(String), /// Filewallet error - #[fail(display = "Wallet data error: {}", _0)] + #[error("Wallet data error: {0}")] FileWallet(&'static str), /// Error when formatting json - #[fail(display = "Controller IO error, {}", _0)] + #[error("Controller IO error, {0}")] IO(String), /// Error when formatting json - #[fail(display = "Serde JSON error, {}", _0)] + #[error("Serde JSON error, {0}")] Format(String), /// Error when contacting a node through its API - #[fail(display = "Node API error, {}", _0)] - Node(api::Error), + #[error("Node API error, {0}")] + Node(#[from] api::Error), /// Error originating from hyper. - #[fail(display = "Hyper error, {}", _0)] + #[error("Hyper error, {0}")] Hyper(String), /// 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, {}", _0)] + #[error("Duplicate transaction ID error, {0}")] DuplicateTransactionId(String), /// 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 = "Invalid argument: {}", _0)] + #[error("Invalid argument: {0}")] ArgumentError(String), /// Other - #[fail(display = "Generic error: {}", _0)] + #[error("Generic error: {0}")] GenericError(String), /// Listener error - #[fail(display = "Listener Startup Error")] + #[error("Listener Startup Error")] ListenerError, /// Tor Configuration Error - #[fail(display = "Tor Config Error: {}", _0)] + #[error("Tor Config Error: {0}")] TorConfig(String), /// Tor Process error - #[fail(display = "Tor Process Error: {}", _0)] + #[error("Tor Process Error: {0}")] TorProcess(String), /// MQS Configuration Error - #[fail(display = "MQS Config Error: {}", _0)] + #[error("MQS Config Error: {0}")] MQSConfig(String), ///rejecting invoice as auto invoice acceptance is turned off - #[fail(display = "rejecting invoice as auto invoice acceptance is turned off!")] + #[error("rejecting invoice as auto invoice acceptance is turned off!")] DoesNotAcceptInvoices, ///when invoice amount is too big(added with mqs feature) - #[fail(display = "error: rejecting invoice as amount '{}' is too big!", _0)] + #[error("error: rejecting invoice as amount '{0}' is too big!")] InvoiceAmountTooBig(u64), /// Verify slate messages call failure - #[fail(display = "failed verifying slate messages, {}", _0)] + #[error("failed verifying slate messages, {0}")] VerifySlateMessagesError(String), /// Processing swap message failure - #[fail(display = "failed processing swap messages, {}", _0)] + #[error("failed processing swap messages, {0}")] ProcessSwapMessageError(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 for Error { - fn from(kind: ErrorKind) -> Error { - Error { - inner: Context::new(kind), - } - } -} - -impl From> for Error { - fn from(inner: Context) -> Error { - Error { inner: inner } - } -} - -impl From for Error { - fn from(error: api::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Node(error)), - } - } -} - -impl From for Error { - fn from(error: keychain::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Keychain(error)), - } - } -} - -impl From for Error { - fn from(error: transaction::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Transaction(error)), - } - } -} - -impl From for Error { - fn from(error: libwallet::Error) -> Error { - Error { - inner: Context::new(ErrorKind::LibWallet(format!("{}", error))), - } - } -} - -impl From for Error { - fn from(error: libtx::Error) -> Error { - Error { - inner: Context::new(ErrorKind::LibTX(error)), - } +impl From for Error { + fn from(error: grin_wallet_libwallet::Error) -> Error { + Error::LibWallet(format!("{}", error)) } } -impl From for Error { - fn from(error: impls::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Impls(error.kind())), - } +impl From for Error { + fn from(error: grin_wallet_libwallet::swap::Error) -> Error { + Error::SwapError(format!("{}", error)) } } diff --git a/controller/src/lib.rs b/controller/src/lib.rs index bd34cf1cb..48d72ee2a 100644 --- a/controller/src/lib.rs +++ b/controller/src/lib.rs @@ -24,7 +24,6 @@ extern crate serde_json; 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; @@ -40,4 +39,4 @@ pub mod display; mod error; pub mod executor; -pub use crate::error::{Error, ErrorKind}; +pub use crate::error::Error; diff --git a/controller/tests/accounts.rs b/controller/tests/accounts.rs index 84f5b396d..a94b153db 100644 --- a/controller/tests/accounts.rs +++ b/controller/tests/accounts.rs @@ -276,7 +276,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); } diff --git a/controller/tests/build_chain.rs b/controller/tests/build_chain.rs index eebda927e..0078cdbbf 100644 --- a/controller/tests/build_chain.rs +++ b/controller/tests/build_chain.rs @@ -170,7 +170,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 } diff --git a/controller/tests/build_output.rs b/controller/tests/build_output.rs index 5a5588165..86dffed9d 100644 --- a/controller/tests/build_output.rs +++ b/controller/tests/build_output.rs @@ -96,7 +96,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); } diff --git a/controller/tests/check.rs b/controller/tests/check.rs index b35e4983d..478c9999e 100644 --- a/controller/tests/check.rs +++ b/controller/tests/check.rs @@ -863,7 +863,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); } @@ -873,7 +873,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); } @@ -883,7 +883,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); } diff --git a/controller/tests/file.rs b/controller/tests/file.rs index e64580ce4..8c1db2106 100644 --- a/controller/tests/file.rs +++ b/controller/tests/file.rs @@ -247,7 +247,7 @@ fn wallet_file_exchange() { let test_dir = "test_output/file_exchange"; setup(test_dir); if let Err(e) = file_exchange_test_impl(test_dir) { - panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap()); + panic!("Libwallet Error: {}", e); } clean_output_dir(test_dir); } diff --git a/controller/tests/integrity_kernel.rs b/controller/tests/integrity_kernel.rs index cc9492f10..2150cc01f 100644 --- a/controller/tests/integrity_kernel.rs +++ b/controller/tests/integrity_kernel.rs @@ -337,7 +337,7 @@ fn wallet_integrity_kernel() { let test_dir = "test_output/integrity_kernel"; setup(test_dir); if let Err(e) = integrity_kernel_impl(test_dir) { - panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap()); + panic!("Libwallet Error: {}", e); } clean_output_dir(test_dir); } diff --git a/controller/tests/late_lock.rs b/controller/tests/late_lock.rs index 1bd118b03..8405f2724 100644 --- a/controller/tests/late_lock.rs +++ b/controller/tests/late_lock.rs @@ -215,7 +215,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); } diff --git a/controller/tests/no_change.rs b/controller/tests/no_change.rs index f710ce97f..e12341bbd 100644 --- a/controller/tests/no_change.rs +++ b/controller/tests/no_change.rs @@ -168,7 +168,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); } diff --git a/controller/tests/payment_proofs.rs b/controller/tests/payment_proofs.rs index 82107eb41..e059668a9 100644 --- a/controller/tests/payment_proofs.rs +++ b/controller/tests/payment_proofs.rs @@ -185,7 +185,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); } diff --git a/controller/tests/repost.rs b/controller/tests/repost.rs index b6e1448e8..771ade021 100644 --- a/controller/tests/repost.rs +++ b/controller/tests/repost.rs @@ -281,7 +281,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); } diff --git a/controller/tests/revert.rs b/controller/tests/revert.rs index c4139ebf9..23939d9ab 100644 --- a/controller/tests/revert.rs +++ b/controller/tests/revert.rs @@ -369,7 +369,7 @@ fn tx_revert_reconfirm() { global::set_global_chain_type(global::ChainTypes::AutomatedTesting); 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); } @@ -380,7 +380,7 @@ fn tx_revert_cancel() { global::set_global_chain_type(global::ChainTypes::AutomatedTesting); 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); } diff --git a/controller/tests/self_send.rs b/controller/tests/self_send.rs index 7717271df..f6fad3b2c 100644 --- a/controller/tests/self_send.rs +++ b/controller/tests/self_send.rs @@ -145,7 +145,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); } diff --git a/controller/tests/self_spend.rs b/controller/tests/self_spend.rs index 98ecd7404..90ddf67cc 100644 --- a/controller/tests/self_spend.rs +++ b/controller/tests/self_spend.rs @@ -165,7 +165,7 @@ fn wallet_self_spend() { let test_dir = "test_output/self_spend"; setup(test_dir); if let Err(e) = self_spend_impl(test_dir) { - panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap()); + panic!("Libwallet Error: {}", e); } clean_output_dir(test_dir); } diff --git a/controller/tests/slatepack.rs b/controller/tests/slatepack.rs index e7d46eeee..be54ecb38 100644 --- a/controller/tests/slatepack.rs +++ b/controller/tests/slatepack.rs @@ -50,9 +50,7 @@ fn output_slatepack( ) -> Result<(), libwallet::Error> { PathToSlatePutter::build_encrypted(Some(file_name.into()), content, sender, recipients, true) .put_tx(&slate, Some(&sender_secret), true, secp) - .map_err(|e| { - libwallet::ErrorKind::GenericError(format!("Unable to store the slate, {}", e)) - })?; + .map_err(|e| libwallet::Error::GenericError(format!("Unable to store the slate, {}", e)))?; Ok(()) } @@ -64,12 +62,11 @@ fn slate_from_packed( ) -> Result { match PathToSlateGetter::build_form_path(file.into()) .get_tx(Some(dec_key), height, secp) - .map_err(|e| { - libwallet::ErrorKind::GenericError(format!("Unable to read the slate, {}", e)) - })? { + .map_err(|e| libwallet::Error::GenericError(format!("Unable to read the slate, {}", e)))? + { // Plain slate, V2 or V3 SlateGetData::PlainSlate(_) => { - return Err(libwallet::ErrorKind::GenericError( + return Err(libwallet::Error::GenericError( "Not found expected encrypted slatepack, found in plain format only".to_string(), ) .into()) @@ -498,7 +495,7 @@ fn slatepack_exchange() { setup(test_dir); // Json output if let Err(e) = slatepack_exchange_test_impl(test_dir) { - panic!("Libwallet Error: {} - {}", e, e.backtrace().unwrap()); + panic!("Libwallet Error: {}", e); } clean_output_dir(test_dir); } diff --git a/controller/tests/transaction.rs b/controller/tests/transaction.rs index 2e4b80a17..5bb3b0524 100644 --- a/controller/tests/transaction.rs +++ b/controller/tests/transaction.rs @@ -586,7 +586,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); } @@ -596,7 +596,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); } diff --git a/controller/tests/ttl_cutoff.rs b/controller/tests/ttl_cutoff.rs index 45a4e9ff6..14b4162dc 100644 --- a/controller/tests/ttl_cutoff.rs +++ b/controller/tests/ttl_cutoff.rs @@ -182,7 +182,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); } diff --git a/controller/tests/updater_thread.rs b/controller/tests/updater_thread.rs index 9bb250847..03c1580e3 100644 --- a/controller/tests/updater_thread.rs +++ b/controller/tests/updater_thread.rs @@ -120,7 +120,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); } diff --git a/impls/Cargo.toml b/impls/Cargo.toml index c946da1db..960462220 100644 --- a/impls/Cargo.toml +++ b/impls/Cargo.toml @@ -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" diff --git a/impls/src/adapters/file.rs b/impls/src/adapters/file.rs index fa9dafb8f..13f946a90 100644 --- a/impls/src/adapters/file.rs +++ b/impls/src/adapters/file.rs @@ -17,7 +17,7 @@ use std::fs::{metadata, File}; use std::io::{Read, Write}; use crate::adapters::SlateGetData; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::libwallet::{Slate, SlateVersion, VersionedSlate}; use crate::{SlateGetter, SlatePutter}; use ed25519_dalek::{PublicKey as DalekPublicKey, SecretKey as DalekSecretKey}; @@ -99,17 +99,15 @@ impl SlatePutter for PathToSlatePutter { if self.recipient.is_some() || self.slatepack_format { // recipient is defining enrypted/nonencrypted format. Sender and content are still required. if self.sender.is_none() || self.content.is_none() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Sender or content are not defined".to_string(), - ) - .into()); + )); } if slatepack_secret.is_none() { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "slatepack_secret is not defiled for encrypted slatepack".to_string(), - ) - .into()); + )); } // Do the slatepack @@ -123,47 +121,47 @@ impl SlatePutter for PathToSlatePutter { use_test_rng, secp, ) - .map_err(|e| { - ErrorKind::GenericError(format!("Unable to build a slatepack, {}", e)) - })? + .map_err(|e| Error::GenericError(format!("Unable to build a slatepack, {}", e)))? } else if slate.compact_slate { warn!("Transaction contains features that require mwc-wallet 4.0.0 or later"); warn!("Please ensure the other party is running mwc-wallet v4.0.0 or later before sending"); VersionedSlate::into_version_plain(slate.clone(), SlateVersion::V3).map_err( - |e| ErrorKind::GenericError(format!("Failed convert Slate to Json, {}", e)), + |e| Error::GenericError(format!("Failed convert Slate to Json, {}", e)), )? } else if slate.payment_proof.is_some() || slate.ttl_cutoff_height.is_some() { warn!("Transaction contains features that require mwc-wallet 3.0.0 or later"); warn!("Please ensure the other party is running mwc-wallet v3.0.0 or later before sending"); VersionedSlate::into_version_plain(slate.clone(), SlateVersion::V3).map_err( - |e| ErrorKind::GenericError(format!("Failed convert Slate to Json, {}", e)), + |e| Error::GenericError(format!("Failed convert Slate to Json, {}", e)), )? } else { let mut s = slate.clone(); s.version_info.version = 2; VersionedSlate::into_version_plain(s, SlateVersion::V2).map_err(|e| { - ErrorKind::GenericError(format!("Failed convert Slate to Json, {}", e)) + Error::GenericError(format!("Failed convert Slate to Json, {}", e)) })? } }; - let slate_str = out_slate.as_string()?; + let slate_str = out_slate + .as_string() + .map_err(|e| Error::LibWallet(format!("Unable to convert slate into string, {}", e)))?; if let Some(path_buf) = &self.path_buf { let file_name = path_buf.to_str().unwrap_or("INVALID PATH"); let mut pub_tx = File::create(&path_buf).map_err(|e| { - ErrorKind::IO(format!("Unable to create proof file {}, {}", file_name, e)) + Error::IO(format!("Unable to create proof file {}, {}", file_name, e)) })?; pub_tx.write_all(slate_str.as_bytes()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to store slate at file {}, {}", file_name, e )) })?; pub_tx.sync_all().map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to store slate at file {}, {}", file_name, e )) @@ -187,11 +185,10 @@ impl SlateGetter for PathToSlateGetter { let max_len = slatepack::max_size(); let len = str.len() as u64; if len < min_len || len > max_len { - return Err(ErrorKind::IO(format!( + return Err(Error::IO(format!( "Slate data had invalid length: {} | min: {}, max: {} |", len, min_len, max_len - )) - .into()); + ))); } str.clone() } @@ -199,7 +196,7 @@ impl SlateGetter for PathToSlateGetter { // Reading from the file if let Some(path_buf) = &self.path_buf { let metadata = metadata(path_buf.as_path()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to access file {}, {}", path_buf.display(), e @@ -212,58 +209,51 @@ impl SlateGetter for PathToSlateGetter { let file_name = path_buf.to_str().unwrap_or("INVALID PATH"); if len < min_len || len > max_len { - return Err(ErrorKind::IO(format!( + return Err(Error::IO(format!( "Data at {} is invalid length: {} | min: {}, max: {} |", file_name, len, min_len, max_len - )) - .into()); + ))); } let mut pub_tx_f = File::open(&path_buf).map_err(|e| { - ErrorKind::IO(format!("Unable to open file {}, {}", file_name, e)) + Error::IO(format!("Unable to open file {}, {}", file_name, e)) })?; let mut content = String::new(); pub_tx_f.read_to_string(&mut content).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to read data from file {}, {}", file_name, e )) })?; if content.len() < 3 { - return Err(ErrorKind::GenericError(format!( - "File {} is empty", - file_name - )) - .into()); + return Err(Error::GenericError(format!("File {} is empty", file_name))); } content } else { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "PathToSlateGetter, not defined slate string or file".to_string(), - ) - .into()); + )); } } }; if Slate::deserialize_is_plain(&content) { - let slate = Slate::deserialize_upgrade_plain(&content).map_err(|e| { - ErrorKind::IO(format!("Unable to build slate from the content, {}", e)) - })?; + let slate = Slate::deserialize_upgrade_plain(&content) + .map_err(|e| Error::IO(format!("Unable to build slate from the content, {}", e)))?; Ok(SlateGetData::PlainSlate(slate)) } else { if slatepack_secret.is_none() { - return Err(ErrorKind::ArgumentError( + return Err(Error::ArgumentError( "slatepack_secret is none for get encrypted slatepack".into(), - ) - .into()); + )); } let sp = Slate::deserialize_upgrade_slatepack( &content, slatepack_secret.unwrap(), height, secp, - )?; + ) + .map_err(|e| Error::LibWallet(format!("Unable to deserialize slatepack, {}", e)))?; Ok(SlateGetData::Slatepack(sp)) } } diff --git a/impls/src/adapters/http.rs b/impls/src/adapters/http.rs index 76694e1bf..2d9793fcc 100644 --- a/impls/src/adapters/http.rs +++ b/impls/src/adapters/http.rs @@ -13,8 +13,8 @@ // limitations under the License. /// HTTP Wallet 'plugin' implementation -use crate::client_utils::{Client, ClientError, ClientErrorKind}; -use crate::error::{Error, ErrorKind}; +use crate::client_utils::{Client, ClientError}; +use crate::error::Error; use crate::libwallet::slate_versions::{SlateVersion, VersionedSlate}; use crate::libwallet::swap::message::Message; use crate::libwallet::Slate; @@ -64,7 +64,10 @@ impl HttpDataSender { tor_log_file: Option, ) -> Result { if !base_url.starts_with("http") && !base_url.starts_with("https") { - Err(ErrorKind::GenericError(format!("Invalid http url: {}", base_url)).into()) + Err(Error::GenericError(format!( + "Invalid http url: {}", + base_url + ))) } else { Ok(HttpDataSender { base_url: base_url.to_owned(), @@ -100,7 +103,7 @@ impl HttpDataSender { )?; ret.use_socks = true; let addr = proxy_addr.parse().map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse address {}, {}", proxy_addr, e)) + Error::GenericError(format!("Unable to parse address {}, {}", proxy_addr, e)) })?; ret.socks_proxy_addr = Some(SocketAddr::V4(addr)); ret.tor_config_dir = tor_config_dir.unwrap_or(String::from("")); @@ -161,12 +164,12 @@ impl HttpDataSender { .to_string(); } error!("{}", report); - ErrorKind::ClientCallback(report) + Error::ClientCallback(report) })?; } let res: Value = serde_json::from_str(&res_str).map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) + Error::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) })?; trace!("Response: {}", res); if res["error"] != json!(null) { @@ -175,14 +178,14 @@ impl HttpDataSender { 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(); trace!("resp_value: {}", resp_value.clone()); let foreign_api_version: u16 = serde_json::from_value(resp_value["foreign_api_version"].clone()).map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to read respond foreign_api_version value {}, {}", res_str, e )) @@ -191,7 +194,7 @@ impl HttpDataSender { resp_value["supported_slate_versions"].clone(), ) .map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to read respond supported_slate_versions value {}, {}", res_str, e )) @@ -201,13 +204,18 @@ impl HttpDataSender { 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)); } let slatepack_address: Option = if supported_slate_versions.contains(&"SP".to_owned()) { match address::pubkey_from_onion_v3(destination_address) { - Ok(pk) => Some(address::onion_v3_from_pubkey(&pk)?), + Ok(pk) => Some(address::onion_v3_from_pubkey(&pk).map_err(|e| { + Error::LibWallet(format!( + "Unable to build onion address from public key, {}", + e + )) + })?), Err(_) => { // Destination is not tor address, so making foreign API request for get an address Some(self.check_receiver_proof_address(url, timeout.clone())?) @@ -229,7 +237,7 @@ impl HttpDataSender { let report = "Unable to negotiate slate format with other wallet.".to_string(); error!("{}", report); - Err(ErrorKind::ClientCallback(report).into()) + Err(Error::ClientCallback(report)) } /// Check proof address of the listening wallet @@ -285,12 +293,12 @@ impl HttpDataSender { .to_string(); } error!("{}", report); - ErrorKind::ClientCallback(report) + Error::ClientCallback(report) })?; } let res: Value = serde_json::from_str(&res_str).map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) + Error::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) })?; trace!("Response: {}", res); if res["error"] != json!(null) { @@ -299,7 +307,7 @@ impl HttpDataSender { 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(); @@ -314,7 +322,7 @@ impl HttpDataSender { } let report = "Unable to check proof address with other wallet.".to_string(); error!("{}", report); - Err(ErrorKind::ClientCallback(report).into()) + Err(Error::ClientCallback(report)) } fn post( @@ -327,17 +335,15 @@ impl HttpDataSender { IN: Serialize, { // For state sender we want send and disconnect - 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(|err| { - ClientErrorKind::Internal(format!("Unable to create http client, {}", err)) - })?; + 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(|err| ClientError::Internal(format!("Unable to create http client, {}", err)))?; let req = client.create_post_request(url, Some("mwc".to_string()), api_secret, &input)?; let res = client.send_request(req)?; @@ -372,26 +378,26 @@ impl HttpDataSender { let mut hm_tor_bridge: HashMap = 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 = 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( &tor_dir, &self .socks_proxy_addr - .ok_or(ErrorKind::GenericError( + .ok_or(Error::GenericError( "Not found socks_proxy_addr value".to_string(), ))? .to_string(), @@ -399,7 +405,7 @@ impl HttpDataSender { hm_tor_bridge, hm_tor_proxy, ) - .map_err(|e| ErrorKind::TorConfig(format!("Failed to config Tor, {}", e)))?; + .map_err(|e| Error::TorConfig(format!("Failed to config Tor, {}", e)))?; // Start TOR process let tor_cmd = format!("{}/torrc", &tor_dir); tor.torrc_path(&tor_cmd) @@ -408,10 +414,7 @@ impl HttpDataSender { .completion_percent(100) .launch() .map_err(|e| { - ErrorKind::TorProcess(format!( - "Unable to start Tor process {}, {:?}", - tor_cmd, e - )) + Error::TorProcess(format!("Unable to start Tor process {}, {:?}", tor_cmd, e)) })?; tor::status::set_tor_sender_running(true); } @@ -447,11 +450,10 @@ impl SlateSender for HttpDataSender { let (url_str, _tor) = self.set_up_tor_send_process()?; if other_wallet_version.is_none() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Internal error, http based send_tx get empty value for other_wallet_version" .to_string(), - ) - .into()); + )); } let (mut slate_version, slatepack_address) = other_wallet_version.unwrap(); @@ -468,15 +470,17 @@ impl SlateSender for HttpDataSender { if recipient.is_none() { if let Some(slatepack_address) = slatepack_address { recipient = - Some(ProvableAddress::from_str(&slatepack_address)?.tor_public_key()?); + Some(ProvableAddress::from_str(&slatepack_address) + .map_err(|e| Error::LibWallet(format!("Unable to parse slatepack address {}, {}", slatepack_address, e)))? + .tor_public_key() + .map_err(|e| Error::LibWallet(format!("Unable to convert slatepack address {} into public key, {}", slatepack_address, e)))?); } } if recipient.is_none() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Not provided expected recipient address for Slate Pack".to_string(), - ) - .into()); + )); } let tor_pk = DalekPublicKey::from(slatepack_secret); @@ -489,33 +493,34 @@ impl SlateSender for HttpDataSender { slatepack_secret, false, secp, - )? + ) + .map_err(|e| Error::LibWallet(format!("Unable to process slate, {}", e)))? } SlateVersion::V3B => { if slate.compact_slate { - return Err(ErrorKind::ClientCallback( + return Err(Error::ClientCallback( "Other wallet doesn't support slatepack compact model".into(), - ) - .into()); + )); } - VersionedSlate::into_version_plain(slate.clone(), SlateVersion::V3B)? + VersionedSlate::into_version_plain(slate.clone(), SlateVersion::V3B) + .map_err(|e| Error::LibWallet(format!("Unable to process slate, {}", e)))? } SlateVersion::V2 | SlateVersion::V3 => { let mut slate = slate.clone(); if slate.compact_slate { - return Err(ErrorKind::ClientCallback( + return Err(Error::ClientCallback( "Other wallet doesn't support slatepack compact model".into(), - ) - .into()); + )); } if slate.payment_proof.is_some() { - return Err(ErrorKind::ClientCallback("Payment proof requested, but other wallet does not support payment proofs or tor payment proof. Please urge other user to upgrade, or re-send tx without a payment proof".into()).into()); + return Err(Error::ClientCallback("Payment proof requested, but other wallet does not support payment proofs or tor payment proof. Please urge other user to upgrade, or re-send tx without a payment proof".into())); } if slate.ttl_cutoff_height.is_some() { warn!("Slate TTL value will be ignored and removed by other wallet, as other wallet does not support this feature. Please urge other user to upgrade"); } slate.version_info.version = 2; - VersionedSlate::into_version_plain(slate.clone(), SlateVersion::V2)? + VersionedSlate::into_version_plain(slate.clone(), SlateVersion::V2) + .map_err(|e| Error::LibWallet(format!("Unable to process slate, {}", e)))? } }; @@ -564,12 +569,12 @@ impl SlateSender for HttpDataSender { res.map_err(|e| { let report = format!("Posting transaction slate (is recipient listening?): {}", e); error!("{}", report); - ErrorKind::ClientCallback(report) + Error::ClientCallback(report) })?; } let mut res: Value = serde_json::from_str(&res_str).map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) + Error::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) })?; trace!("Response: {}", res); if res["error"] != json!(null) { @@ -578,12 +583,12 @@ impl SlateSender for HttpDataSender { res["error"]["code"], res["error"]["message"] ); error!("{}", report); - return Err(ErrorKind::ClientCallback(report).into()); + return Err(Error::ClientCallback(report)); } if res["result"]["Err"] != json!(null) { let report = format!("Posting transaction slate: Error: {}", res["result"]["Err"]); error!("{}", report); - return Err(ErrorKind::ClientCallback(report).into()); + return Err(Error::ClientCallback(report)); } let slate_value = res["result"]["Ok"].clone(); @@ -591,7 +596,7 @@ impl SlateSender for HttpDataSender { if slate_value.is_null() { let report = format!("Unable to parse receiver wallet response {}", res_str); error!("{}", report); - return Err(ErrorKind::ClientCallback(report).into()); + return Err(Error::ClientCallback(report)); } if res["result"]["Ok"]["version_info"]["version"] == json!(3) @@ -601,19 +606,19 @@ impl SlateSender for HttpDataSender { } let slate_str = serde_json::to_string(&slate_value).map_err(|e| { - ErrorKind::GenericError(format!("Unable to build slate from values, {}", e)) + Error::GenericError(format!("Unable to build slate from values, {}", e)) })?; let res_slate = if Slate::deserialize_is_plain(&slate_str) { Slate::deserialize_upgrade_plain(&slate_str).map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to build slate from response {}, {}", res_str, e )) })? } else { let slatepack_str: String = serde_json::from_str(&slate_str).map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Invalid other wallet response, unable to decode the slate {}, {}", slate_str, e )) @@ -623,7 +628,8 @@ impl SlateSender for HttpDataSender { &slatepack_secret, height, secp, - )?; + ) + .map_err(|e| Error::LibWallet(format!("Unable to process slate, {}", e)))?; sp.to_result_slate() }; @@ -637,7 +643,7 @@ impl SwapMessageSender for HttpDataSender { // we need to keep _tor in scope so that the process is not killed by drop. let (url_str, _tor) = self.set_up_tor_send_process()?; let message_ser = &serde_json::to_string(&swap_message).map_err(|e| { - ErrorKind::SwapMessageGenericError(format!( + Error::SwapMessageGenericError(format!( "Failed to convert swap message to json in preparation for Tor request, {}", e )) @@ -669,12 +675,12 @@ impl SwapMessageSender for HttpDataSender { res.map_err(|e| { let report = format!("Posting swap message (is recipient listening?): {}", e); error!("{}", report); - ErrorKind::ClientCallback(report) + Error::ClientCallback(report) })?; } let res: Value = serde_json::from_str(&res_str).map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) + Error::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) })?; if res["error"] != json!(null) { @@ -683,7 +689,7 @@ impl SwapMessageSender for HttpDataSender { res["error"]["code"], res["error"]["message"] ); error!("{}", report); - return Err(ErrorKind::ClientCallback(report).into()); + return Err(Error::ClientCallback(report)); } // http call is synchronouse, so message was delivered and processes. Ack cn be granted. @@ -722,12 +728,12 @@ impl MarketplaceMessageSender for HttpDataSender { res.map_err(|e| { let report = format!("Posting swap message (is recipient listening?): {}", e); error!("{}", report); - ErrorKind::ClientCallback(report) + Error::ClientCallback(report) })?; } let res: Value = serde_json::from_str(&res_str).map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) + Error::GenericError(format!("Unable to parse respond {}, {}", res_str, e)) })?; if res["error"] != json!(null) { @@ -736,7 +742,7 @@ impl MarketplaceMessageSender for HttpDataSender { res["error"]["code"], res["error"]["message"] ); error!("{}", report); - return Err(ErrorKind::ClientCallback(report).into()); + return Err(Error::ClientCallback(report)); } // http call is synchronouse, so message was delivered and processes. Ack cn be granted. diff --git a/impls/src/adapters/libp2p_messaging.rs b/impls/src/adapters/libp2p_messaging.rs index 305b65bd7..cd280135a 100644 --- a/impls/src/adapters/libp2p_messaging.rs +++ b/impls/src/adapters/libp2p_messaging.rs @@ -14,7 +14,7 @@ use crate::grin_p2p::libp2p_connection; use crate::util::RwLock; -use crate::{Error, ErrorKind}; +use crate::Error; use chrono::Utc; use grin_wallet_libwallet::IntegrityContext; use grin_wallet_util::grin_util::secp::Secp256k1; @@ -82,11 +82,10 @@ pub fn add_broadcasting_messages( .next() .is_some() { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Message with integrity_ctx {} is already exist", integrity_ctx.tx_uuid - )) - .into()); + ))); } // we are good to add a new message @@ -168,7 +167,7 @@ pub fn add_broadcasting_messages( *BROADCASTING_RUNNUNG.write() = false; }) .map_err(|e| { - ErrorKind::GenericError(format!( + Error::GenericError(format!( "Unable to start broadcasting_messages thread, {}", e )) diff --git a/impls/src/adapters/mod.rs b/impls/src/adapters/mod.rs index 0a4853cde..c831feda6 100644 --- a/impls/src/adapters/mod.rs +++ b/impls/src/adapters/mod.rs @@ -22,7 +22,7 @@ pub use self::file::{PathToSlateGetter, PathToSlatePutter}; pub use self::http::HttpDataSender; use crate::config::{TorConfig, WalletConfig}; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::libwallet::swap::message::Message; use crate::libwallet::Slate; use crate::tor::config::complete_tor_address; @@ -168,7 +168,7 @@ pub fn create_sender( tor_config: Option, ) -> Result, Error> { let invalid = |e| { - ErrorKind::WalletComms(format!( + Error::WalletComms(format!( "Invalid wallet comm type and destination. method: {}, dest: {}, error: {}", method, dest, e )) @@ -192,9 +192,7 @@ pub fn create_sender( ), "tor" => match tor_config { None => { - return Err( - ErrorKind::WalletComms("Tor Configuration required".to_string()).into(), - ); + return Err(Error::WalletComms("Tor Configuration required".to_string())); } Some(tc) => { let dest = validate_tor_address(dest)?; @@ -228,7 +226,7 @@ pub fn create_swap_message_sender( tor_config: &TorConfig, ) -> Result, Error> { let invalid = |e| { - ErrorKind::WalletComms(format!( + Error::WalletComms(format!( "Invalid wallet comm type and destination. method: {}, dest: {}, error: {}", method, dest, e )) @@ -270,21 +268,18 @@ pub fn validate_tor_address(dest: &str) -> Result { pub fn handle_unsupported_types(method: &str) -> Error { match method { "file" => { - return ErrorKind::WalletComms( + return Error::WalletComms( "File based transactions must be performed asynchronously.".to_string(), - ) - .into(); + ); } "self" => { - return ErrorKind::WalletComms("No sender implementation for \"self\".".to_string()) - .into(); + return Error::WalletComms("No sender implementation for \"self\".".to_string()); } _ => { - return ErrorKind::WalletComms(format!( + return Error::WalletComms(format!( "Wallet comm method \"{}\" does not exist.", method - )) - .into(); + )); } } } diff --git a/impls/src/adapters/mwcmq.rs b/impls/src/adapters/mwcmq.rs index 692d82539..a05cce8ca 100644 --- a/impls/src/adapters/mwcmq.rs +++ b/impls/src/adapters/mwcmq.rs @@ -14,7 +14,7 @@ use super::types::{Address, Publisher, Subscriber, SubscriptionHandler}; use crate::adapters::types::MWCMQSAddress; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::libwallet::proof::crypto; use crate::libwallet::proof::crypto::Hex; use crate::util::Mutex; @@ -87,13 +87,12 @@ impl MwcMqsChannel { rx_slate: Receiver, secp: &Secp256k1, ) -> Result { - let des_address = MWCMQSAddress::from_str(self.des_address.as_ref()).map_err(|e| { - ErrorKind::MqsGenericError(format!("Invalid destination address, {}", e)) - })?; + let des_address = MWCMQSAddress::from_str(self.des_address.as_ref()) + .map_err(|e| Error::MqsGenericError(format!("Invalid destination address, {}", e)))?; mwcmqs_publisher .post_slate(&slate, &des_address, secp) .map_err(|e| { - ErrorKind::MqsGenericError(format!( + Error::MqsGenericError(format!( "MQS unable to transfer slate {} to the worker, {}", slate.id, e )) @@ -110,10 +109,7 @@ impl MwcMqsChannel { let slate_returned = rx_slate .recv_timeout(Duration::from_secs(120)) .map_err(|e| { - ErrorKind::MqsGenericError(format!( - "MQS unable to process slate {}, {}", - slate.id, e - )) + Error::MqsGenericError(format!("MQS unable to process slate {}, {}", slate.id, e)) })?; return Ok(slate_returned); } @@ -125,13 +121,12 @@ impl MwcMqsChannel { _rs_message: Receiver, secp: &Secp256k1, ) -> Result<(), Error> { - let des_address = MWCMQSAddress::from_str(self.des_address.as_ref()).map_err(|e| { - ErrorKind::MqsGenericError(format!("Invalid destination address, {}", e)) - })?; + let des_address = MWCMQSAddress::from_str(self.des_address.as_ref()) + .map_err(|e| Error::MqsGenericError(format!("Invalid destination address, {}", e)))?; mwcmqs_publisher .post_take(swap_message, &des_address, secp) .map_err(|e| { - ErrorKind::MqsGenericError(format!( + Error::MqsGenericError(format!( "MQS unable to transfer swap message {} to the worker, {}", swap_message.id, e )) @@ -168,11 +163,10 @@ impl SlateSender for MwcMqsChannel { mwcmqs_subscriber.reset_notification_channels(&slate.id); res } else { - return Err(ErrorKind::MqsGenericError(format!( + return Err(Error::MqsGenericError(format!( "MQS is not started, not able to send the slate {}", slate.id - )) - .into()); + ))); } } } @@ -186,11 +180,10 @@ impl SwapMessageSender for MwcMqsChannel { // MQS is async protocol, message might never be delivered, so no ack can be granted. Ok(false) } else { - return Err(ErrorKind::MqsGenericError(format!( + return Err(Error::MqsGenericError(format!( "MQS is not started, not able to send the swap message {}", message.id - )) - .into()); + ))); } } } @@ -267,12 +260,11 @@ impl Publisher for MWCMQPublisher { secp, ) .map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable to build txproof from the payload, {}", e)) + Error::MqsGenericError(format!("Unable to build txproof from the payload, {}", e)) })?; - let slate = serde_json::to_string(&slate).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable convert Slate to Json, {}", e)) - })?; + let slate = serde_json::to_string(&slate) + .map_err(|e| Error::MqsGenericError(format!("Unable convert Slate to Json, {}", e)))?; Ok(slate) } @@ -397,24 +389,30 @@ impl MWCMQSBroker { secret_key: &SecretKey, secp: &Secp256k1, ) -> Result { - let pkey = to.address.public_key()?; + let pkey = to.address.public_key().map_err(|e| { + Error::LibWallet(format!( + "Unable to parse address public key {}, {}", + to.address.public_key, e + )) + })?; let skey = secret_key.clone(); let version = slate.lowest_version(); - let slate = VersionedSlate::into_version_plain(slate.clone(), version)?; - let serde_json = serde_json::to_string(&slate).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable convert Slate to Json, {}", e)) - })?; + let slate = VersionedSlate::into_version_plain(slate.clone(), version) + .map_err(|e| Error::LibWallet(format!("Unable to process slate, {}", e)))?; + let serde_json = serde_json::to_string(&slate) + .map_err(|e| Error::MqsGenericError(format!("Unable convert Slate to Json, {}", e)))?; let message = EncryptedMessage::new(serde_json, &to.address, &pkey, &skey, secp) - .map_err(|e| ErrorKind::GenericError(format!("Unable encrypt slate, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable encrypt slate, {}", e)))?; let message_ser = &serde_json::to_string(&message).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable convert Message to Json, {}", e)) + Error::MqsGenericError(format!("Unable convert Message to Json, {}", e)) })?; let mut challenge = String::new(); challenge.push_str(&message_ser); - let signature = crypto::sign_challenge(&challenge, secret_key, secp)?; + let signature = crypto::sign_challenge(&challenge, secret_key, secp) + .map_err(|e| Error::LibWallet(format!("Unable to sign challenge, {}", e)))?; let signature = signature.to_hex(); let mser: &str = &message_ser; @@ -442,37 +440,44 @@ impl MWCMQSBroker { secp: &Secp256k1, ) -> Result<(), Error> { if !self.is_running() { - return Err(ErrorKind::ClosedListener("mwcmqs".to_string()).into()); + return Err(Error::ClosedListener("mwcmqs".to_string())); } - let pkey = to.address.public_key()?; + let pkey = to.address.public_key().map_err(|e| { + Error::LibWallet(format!( + "Unable to parse address public key {}, {}", + to.address.public_key, e + )) + })?; let skey = secret_key.clone(); let version = slate.lowest_version(); - let slate = VersionedSlate::into_version_plain(slate.clone(), version)?; + let slate = VersionedSlate::into_version_plain(slate.clone(), version) + .map_err(|e| Error::LibWallet(format!("Unable to process slate, {}", e)))?; let message = EncryptedMessage::new( serde_json::to_string(&slate).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable convert Slate to Json, {}", e)) + Error::MqsGenericError(format!("Unable convert Slate to Json, {}", e)) })?, &to.address, &pkey, &skey, secp, ) - .map_err(|e| ErrorKind::GenericError(format!("Unable encrypt slate, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable encrypt slate, {}", e)))?; let message_ser = &serde_json::to_string(&message).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable convert Message to Json, {}", e)) + Error::MqsGenericError(format!("Unable convert Message to Json, {}", e)) })?; let mut challenge = String::new(); challenge.push_str(&message_ser); - let signature = crypto::sign_challenge(&challenge, secret_key, secp)?; + let signature = crypto::sign_challenge(&challenge, secret_key, secp) + .map_err(|e| Error::LibWallet(format!("Unable to sign challenge, {}", e)))?; let signature = signature.to_hex(); let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(120)) .build() - .map_err(|e| ErrorKind::GenericError(format!("Failed to build a client, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Failed to build a client, {}", e)))?; let mser: &str = &message_ser; let fromstripped = from.get_stripped(); @@ -491,22 +496,24 @@ impl MWCMQSBroker { let response = client.post(&url).form(¶ms).send(); if !response.is_ok() { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs connection error".to_string()).into()); + return Err(Error::MqsInvalidRespose( + "mwcmqs connection error".to_string(), + )); } else { let mut response = response.unwrap(); let mut resp_str = "".to_string(); let read_resp = response.read_to_string(&mut resp_str); if !read_resp.is_ok() { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs i/o error".to_string()).into()); + return Err(Error::MqsInvalidRespose("mwcmqs i/o error".to_string())); } else { let data: Vec<&str> = resp_str.split(" ").collect(); if data.len() <= 1 { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs".to_string()).into()); + return Err(Error::MqsInvalidRespose("mwcmqs".to_string())); } else { let last_seen = data[1].parse::(); if !last_seen.is_ok() { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs".to_string()).into()); + return Err(Error::MqsInvalidRespose("mwcmqs".to_string())); } else { let last_seen = last_seen.unwrap(); if last_seen > 10000000000 { @@ -534,24 +541,29 @@ impl MWCMQSBroker { secp: &Secp256k1, ) -> Result<(), Error> { if !self.is_running() { - return Err(ErrorKind::ClosedListener("mwcmqs".to_string()).into()); + return Err(Error::ClosedListener("mwcmqs".to_string())); } - let pkey = to.address.public_key()?; + let pkey = to.address.public_key().map_err(|e| { + Error::LibWallet(format!( + "Unable to parse address public key {}, {}", + to.address.public_key, e + )) + })?; let skey = secret_key.clone(); let message = EncryptedMessage::new( serde_json::to_string(&swapmessage).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable convert Slate to Json, {}", e)) + Error::MqsGenericError(format!("Unable convert Slate to Json, {}", e)) })?, &to.address, &pkey, &skey, secp, ) - .map_err(|e| ErrorKind::GenericError(format!("Unable encrypt slate, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable encrypt slate, {}", e)))?; let message_ser = &serde_json::to_string(&message).map_err(|e| { - ErrorKind::MqsGenericError(format!("Unable to convert Swap Message to Json, {}", e)) + Error::MqsGenericError(format!("Unable to convert Swap Message to Json, {}", e)) })?; let mut challenge = String::new(); @@ -563,7 +575,7 @@ impl MWCMQSBroker { .timeout(Duration::from_secs(60)) .build() .map_err(|e| { - ErrorKind::GenericError(format!("Failed to build a client for post_take, {}", e)) + Error::GenericError(format!("Failed to build a client for post_take, {}", e)) })?; let mser: &str = &message_ser; @@ -583,26 +595,25 @@ impl MWCMQSBroker { let response = client.post(&url).form(¶ms).send(); if !response.is_ok() { - return Err(ErrorKind::MqsInvalidRespose(format!( + return Err(Error::MqsInvalidRespose(format!( "mwcmqs connection error, {:?}", response - )) - .into()); + ))); } else { let mut response = response.unwrap(); let mut resp_str = "".to_string(); let read_resp = response.read_to_string(&mut resp_str); if !read_resp.is_ok() { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs i/o error".to_string()).into()); + return Err(Error::MqsInvalidRespose("mwcmqs i/o error".to_string())); } else { let data: Vec<&str> = resp_str.split(" ").collect(); if data.len() <= 1 { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs".to_string()).into()); + return Err(Error::MqsInvalidRespose("mwcmqs".to_string())); } else { let last_seen = data[1].parse::(); if !last_seen.is_ok() { - return Err(ErrorKind::MqsInvalidRespose("mwcmqs".to_string()).into()); + return Err(Error::MqsInvalidRespose("mwcmqs".to_string())); } else { let last_seen = last_seen.unwrap(); if last_seen > 10000000000 { diff --git a/impls/src/adapters/types.rs b/impls/src/adapters/types.rs index 732ce78e2..ac60df977 100644 --- a/impls/src/adapters/types.rs +++ b/impls/src/adapters/types.rs @@ -1,5 +1,5 @@ //The following is support mqs usage in mwc713 -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use grin_wallet_libwallet::swap::message::Message; use grin_wallet_libwallet::Slate; use std::sync::mpsc::Sender; @@ -119,7 +119,7 @@ impl Address for MWCMQSAddress { let re = Regex::new(MWCMQ_ADDRESS_REGEX).unwrap(); let captures = re.captures(s); if captures.is_none() { - Err(ErrorKind::MqsGenericError(format!( + Err(Error::MqsGenericError(format!( "Unable to parse MWC address {}", s )))?; @@ -128,7 +128,7 @@ impl Address for MWCMQSAddress { let captures = captures.unwrap(); let public_key = captures .name("public_key") - .ok_or(ErrorKind::MqsGenericError(format!( + .ok_or(Error::MqsGenericError(format!( "Unable to parse MWC MQS address {}, public key part is not found", s )))? @@ -138,15 +138,14 @@ impl Address for MWCMQSAddress { let domain = captures.name("domain").map(|m| m.as_str().to_string()); let port = match captures.name("port") { Some(m) => Some(u16::from_str_radix(m.as_str(), 10).map_err(|_| { - ErrorKind::MqsGenericError(format!("Unable to parse MWC MQS port value")) + Error::MqsGenericError(format!("Unable to parse MWC MQS port value")) })?), None => None, }; Ok(MWCMQSAddress::new( - ProvableAddress::from_str(&public_key).map_err(|e| { - ErrorKind::MqsGenericError(format!("Invalid MQS address {}, {}", s, e)) - })?, + ProvableAddress::from_str(&public_key) + .map_err(|e| Error::MqsGenericError(format!("Invalid MQS address {}, {}", s, e)))?, domain, port, )) @@ -172,7 +171,7 @@ pub struct HttpsAddress { impl Address for HttpsAddress { fn from_str(s: &str) -> Result { - Url::parse(s).map_err(|_| ErrorKind::HttpsAddressParsingError(s.to_string()))?; + Url::parse(s).map_err(|_| Error::HttpsAddressParsingError(s.to_string()))?; Ok(Self { uri: s.to_string() }) } @@ -200,7 +199,7 @@ impl Display for HttpsAddress { impl dyn Address { pub fn parse(address: &str) -> Result, Error> { let re = Regex::new(ADDRESS_REGEX).map_err(|e| { - ErrorKind::AddressGenericError(format!("Unable to construct address parser, {}", e)) + Error::AddressGenericError(format!("Unable to construct address parser, {}", e)) })?; let captures = re.captures(address); if captures.is_none() { @@ -213,7 +212,7 @@ impl dyn Address { "mwcmqs" => Box::new(MWCMQSAddress::from_str(address)?), "https" => Box::new(HttpsAddress::from_str(address)?), "http" => Box::new(HttpsAddress::from_str(address)?), - x => Err(ErrorKind::UnknownAddressType(x.to_string()))?, + x => Err(Error::UnknownAddressType(x.to_string()))?, }; Ok(address) } diff --git a/impls/src/backends/lmdb.rs b/impls/src/backends/lmdb.rs index 2ae99561f..d2afa4325 100644 --- a/impls/src/backends/lmdb.rs +++ b/impls/src/backends/lmdb.rs @@ -29,8 +29,8 @@ use crate::store::{self, option_to_not_found, to_key, to_key_u64, u64_to_key}; use crate::core::core::Transaction; use crate::core::ser; use crate::libwallet::{ - swap::ethereum::EthereumWallet, AcctPathMapping, Context, Error, ErrorKind, NodeClient, - OutputData, ScannedBlockInfo, TxLogEntry, TxProof, WalletBackend, WalletOutputBatch, + swap::ethereum::EthereumWallet, AcctPathMapping, Context, Error, NodeClient, OutputData, + ScannedBlockInfo, TxLogEntry, TxProof, WalletBackend, WalletOutputBatch, }; use crate::util::secp::constants::SECRET_KEY_SIZE; use crate::util::secp::key::SecretKey; @@ -247,11 +247,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), } } @@ -289,7 +289,7 @@ where self.set_parent_key_id(a.path); Ok(()) } else { - Err(ErrorKind::UnknownAccountLabel(label).into()) + Err(Error::UnknownAccountLabel(label)) } } @@ -410,7 +410,7 @@ where match path.to_str() { Some(s) => Ok(Some(self.load_stored_tx(s)?)), - None => Err(ErrorKind::GenericError( + None => Err(Error::GenericError( "Unable to build transaction path".to_string(), ))?, } @@ -426,9 +426,9 @@ where .join(TX_SAVE_DIR) .join(filename); - let trans = self.load_stored_tx(path.to_str().ok_or( - ErrorKind::GenericError("Unable to build transaction path".to_string()), - )?)?; + let trans = self.load_stored_tx(path.to_str().ok_or(Error::GenericError( + "Unable to build transaction path".to_string(), + ))?)?; Ok(trans) }; @@ -442,7 +442,7 @@ where let mut content = String::new(); tx_f.read_to_string(&mut content)?; let tx_bin = util::from_hex(&content).map_err(|e| { - ErrorKind::StoredTransactionError(format!("Unable to decode the data, {}", e)) + Error::StoredTransactionError(format!("Unable to decode the data, {}", e)) })?; Ok(ser::deserialize( &mut &tx_bin[..], @@ -450,7 +450,7 @@ where ser::DeserializationMode::default(), ) .map_err(|e| { - ErrorKind::StoredTransactionError(format!("Unable to deserialize the data, {}", e)) + Error::StoredTransactionError(format!("Unable to deserialize the data, {}", e)) })?) } @@ -561,10 +561,9 @@ where if self.ethereum_wallet.is_some() { Ok(self.ethereum_wallet.clone().unwrap()) } else { - Err( - ErrorKind::EthereumWalletError("Ethereum Wallet Not Generated!!!".to_string()) - .into(), - ) + Err(Error::EthereumWalletError( + "Ethereum Wallet Not Generated!!!".to_string(), + )) } } } diff --git a/impls/src/client_utils/client.rs b/impls/src/client_utils/client.rs index 5d0cd8c50..4bf1d984c 100644 --- a/impls/src/client_utils/client.rs +++ b/impls/src/client_utils/client.rs @@ -16,7 +16,6 @@ use crate::core::global; use crate::util::to_base64; -use failure::{Backtrace, Context, Fail}; use grin_wallet_util::RUNTIME; use reqwest::header::{ HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, CONNECTION, CONTENT_TYPE, USER_AGENT, @@ -24,63 +23,20 @@ use reqwest::header::{ use reqwest::{ClientBuilder, Method, Proxy, RequestBuilder}; use serde::{Deserialize, Serialize}; use serde_json; -use std::fmt::{self, Display}; use std::net::SocketAddr; use std::time::Duration; use tokio::runtime::Handle; -/// Errors that can be returned by an ApiEndpoint implementation. -#[derive(Debug)] -pub struct Error { - inner: Context, -} - -#[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 = "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 for Error { - fn from(kind: ErrorKind) -> Error { - Error { - inner: Context::new(kind), - } - } -} - -impl From> for Error { - fn from(inner: Context) -> Error { - Error { inner: inner } - } -} - #[derive(Clone)] pub struct Client { client: reqwest::Client, @@ -133,13 +89,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 }) } @@ -310,7 +266,7 @@ impl Client { IN: Serialize, { let json = serde_json::to_string(input) - .map_err(|e| ErrorKind::Internal(format!("Could not serialize data to JSON, {}", e)))?; + .map_err(|e| Error::Internal(format!("Could not serialize data to JSON, {}", e)))?; self.build_request(url, Method::POST, basic_auth_key, api_secret, Some(json)) } @@ -325,7 +281,7 @@ impl Client { IN: Serialize, { let json = serde_json::to_string(input) - .map_err(|e| ErrorKind::Internal(format!("Could not serialize data to JSON, {}", e)))?; + .map_err(|e| Error::Internal(format!("Could not serialize data to JSON, {}", e)))?; self.build_request_ex(url, Method::POST, api_secret, basic_auth_key, Some(json)) } @@ -334,9 +290,8 @@ impl Client { for<'de> T: Deserialize<'de>, { let data = self.send_request(req)?; - serde_json::from_str(&data).map_err(|e| { - ErrorKind::ResponseError(format!("Cannot parse response {}, {}", data, e)).into() - }) + serde_json::from_str(&data) + .map_err(|e| Error::ResponseError(format!("Cannot parse response {}, {}", data, e))) } async fn handle_request_async(&self, req: RequestBuilder) -> Result @@ -344,9 +299,8 @@ impl Client { for<'de> T: Deserialize<'de> + Send + 'static, { let data = self.send_request_async(req).await?; - let ser = serde_json::from_str(&data).map_err(|e| { - ErrorKind::ResponseError(format!("Cannot parse response {}, {}", data, e)) - })?; + let ser = serde_json::from_str(&data) + .map_err(|e| Error::ResponseError(format!("Cannot parse response {}, {}", data, e)))?; Ok(ser) } @@ -354,11 +308,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) } diff --git a/impls/src/client_utils/json_rpc.rs b/impls/src/client_utils/json_rpc.rs index fd71ea2e5..f2bf8eb73 100644 --- a/impls/src/client_utils/json_rpc.rs +++ b/impls/src/client_utils/json_rpc.rs @@ -14,7 +14,6 @@ // Derived from https://github.com/apoelstra/rust-jsonrpc //! JSON RPC Client functionality -use failure::Fail; use serde_json; /// Builds a request @@ -98,16 +97,16 @@ impl Response { } /// A library error -#[derive(Debug, Fail, Clone)] +#[derive(Debug, thiserror::Error, Clone)] pub enum Error { /// Json error - #[fail(display = "Unable to parse json, {}", _0)] + #[error("Unable to parse json, {0}")] Json(String), /// Error response - #[fail(display = "RPC error: {:?}", _0)] + #[error("RPC error: {0:?}")] Rpc(RpcError), /// Internal generic Error - #[fail(display = "Client error: {}", _0)] + #[error("Client error: {0}")] GenericError(String), } diff --git a/impls/src/client_utils/mod.rs b/impls/src/client_utils/mod.rs index cb980116b..a747cba93 100644 --- a/impls/src/client_utils/mod.rs +++ b/impls/src/client_utils/mod.rs @@ -15,4 +15,4 @@ mod client; pub mod json_rpc; -pub use client::{Client, Error as ClientError, ErrorKind as ClientErrorKind}; +pub use client::{Client, Error as ClientError}; diff --git a/impls/src/error.rs b/impls/src/error.rs index b30a784c2..b050d7f28 100644 --- a/impls/src/error.rs +++ b/impls/src/error.rs @@ -15,253 +15,138 @@ //! Implementation specific error types 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::error::Error as StdError; -use std::fmt::{self, Display}; - -/// Error definition -#[derive(Debug)] -pub struct Error { - pub inner: Context, -} /// 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, {}", _0)] - LibTX(libtx::Error), + #[error("LibTx Error, {0}")] + LibTX(#[from] libtx::Error), /// LibWallet Error - #[fail(display = "LibWallet Error, {}", _0)] + #[error("LibWallet Error, {0}")] LibWallet(String), /// Keychain error - #[fail(display = "Keychain error, {}", _0)] - Keychain(keychain::Error), + #[error("Keychain error, {0}")] + Keychain(#[from] keychain::Error), /// Onion V3 Address Error - #[fail(display = "Onion V3 Address Error, {}", _0)] - OnionV3Address(OnionV3AddressError), + #[error("Onion V3 Address Error, {0}")] + 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, {}", _0)] + #[error("IO error, {0}")] IO(String), /// Secp Error - #[fail(display = "Secp error, {}", _0)] + #[error("Secp error, {0}")] Secp(String), /// Error when formatting json - #[fail(display = "Serde JSON error, {}", _0)] + #[error("Serde JSON error, {0}")] Format(String), /// 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?), {}", _0)] + #[error("Enc/Decryption error (check password?), {0}")] Encryption(String), /// BIP 39 word list - #[fail(display = "BIP39 Mnemonic (word list) Error, {}", _0)] + #[error("BIP39 Mnemonic (word list) Error, {0}")] Mnemonic(String), /// 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), /// API Error - #[fail(display = "Adapter Callback Error, {}", _0)] + #[error("Adapter Callback Error, {0}")] ClientCallback(String), /// Tor Configuration Error - #[fail(display = "Tor Config Error: {}", _0)] + #[error("Tor Config Error: {0}")] TorConfig(String), /// Tor Process error - #[fail(display = "Tor Process Error: {}", _0)] + #[error("Tor Process Error: {0}")] TorProcess(String), /// Error contacting wallet API - #[fail(display = "Wallet Communication Error: {}", _0)] + #[error("Wallet Communication Error: {0}")] WalletComms(String), /// Listener is closed issue - #[fail(display = "{} listener is closed! consider using `listen` first.", _0)] + #[error("{0} listener is closed! consider using `listen` first.")] ClosedListener(String), /// MQS generic error - #[fail(display = "MQS error: {}", _0)] + #[error("MQS error: {0}")] MqsGenericError(String), /// Address generic error - #[fail(display = "Address error: {}", _0)] + #[error("Address error: {0}")] AddressGenericError(String), /// Get MQS invalid response - #[fail(display = "{} Sender returned invalid response.", _0)] + #[error("{0} Sender returned invalid response.")] MqsInvalidRespose(String), /// Other - #[fail(display = "Generic error: {}", _0)] + #[error("Generic error: {0}")] GenericError(String), - #[fail(display = "unkown address!, {}", _0)] + #[error("unknown address!, {0}")] UnknownAddressType(String), - #[fail(display = "could not parse `{}` to a https address!", 0)] + #[error("could not parse `{0}` to a https address!")] HttpsAddressParsingError(String), - #[fail(display = "Swap message error, {}", _0)] + #[error("Swap message error, {0}")] SwapMessageGenericError(String), - #[fail(display = "Swap deal not found error, {}", _0)] + #[error("Swap deal not found error, {0}")] SwapDealGenericError(String), - #[fail(display = "Error in getting swap nodes info, {}", _0)] + #[error("Error in getting swap nodes info, {0}")] SwapNodesObtainError(String), - #[fail(display = "proof address mismatch {}, {}!", _0, _1)] + #[error("proof address mismatch {0}, {1}!")] ProofAddressMismatch(String, 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 for Error { - fn from(kind: ErrorKind) -> Error { - Error { - inner: Context::new(kind), - } - } -} - -impl From> for Error { - fn from(inner: Context) -> Error { - Error { inner: inner } - } -} - -impl From for Error { - fn from(error: keychain::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Keychain(error)), - } - } -} - -// we have to use e.description because of the bug at rust-secp256k1-zkp -#[allow(deprecated)] - -impl From for Error { - fn from(error: secp::Error) -> Error { - Error { - // secp::Error to_string is broken, in past biilds. - inner: Context::new(ErrorKind::Secp(format!("{}", error.description()))), - } - } -} - -#[warn(deprecated)] - -impl From for Error { - fn from(error: libwallet::Error) -> Error { - Error { - inner: Context::new(ErrorKind::LibWallet(format!("{}", error))), - } - } -} - -impl From for Error { - fn from(error: libtx::Error) -> Error { - Error { - inner: Context::new(ErrorKind::LibTX(error)), - } - } -} - -impl From for Error { - fn from(error: OnionV3AddressError) -> Error { - Error::from(ErrorKind::OnionV3Address(error)) - } -} diff --git a/impls/src/lib.rs b/impls/src/lib.rs index 2a5c5ea70..4a9df92c6 100644 --- a/impls/src/lib.rs +++ b/impls/src/lib.rs @@ -54,7 +54,7 @@ pub use crate::adapters::{ SlateSender, Subscriber, SubscriptionHandler, SwapMessageSender, }; 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; diff --git a/impls/src/lifecycle/default.rs b/impls/src/lifecycle/default.rs index afc1dffad..c9683e23c 100644 --- a/impls/src/lifecycle/default.rs +++ b/impls/src/lifecycle/default.rs @@ -21,7 +21,7 @@ use crate::config::{ use crate::core::global; use crate::keychain::Keychain; use crate::libwallet::swap::ethereum::generate_ethereum_wallet; -use crate::libwallet::{Error, ErrorKind, NodeClient, WalletBackend, WalletLCProvider}; +use crate::libwallet::{Error, NodeClient, WalletBackend, WalletLCProvider}; use crate::lifecycle::seed::WalletSeed; use crate::util::secp::key::SecretKey; use crate::util::ZeroingString; @@ -146,7 +146,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 @@ -166,7 +166,7 @@ where config_file_name.to_str().unwrap(), e ); - return Err(ErrorKind::Lifecycle(msg).into()); + return Err(Error::Lifecycle(msg)); } info!( @@ -177,13 +177,11 @@ where let mut api_secret_path = PathBuf::from(self.data_dir.clone()); api_secret_path.push(PathBuf::from(config::API_SECRET_FILE_NAME)); if !api_secret_path.exists() { - config::init_api_secret(&api_secret_path).map_err(|e| { - ErrorKind::GenericError(format!("Unable to init api secret, {}", e)) - })?; + config::init_api_secret(&api_secret_path) + .map_err(|e| Error::GenericError(format!("Unable to init api secret, {}", e)))?; } else { - config::check_api_secret(&api_secret_path).map_err(|e| { - ErrorKind::GenericError(format!("Unable to read api secret, {}", e)) - })?; + config::check_api_secret(&api_secret_path) + .map_err(|e| Error::GenericError(format!("Unable to read api secret, {}", e)))?; } Ok(()) @@ -205,7 +203,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( @@ -216,7 +214,7 @@ where test_mode, ) .map_err(|e| { - ErrorKind::Lifecycle(format!( + Error::Lifecycle(format!( "Error creating wallet seed (is mnemonic valid?), {}", e )) @@ -228,7 +226,7 @@ where 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)); } Ok(d) => d, }; @@ -254,12 +252,12 @@ 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.clone()).map_err(|e| { - ErrorKind::Lifecycle(format!( + Error::Lifecycle(format!( "Error opening wallet (is password correct?), {}", e )) @@ -291,7 +289,7 @@ where let keychain = wallet_seed .derive_keychain(global::is_floonet()) - .map_err(|e| ErrorKind::Lifecycle(format!("Error deriving keychain, {}", e)))?; + .map_err(|e| Error::Lifecycle(format!("Error deriving keychain, {}", e)))?; let mask = wallet.set_keychain(Box::new(keychain), create_mask, use_test_rng)?; self.backend = Some(Box::new(wallet)); @@ -315,7 +313,7 @@ where data_dir_name.push(wallet_data_dir.unwrap_or(GRIN_WALLET_DIR)); let data_dir_name = data_dir_name.to_str().unwrap(); let res = WalletSeed::seed_file_exists(&data_dir_name).map_err(|e| { - ErrorKind::CallbackImpl(format!("Error checking for wallet existence, {}", e)) + Error::CallbackImpl(format!("Error checking for wallet existence, {}", e)) })?; Ok(res) } @@ -330,20 +328,17 @@ where data_dir_name.push(wallet_data_dir.unwrap_or(GRIN_WALLET_DIR)); let data_dir_name = data_dir_name.to_str().unwrap(); let wallet_seed = WalletSeed::from_file(&data_dir_name, password) - .map_err(|e| ErrorKind::Lifecycle(format!("Error opening wallet seed file, {}", e)))?; + .map_err(|e| Error::Lifecycle(format!("Error opening wallet seed file, {}", e)))?; let res = wallet_seed .to_mnemonic() - .map_err(|e| ErrorKind::Lifecycle(format!("Error recovering wallet seed, {}", e)))?; + .map_err(|e| Error::Lifecycle(format!("Error recovering wallet seed, {}", e)))?; Ok(ZeroingString::from(res)) } fn validate_mnemonic(&self, mnemonic: ZeroingString) -> Result<(), Error> { match WalletSeed::from_mnemonic(mnemonic) { Ok(_) => Ok(()), - Err(e) => Err(ErrorKind::GenericError(format!( - "Validating mnemonic, {}", - e - )))?, + Err(e) => Err(Error::GenericError(format!("Validating mnemonic, {}", e)))?, } } @@ -357,7 +352,7 @@ where data_dir_name.push(wallet_data_dir.unwrap_or(GRIN_WALLET_DIR)); let data_dir_name = data_dir_name.to_str().unwrap(); WalletSeed::recover_from_phrase(data_dir_name, mnemonic, password) - .map_err(|e| ErrorKind::Lifecycle(format!("Error recovering from mnemonic, {}", e)))?; + .map_err(|e| Error::Lifecycle(format!("Error recovering from mnemonic, {}", e)))?; Ok(()) } @@ -374,24 +369,24 @@ where // get seed for later check let orig_wallet_seed = WalletSeed::from_file(&data_dir_name, old).map_err(|e| { - ErrorKind::Lifecycle(format!( + Error::Lifecycle(format!( "Error opening wallet seed file {}, {}", data_dir_name, e )) })?; let orig_mnemonic = orig_wallet_seed .to_mnemonic() - .map_err(|e| ErrorKind::Lifecycle(format!("Error recovering mnemonic, {}", e)))?; + .map_err(|e| Error::Lifecycle(format!("Error recovering mnemonic, {}", e)))?; // 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).map_err(|e| { - ErrorKind::Lifecycle(format!("Error temporarily backing up existing seed, {}", e)) + Error::Lifecycle(format!("Error temporarily backing up existing seed, {}", e)) })?; // Delete seed file WalletSeed::delete_seed_file(data_dir_name).map_err(|e| { - ErrorKind::Lifecycle(format!( + Error::Lifecycle(format!( "Unable to delete seed file {} for password change, {}", data_dir_name, e )) @@ -408,7 +403,7 @@ where info!("Wallet seed file created"); let new_wallet_seed = WalletSeed::from_file(&data_dir_name, new).map_err(|e| { - ErrorKind::Lifecycle(format!( + Error::Lifecycle(format!( "Error opening wallet seed file {}, {}", data_dir_name, e )) @@ -418,12 +413,12 @@ where 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)); } // Removing info!("Password change confirmed, removing old seed file."); fs::remove_file(backup_name) - .map_err(|e| ErrorKind::IO(format!("Failed to remove old seed file, {}", e)))?; + .map_err(|e| Error::IO(format!("Failed to remove old seed file, {}", e)))?; Ok(()) } @@ -433,13 +428,13 @@ where let data_dir_path = data_dir_name.to_str().unwrap(); warn!("Removing all wallet data from: {}", data_dir_path); fs::remove_dir_all(data_dir_name) - .map_err(|e| ErrorKind::IO(format!("Failed to remove wallet data, {}", e)))?; + .map_err(|e| Error::IO(format!("Failed to remove wallet data, {}", e)))?; Ok(()) } fn wallet_inst(&mut self) -> Result<&mut Box + 'a>, Error> { match self.backend.as_mut() { - None => Err(ErrorKind::Lifecycle("Wallet has not been opened".to_string()).into()), + None => Err(Error::Lifecycle("Wallet has not been opened".to_string())), Some(w) => Ok(w), } } diff --git a/impls/src/lifecycle/seed.rs b/impls/src/lifecycle/seed.rs index 9472c4bc9..3ef2f64ec 100644 --- a/impls/src/lifecycle/seed.rs +++ b/impls/src/lifecycle/seed.rs @@ -26,7 +26,7 @@ use util::ZeroingString; use crate::keychain::{mnemonic, Keychain}; use crate::util::{self, ToHex}; -use crate::{Error, ErrorKind}; +use crate::Error; use std::num::NonZeroU32; pub const SEED_FILE: &str = "wallet.seed"; @@ -51,17 +51,16 @@ impl WalletSeed { let res = mnemonic::to_entropy(&word_list); match res { Ok(s) => Ok(WalletSeed::from_bytes(&s)), - Err(e) => Err(ErrorKind::Mnemonic(format!( + Err(e) => Err(Error::Mnemonic(format!( "Unable to convert mnemonic passphrase into seed, {}", e - )) - .into()), + ))), } } pub fn _from_hex(hex: &str) -> Result { let bytes = util::from_hex(hex) - .map_err(|e| ErrorKind::GenericError(format!("Invalid hex {}, {}", hex, e)))?; + .map_err(|e| Error::GenericError(format!("Invalid hex {}, {}", hex, e)))?; Ok(WalletSeed::from_bytes(&bytes)) } @@ -73,9 +72,10 @@ impl WalletSeed { let result = mnemonic::from_entropy(&self.0); match result { Ok(r) => Ok(r), - Err(e) => { - Err(ErrorKind::Mnemonic(format!("Unable convert seed to menmonic, {}", e)).into()) - } + Err(e) => Err(Error::Mnemonic(format!( + "Unable convert seed to menmonic, {}", + e + ))), } } @@ -122,9 +122,8 @@ impl WalletSeed { i += 1; } path.push(backup_seed_file_name.clone()); - fs::rename(seed_file_name, backup_seed_file_name.as_str()).map_err(|e| { - ErrorKind::GenericError(format!("Unable rename wallet seed file, {}", e)) - })?; + fs::rename(seed_file_name, backup_seed_file_name.as_str()) + .map_err(|e| Error::GenericError(format!("Unable rename wallet seed file, {}", e)))?; warn!("{} backed up as {}", seed_file_name, backup_seed_file_name); Ok(backup_seed_file_name) @@ -142,23 +141,21 @@ 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 'mwc-wallet init -r'" .to_owned(), - ) - .into()); + )); } 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).map_err(|e| { - ErrorKind::Format(format!("EncryptedWalletSeed to json convert error, {}", e)) - })?; - let mut file = File::create(seed_file_path).map_err(|e| { - ErrorKind::IO(format!("Unable to crate file {}, {}", seed_file_path, e)) + Error::Format(format!("EncryptedWalletSeed to json convert error, {}", e)) })?; + let mut file = File::create(seed_file_path) + .map_err(|e| Error::IO(format!("Unable to crate file {}, {}", seed_file_path, e)))?; file.write_all(&enc_seed_json.as_bytes()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to store data to file {}, {}", seed_file_path, e )) @@ -201,14 +198,14 @@ impl WalletSeed { ) -> Result { // create directory if it doesn't exist fs::create_dir_all(data_file_dir) - .map_err(|e| ErrorKind::IO(format!("Unable create dir {}, {}", data_file_dir, e)))?; + .map_err(|e| Error::IO(format!("Unable create dir {}, {}", data_file_dir, e)))?; let seed_file_path = &format!("{}{}{}", data_file_dir, MAIN_SEPARATOR, SEED_FILE,); warn!("Generating wallet seed file at: {}", seed_file_path); let exists = WalletSeed::seed_file_exists(data_file_dir)?; if exists && !test_mode { - return Err(ErrorKind::WalletSeedExists(format!( + return Err(Error::WalletSeedExists(format!( "Wallet seed already exists at: {}", data_file_dir )))?; @@ -226,16 +223,16 @@ impl WalletSeed { if write_seed { let enc_seed = EncryptedWalletSeed::from_seed(&seed, password)?; let enc_seed_json = serde_json::to_string_pretty(&enc_seed).map_err(|e| { - ErrorKind::Format(format!( + Error::Format(format!( "EncryptedWalletSeed to json conversion error, {}", e )) })?; let mut file = File::create(seed_file_path).map_err(|e| { - ErrorKind::IO(format!("Unable to create file {}, {}", seed_file_path, e)) + Error::IO(format!("Unable to create file {}, {}", seed_file_path, e)) })?; file.write_all(&enc_seed_json.as_bytes()).map_err(|e| { - ErrorKind::IO(format!("Unable to save data to {}, {}", seed_file_path, e)) + Error::IO(format!("Unable to save data to {}, {}", seed_file_path, e)) })?; } @@ -252,25 +249,24 @@ impl WalletSeed { ) -> Result { // create directory if it doesn't exist fs::create_dir_all(data_file_dir) - .map_err(|e| ErrorKind::IO(format!("Unable to create dir {}, {}", data_file_dir, e)))?; + .map_err(|e| Error::IO(format!("Unable to create dir {}, {}", data_file_dir, e)))?; 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).map_err(|e| { - ErrorKind::IO(format!("Unable to open file {}, {}", seed_file_path, e)) - })?; + let mut file = File::open(seed_file_path) + .map_err(|e| Error::IO(format!("Unable to open file {}, {}", seed_file_path, e)))?; let mut buffer = String::new(); file.read_to_string(&mut buffer).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to read from file {}, {}", seed_file_path, e )) })?; let enc_seed: EncryptedWalletSeed = serde_json::from_str(&buffer).map_err(|e| { - ErrorKind::Format(format!( + Error::Format(format!( "Json to EncryptedWalletSeed conversion error, {}", e )) @@ -283,7 +279,7 @@ impl WalletSeed { Run \"mwc wallet init\" to initialize a new wallet.", seed_file_path ); - Err(ErrorKind::WalletSeedDoesntExist.into()) + Err(Error::WalletSeedDoesntExist) } } @@ -292,7 +288,7 @@ impl WalletSeed { if Path::new(seed_file_path).exists() { debug!("Deleting wallet seed file at: {}", seed_file_path); fs::remove_file(seed_file_path).map_err(|e| { - ErrorKind::IO(format!("Unable to remove file {}, {}", seed_file_path, e)) + Error::IO(format!("Unable to remove file {}, {}", seed_file_path, e)) })?; } Ok(()) @@ -344,7 +340,7 @@ impl EncryptedWalletSeed { aad, &mut enc_bytes, ) - .map_err(|e| ErrorKind::Encryption(format!("Seal in place error, {}", e)))?; + .map_err(|e| Error::Encryption(format!("Seal in place error, {}", e)))?; Ok(EncryptedWalletSeed { encrypted_seed: enc_bytes.to_hex(), @@ -356,11 +352,11 @@ impl EncryptedWalletSeed { /// Decrypt seed pub fn decrypt(&self, password: &str) -> Result { let mut encrypted_seed = util::from_hex(&self.encrypted_seed) - .map_err(|e| ErrorKind::Encryption(format!("Failed to convert seed HEX, {}", e)))?; + .map_err(|e| Error::Encryption(format!("Failed to convert seed HEX, {}", e)))?; let salt = util::from_hex(&self.salt) - .map_err(|e| ErrorKind::Encryption(format!("Failed to convert salt HEX, {}", e)))?; + .map_err(|e| Error::Encryption(format!("Failed to convert salt HEX, {}", e)))?; let nonce = util::from_hex(&self.nonce) - .map_err(|e| ErrorKind::Encryption(format!("Failed to convert nonce HEX, {}", e)))?; + .map_err(|e| Error::Encryption(format!("Failed to convert nonce HEX, {}", e)))?; let password = password.as_bytes(); let mut key = [0; 32]; @@ -383,7 +379,7 @@ impl EncryptedWalletSeed { aad, &mut encrypted_seed, ) - .map_err(|e| ErrorKind::Encryption(format!("Open in place error, {}", e)))?; + .map_err(|e| Error::Encryption(format!("Open in place error, {}", e)))?; for _ in 0..aead::AES_256_GCM.tag_len() { encrypted_seed.pop(); diff --git a/impls/src/node_clients/http.rs b/impls/src/node_clients/http.rs index 90a866599..72a5e80bf 100644 --- a/impls/src/node_clients/http.rs +++ b/impls/src/node_clients/http.rs @@ -31,9 +31,9 @@ use crate::util::ToHex; use super::resp_types::*; use crate::client_utils::json_rpc::*; -use failure::_core::sync::atomic::{AtomicU8, Ordering}; use grin_wallet_util::grin_api::{Libp2pMessages, Libp2pPeers}; use grin_wallet_util::RUNTIME; +use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::{Arc, RwLock}; use std::time::{Duration, Instant}; @@ -154,7 +154,7 @@ impl HTTPNodeClient { } 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), @@ -169,7 +169,7 @@ impl HTTPNodeClient { // error message is likely what user want to see... let report = format!("{}", e); error!("{}", report); - Err(libwallet::ErrorKind::ClientCallback(report).into()) + Err(libwallet::Error::ClientCallback(report)) } }, } @@ -200,7 +200,7 @@ impl HTTPNodeClient { } let report = format!("Get connected peers error {}, {}", url, e); error!("{}", report); - Err(libwallet::ErrorKind::ClientCallback(report).into()) + Err(libwallet::Error::ClientCallback(report)) } Ok(peer) => Ok(peer), } @@ -232,7 +232,7 @@ impl HTTPNodeClient { } 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(Some((r.tx_kernel, r.height, r.mmr_index))), @@ -243,7 +243,7 @@ impl 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)) } } }, @@ -336,7 +336,7 @@ impl HTTPNodeClient { 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)); } }; } @@ -350,7 +350,7 @@ impl HTTPNodeClient { } let report = format!("Outputs by id failed: {}", e); error!("{}", report); - return Err(libwallet::ErrorKind::ClientCallback(report).into()); + return Err(libwallet::Error::ClientCallback(report)); } }; @@ -362,7 +362,7 @@ impl 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( @@ -560,7 +560,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 { @@ -571,7 +571,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(( @@ -661,7 +661,7 @@ impl NodeClient for HTTPNodeClient { e ); error!("{}", report); - return Err(libwallet::ErrorKind::ClientCallback(report).into()); + return Err(libwallet::Error::ClientCallback(report)); } } } @@ -782,7 +782,7 @@ mod tests { let node_list_clone = node_list.clone(); joins.push(thread::spawn(move || { let client = HTTPNodeClient::new(node_list_clone, Some(api_secret.to_string())) - .map_err(|e| libwallet::ErrorKind::ClientCallback(format!("{}", e)))?; + .map_err(|e| libwallet::Error::ClientCallback(format!("{}", e)))?; let total_time = Instant::now(); diff --git a/impls/src/test_framework/testclient.rs b/impls/src/test_framework/testclient.rs index 76a3e2339..44dabb20c 100644 --- a/impls/src/test_framework/testclient.rs +++ b/impls/src/test_framework/testclient.rs @@ -188,7 +188,7 @@ where 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).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Error parsing Transaction, {}", e)) + libwallet::Error::ClientCallback(format!("Error parsing Transaction, {}", e)) })?; super::award_block_to_wallet( @@ -218,7 +218,7 @@ where }; let slate: SlateV3 = serde_json::from_str(&m.body).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Error parsing Transaction, {}", e)) + libwallet::Error::ClientCallback(format!("Error parsing Transaction, {}", e)) })?; let slate: Slate = { @@ -459,15 +459,14 @@ impl LocalWalletClient { }; { let p = self.proxy_tx.lock(); - p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Send TX Slate, {}", e)) - })?; + p.send(m) + .map_err(|e| libwallet::Error::ClientCallback(format!("Send TX Slate, {}", e)))?; } let r = self.rx.lock(); let m = r.recv().unwrap(); trace!("Received send_tx_slate response: {:?}", m.clone()); let slate: SlateV3 = serde_json::from_str(&m.body).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Parsing send_tx_slate response, {}", e)) + libwallet::Error::ClientCallback(format!("Parsing send_tx_slate response, {}", e)) })?; Ok(slate.to_slate(false)?) } @@ -502,9 +501,8 @@ impl NodeClient for LocalWalletClient { }; { let p = self.proxy_tx.lock(); - p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("post_tx send, {}", e)) - })?; + p.send(m) + .map_err(|e| libwallet::Error::ClientCallback(format!("post_tx send, {}", e)))?; } let r = self.rx.lock(); let m = r.recv().unwrap(); @@ -523,14 +521,14 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Get chain height send, {}", e)) + libwallet::Error::ClientCallback(format!("Get chain height send, {}", e)) })?; } let r = self.rx.lock(); let m = r.recv().unwrap(); trace!("Received get_chain_tip response: {:?}", m.clone()); let res = m.body.parse::().map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Parsing get_height response, {}", e)) + libwallet::Error::ClientCallback(format!("Parsing get_height response, {}", e)) })?; let split: Vec<&str> = res.split(",").collect(); Ok((split[0].parse::().unwrap(), split[1].to_owned(), 1)) @@ -547,14 +545,14 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Get chain header info send, {}", e)) + libwallet::Error::ClientCallback(format!("Get chain header info send, {}", e)) })?; } let r = self.rx.lock(); let m = r.recv().unwrap(); trace!("Received get_header_info response: {:?}", m.clone()); let res = m.body.parse::().map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Parsing get_header_info response, {}", e)) + libwallet::Error::ClientCallback(format!("Parsing get_header_info response, {}", e)) })?; let split: Vec<&str> = res.split(",").collect(); @@ -604,7 +602,7 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Get outputs from node send, {}", e)) + libwallet::Error::ClientCallback(format!("Get outputs from node send, {}", e)) })?; } let r = self.rx.lock(); @@ -647,7 +645,7 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!( + libwallet::Error::ClientCallback(format!( "Get outputs from node by PMMR index send, {}", e )) @@ -656,7 +654,7 @@ impl NodeClient for LocalWalletClient { let r = self.rx.lock(); let m = r.recv().unwrap(); let res: Option = serde_json::from_str(&m.body).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!("Get transaction kernels send, {}", e)) + libwallet::Error::ClientCallback(format!("Get transaction kernels send, {}", e)) })?; match res { Some(k) => Ok(Some((k.tx_kernel, k.height, k.mmr_index))), @@ -692,7 +690,7 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!( + libwallet::Error::ClientCallback(format!( "Get outputs from node by PMMR index send, {}", e )) @@ -742,7 +740,7 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!( + libwallet::Error::ClientCallback(format!( "Get outputs within height range send, {}", e )) @@ -770,10 +768,7 @@ impl NodeClient for LocalWalletClient { { let p = self.proxy_tx.lock(); p.send(m).map_err(|e| { - libwallet::ErrorKind::ClientCallback(format!( - "Get blocks by height range send, {}", - e - )) + libwallet::Error::ClientCallback(format!("Get blocks by height range send, {}", e)) })?; } diff --git a/impls/src/tor/bridge.rs b/impls/src/tor/bridge.rs index e451b71ad..834e0b9ae 100644 --- a/impls/src/tor/bridge.rs +++ b/impls/src/tor/bridge.rs @@ -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::().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 { 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::().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 { let max = arg.parse::().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 { let url = arg .parse::() - .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 { - 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 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 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 for TorBridge { "Invalid transport method: {} - must be obfs4/meek_lite/meek/snowflake", transport ); - Err(ErrorKind::TorBridge(msg).into()) + Err(Error::TorBridge(msg)) } } } diff --git a/impls/src/tor/config.rs b/impls/src/tor/config.rs index d8a2244cf..dc24ab0e0 100644 --- a/impls/src/tor/config.rs +++ b/impls/src/tor/config.rs @@ -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 crate::tor; @@ -28,8 +28,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"; @@ -42,7 +40,7 @@ const HIDDEN_SERVICES_DIR: &str = "onion_service_addresses"; fn set_permissions(file_path: &str) -> Result<(), Error> { use std::os::unix::prelude::*; fs::set_permissions(file_path, fs::Permissions::from_mode(0o700)).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to update permissions for {}, {}", file_path, e )) @@ -88,19 +86,19 @@ impl TorRcConfig { /// write to file pub fn write_to_file(&self, file_path: &str) -> Result<(), Error> { let mut file = File::create(file_path) - .map_err(|e| ErrorKind::IO(format!("Unable to create file {}, {}", file_path, e)))?; + .map_err(|e| Error::IO(format!("Unable to create file {}, {}", file_path, e)))?; for item in &self.items { file.write_all(item.name.as_bytes()).map_err(|e| { - ErrorKind::IO(format!("Unable to write into file {}, {}", file_path, e)) + Error::IO(format!("Unable to write into file {}, {}", file_path, e)) })?; file.write_all(b" ").map_err(|e| { - ErrorKind::IO(format!("Unable to write into file {}, {}", file_path, e)) + Error::IO(format!("Unable to write into file {}, {}", file_path, e)) })?; file.write_all(item.value.as_bytes()).map_err(|e| { - ErrorKind::IO(format!("Unable to write into file {}, {}", file_path, e)) + Error::IO(format!("Unable to write into file {}, {}", file_path, e)) })?; file.write_all(b"\n").map_err(|e| { - ErrorKind::IO(format!("Unable to write into file {}, {}", file_path, e)) + Error::IO(format!("Unable to write into file {}, {}", file_path, e)) })?; } Ok(()) @@ -113,18 +111,18 @@ pub fn create_onion_service_sec_key_file( ) -> Result<(), Error> { let key_file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, SEC_KEY_FILE); let mut file = File::create(key_file_path) - .map_err(|e| ErrorKind::IO(format!("Unable to create file {}, {}", key_file_path, e)))?; + .map_err(|e| Error::IO(format!("Unable to create file {}, {}", key_file_path, e)))?; // Tag is always 32 bytes, so pad with null zeroes file.write(b"== ed25519v1-secret: type0 ==\0\0\0") .map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to write into file {}, {}", key_file_path, e )) })?; let expanded_skey: ExpandedSecretKey = ExpandedSecretKey::from(sec_key); file.write_all(&expanded_skey.to_bytes()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to write into file {}, {}", key_file_path, e )) @@ -138,17 +136,17 @@ pub fn create_onion_service_pub_key_file( ) -> Result<(), Error> { let key_file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, PUB_KEY_FILE); let mut file = File::create(key_file_path) - .map_err(|e| ErrorKind::IO(format!("Unable to create file {}, {}", key_file_path, e)))?; + .map_err(|e| Error::IO(format!("Unable to create file {}, {}", key_file_path, e)))?; // Tag is always 32 bytes, so pad with null zeroes file.write(b"== ed25519v1-public: type0 ==\0\0\0") .map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to write into file {}, {}", key_file_path, e )) })?; file.write_all(pub_key.as_bytes()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Fail to write data to file {}, {}", key_file_path, e )) @@ -159,16 +157,16 @@ pub fn create_onion_service_pub_key_file( 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) - .map_err(|e| ErrorKind::IO(format!("Unable to create file {}, {}", file_path, e)))?; + .map_err(|e| Error::IO(format!("Unable to create file {}, {}", file_path, e)))?; file.write_all(&format!("{}.onion\n", hostname).as_bytes()) - .map_err(|e| ErrorKind::IO(format!("Fail to store data to file {}, {}", file_path, e)))?; + .map_err(|e| Error::IO(format!("Fail to store data to file {}, {}", file_path, e)))?; 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) - .map_err(|e| ErrorKind::IO(format!("Unable to create dir {}, {}", auth_dir_path, e)))?; + .map_err(|e| Error::IO(format!("Unable to create dir {}, {}", auth_dir_path, e)))?; Ok(()) } /// output an onion service config for the secret key, and return the address @@ -177,7 +175,7 @@ pub fn output_onion_service_config( sec_key: &SecretKey, ) -> Result { 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!( "{}{}{}{}{}", @@ -191,7 +189,7 @@ pub fn output_onion_service_config( // create directory if it doesn't exist fs::create_dir_all(&hs_dir_file_path) - .map_err(|e| ErrorKind::IO(format!("Unable to create dir {}, {}", hs_dir_file_path, e)))?; + .map_err(|e| Error::IO(format!("Unable to create dir {}, {}", hs_dir_file_path, e)))?; 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()?)?; @@ -272,7 +270,7 @@ pub fn output_tor_listener_config( // create data directory if it doesn't exist fs::create_dir_all(&tor_data_dir) - .map_err(|e| ErrorKind::IO(format!("Unable to create dir {}, {}", tor_data_dir, e)))?; + .map_err(|e| Error::IO(format!("Unable to create dir {}, {}", tor_data_dir, e)))?; let mut service_dirs = vec![]; @@ -312,7 +310,7 @@ pub fn output_tor_sender_config( ) -> Result<(), Error> { // create data directory if it doesn't exist fs::create_dir_all(&tor_config_dir) - .map_err(|e| ErrorKind::IO(format!("Unable to create dir {}, {}", tor_config_dir, e)))?; + .map_err(|e| Error::IO(format!("Unable to create dir {}, {}", tor_config_dir, e)))?; output_torrc( tor_config_dir, @@ -331,7 +329,7 @@ pub fn output_tor_sender_config( pub fn is_tor_address(input: &str) -> Result<(), Error> { match OnionV3Address::try_from(input) { Ok(_) => Ok(()), - Err(e) => Err(ErrorKind::NotOnion(format!("{}, {}", input, e)))?, + Err(e) => Err(Error::NotOnion(format!("{}, {}", input, e)))?, } } diff --git a/impls/src/tor/process.rs b/impls/src/tor/process.rs index 2102ff65a..346fb7459 100644 --- a/impls/src/tor/process.rs +++ b/impls/src/tor/process.rs @@ -49,7 +49,6 @@ extern crate chrono; extern crate regex; extern crate timer; -use failure::Fail; use regex::Regex; use std::fs::{self, File}; use std::io; @@ -66,25 +65,25 @@ const TOR_EXE_NAME: &str = "tor.exe"; #[cfg(not(windows))] const TOR_EXE_NAME: &str = "tor"; -#[derive(Fail, Debug)] +#[derive(thiserror::Error, Debug)] pub enum Error { - #[fail(display = "Tor process error, {}", _0)] + #[error("Tor process error, {0}")] Process(String), - #[fail(display = "Tor IO error, {}, {}", _0, _1)] + #[error("Tor IO error, {0}, {1}")] IO(String, io::Error), - #[fail(display = "Tor PID error, {}", _0)] + #[error("Tor PID error, {0}")] PID(String), - #[fail(display = "Tor Reported Error {}, and warnings: {:?}", _0, _1)] + #[error("Tor Reported Error {0}, and warnings: {1:?}")] Tor(String, Vec), - #[fail(display = "Tor invalid log line: {}", _0)] + #[error("Tor invalid log line: {0}")] InvalidLogLine(String), - #[fail(display = "Tor invalid bootstrap line: {}", _0)] + #[error("Tor invalid bootstrap line: {0}")] InvalidBootstrapLine(String), - #[fail(display = "Tor regex error {}, {}", _0, _1)] + #[error("Tor regex error {0}, {1}")] Regex(String, regex::Error), - #[fail(display = "Tor process not running")] + #[error("Tor process not running")] ProcessNotStarted, - #[fail(display = "Waiting for tor respond timeout")] + #[error("Waiting for tor respond timeout")] Timeout, } diff --git a/impls/src/tor/proxy.rs b/impls/src/tor/proxy.rs index 6357643ab..9e0deb254 100644 --- a/impls/src/tor/proxy.rs +++ b/impls/src/tor/proxy.rs @@ -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), 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::() - .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 for TorProxy { "Missing proxy address: {} - must be or ", transport ); - return Err(ErrorKind::TorProxy(msg).into()); + return Err(Error::TorProxy(msg).into()); } } // Missing transport type @@ -176,7 +176,7 @@ impl TryFrom for TorProxy { "Invalid proxy transport: {} - must be socks4/socks5/http(s)", transport ); - Err(ErrorKind::TorProxy(msg).into()) + Err(Error::TorProxy(msg).into()) } } } else { diff --git a/libwallet/Cargo.toml b/libwallet/Cargo.toml index da8b43688..3d9171de9 100644 --- a/libwallet/Cargo.toml +++ b/libwallet/Cargo.toml @@ -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.4" strum = "0.18" strum_macros = "0.18" +thiserror = "1" ed25519-dalek = "1.0.0-pre.4" x25519-dalek = "0.6" byteorder = "1" diff --git a/libwallet/src/address.rs b/libwallet/src/address.rs index 04a30f980..e86de4b0f 100644 --- a/libwallet/src/address.rs +++ b/libwallet/src/address.rs @@ -17,7 +17,7 @@ use crate::grin_util::from_hex; use crate::grin_util::secp::key::SecretKey; -use crate::{Error, ErrorKind}; +use crate::Error; use data_encoding::BASE32; use ed25519_dalek::PublicKey as DalekPublicKey; @@ -29,7 +29,7 @@ pub fn ed25519_keypair(sec_key: &SecretKey) -> Result<(DalekSecretKey, DalekPubl let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) { Ok(k) => k, Err(e) => { - return Err(ErrorKind::ED25519Key(format!( + return Err(Error::ED25519Key(format!( "Unable to build Dalek key, {}", e )))? @@ -41,13 +41,12 @@ pub fn ed25519_keypair(sec_key: &SecretKey) -> Result<(DalekSecretKey, DalekPubl /// Output ed25519 pubkey represented by string pub fn ed25519_parse_pubkey(pub_key: &str) -> Result { - let bytes = from_hex(pub_key).map_err(|e| { - ErrorKind::AddressDecoding(format!("Can't parse pubkey {}, {}", pub_key, e)) - })?; + let bytes = from_hex(pub_key) + .map_err(|e| Error::AddressDecoding(format!("Can't parse pubkey {}, {}", pub_key, e)))?; match DalekPublicKey::from_bytes(&bytes) { Ok(k) => Ok(k), Err(e) => { - return Err(ErrorKind::AddressDecoding(format!( + return Err(Error::AddressDecoding(format!( "Not a valid public key {}, {}", pub_key, e )))? @@ -68,7 +67,7 @@ pub fn pubkey_from_onion_v3(onion_address: &str) -> Result Result 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 { @@ -328,28 +328,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 { @@ -372,9 +369,9 @@ where K: Keychain + 'a, { if id.is_none() { - return Err( - ErrorKind::PaymentProofRetrieval("Transaction ID must be specified".into()).into(), - ); + return Err(Error::PaymentProofRetrieval( + "Transaction ID must be specified".into(), + )); } let tx_id = id.unwrap(); wallet_lock!(wallet_inst, w); @@ -389,18 +386,15 @@ where None, None, ) - .map_err(|e| ErrorKind::StoredTransactionError(format!("{}", e)))?; + .map_err(|e| Error::StoredTransactionError(format!("{}", e)))?; if txs.len() != 1 { - return Err(ErrorKind::GenericError(format!( - "Unable to find tx, {}", - tx_id - )))?; + return Err(Error::GenericError(format!("Unable to find tx, {}", tx_id)))?; } let uuid = txs[0].tx_slate_id.ok_or_else(|| { - ErrorKind::GenericError(format!("Unable to find slateId for txId, {}", tx_id)) + Error::GenericError(format!("Unable to find slateId for txId, {}", tx_id)) })?; let proof = TxProof::get_stored_tx_proof(w.get_data_file_dir(), &uuid.to_string()) - .map_err(|e| ErrorKind::TransactionHasNoProof(format!("{}", e)))?; + .map_err(|e| Error::TransactionHasNoProof(format!("{}", e)))?; return Ok(proof); } @@ -478,11 +472,10 @@ where let h = slate.height; let mut context = if args.late_lock.unwrap_or(false) { if !slate.compact_slate { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Lock later feature available only with a slatepack (compact slate) model" .to_string(), - ) - .into()); + )); } tx::create_late_lock_context( @@ -674,7 +667,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())); } } @@ -949,7 +942,7 @@ where K: Keychain + 'a, { if !perform_refresh_from_node(wallet_inst.clone(), keychain_mask, status_send_channel)? { - return Err(ErrorKind::TransactionCancellationError( + return Err(Error::TransactionCancellationError( "Can't contact running MWC node. Not Cancelling.", ))?; } @@ -1023,7 +1016,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 = { @@ -1075,7 +1068,7 @@ where )?; if tip_height == 0 { - return Err(ErrorKind::NodeNotReady)?; + return Err(Error::NodeNotReady)?; } if has_reorg { @@ -1446,7 +1439,7 @@ where if let Some(e) = slate.ttl_cutoff_height { if last_confirmed_height >= e { - return Err(ErrorKind::TransactionExpired.into()); + return Err(Error::TransactionExpired); } } Ok(()) @@ -1475,18 +1468,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(_)) => {} }; @@ -1500,7 +1491,7 @@ where &recipient_pubkey, keychain.secp(), ) - .map_err(|e| ErrorKind::TxProofVerifySignature(format!("{}", e)))?; + .map_err(|e| Error::TxProofVerifySignature(format!("{}", e)))?; let sender_pubkey = proof.sender_address.public_key()?; @@ -1510,7 +1501,7 @@ where &sender_pubkey, keychain.secp(), ) - .map_err(|e| ErrorKind::TxProofVerifySignature(format!("{}", e)))?; + .map_err(|e| Error::TxProofVerifySignature(format!("{}", e)))?; let my_address_pubkey = proofaddress::payment_proof_address_pubkey(&keychain)?; let sender_mine = my_address_pubkey == sender_pubkey; diff --git a/libwallet/src/api_impl/owner_eth.rs b/libwallet/src/api_impl/owner_eth.rs index 96b51b15b..0abaebaa3 100644 --- a/libwallet/src/api_impl/owner_eth.rs +++ b/libwallet/src/api_impl/owner_eth.rs @@ -25,8 +25,7 @@ use crate::swap::ethereum::InfuraNodeClient; use crate::swap::ethereum::*; use crate::swap::trades; use crate::swap::types::Currency; -use crate::swap::ErrorKind; -use crate::Error; +use crate::swap::Error; /// Show Wallet Info pub fn info<'a, L, C, K>( @@ -91,7 +90,7 @@ pub fn transfer<'a, L, C, K>( currency: Currency, dest: Option, amount: Option, -) -> Result<(), ErrorKind> +) -> Result<(), Error> where L: WalletLCProvider<'a, C, K>, C: NodeClient + 'a, diff --git a/libwallet/src/api_impl/owner_libp2p.rs b/libwallet/src/api_impl/owner_libp2p.rs index 720d4c230..fd54ea1f3 100644 --- a/libwallet/src/api_impl/owner_libp2p.rs +++ b/libwallet/src/api_impl/owner_libp2p.rs @@ -29,11 +29,10 @@ use crate::grin_util::secp::pedersen::Commitment; use crate::grin_util::secp::Signature; use crate::grin_util::secp::{Message, PublicKey}; use crate::internal::{keys, updater}; -use crate::swap::error::ErrorKind; use crate::types::NodeClient; -use crate::Context; use crate::{wallet_lock, WalletInst, WalletLCProvider}; -use crate::{AcctPathMapping, Error, InitTxArgs, OutputCommitMapping, OutputStatus}; +use crate::{AcctPathMapping, InitTxArgs, OutputCommitMapping, OutputStatus}; +use crate::{Context, Error}; use ed25519_dalek::PublicKey as DalekPublicKey; use grin_wallet_util::grin_util::secp::Secp256k1; use std::collections::HashMap; @@ -453,7 +452,7 @@ where let total_amount: u64 = outputs.iter().map(|o| o.output.value).sum(); let fee = tx_fee(outputs.len(), 1, 1); if total_amount <= fee { - return Err(ErrorKind::Generic("Reserved amount for Integrity fees is smaller then a transaction fee. It is impossible to move dust funds.".to_string()).into()); + return Err(Error::GenericError("Reserved amount for Integrity fees is smaller then a transaction fee. It is impossible to move dust funds.".to_string())); } let mut args = InitTxArgs::default(); diff --git a/libwallet/src/api_impl/owner_swap.rs b/libwallet/src/api_impl/owner_swap.rs index 2b47efd89..bd5f96593 100644 --- a/libwallet/src/api_impl/owner_swap.rs +++ b/libwallet/src/api_impl/owner_swap.rs @@ -23,14 +23,14 @@ use crate::grin_keychain::ExtKeychainPath; use crate::grin_keychain::{Identifier, Keychain, SwitchCommitmentType}; use crate::grin_util::to_hex; use crate::internal::selection; -use crate::swap::error::ErrorKind; +use crate::swap::error::Error; use crate::swap::fsm::state::{Input, StateEtaInfo, StateId, StateProcessRespond}; use crate::swap::message::{Message, SecondaryUpdate, Update}; use crate::swap::swap::{Swap, SwapJournalRecord}; use crate::swap::types::{Action, Currency, Network, Role, SwapTransactionsConfirmations}; use crate::swap::{trades, BuyApi, Context, SwapApi}; use crate::types::NodeClient; -use crate::{get_receive_account, owner_eth, Error}; +use crate::{get_receive_account, owner_eth}; use crate::{ wallet_lock, OutputData, OutputStatus, Slate, SwapStartArgs, TxLogEntry, TxLogEntryType, WalletBackend, WalletInst, WalletLCProvider, @@ -114,7 +114,9 @@ where let (height, _, _) = node_client.get_chain_tip()?; if height == 0 { - return Err(ErrorKind::Generic("MWC node is syncing and not ready yet".to_string()).into()); + return Err(Error::Generic( + "MWC node is syncing and not ready yet".to_string(), + )); } let mut swap_reserved_amount = 0; @@ -277,7 +279,9 @@ where swap.secondary_fee = secondary_fee; if secondary_fee <= 0.0 { - return Err(ErrorKind::Generic("Invalid secondary transaction fee".to_string()).into()); + return Err(Error::Generic( + "Invalid secondary transaction fee".to_string(), + )); } if !secondary_currency.is_btc_family() && !params.dry_run { @@ -289,7 +293,9 @@ where "WARNING. {} gases should be keeped. Now {} ethers in your ethereum wallet!", swap_reserved_gas_amount, balance_gwei ); - return Err(ErrorKind::Generic("No enough ether as gas for swap".to_string()).into()); + return Err(Error::Generic( + "No enough ether as gas for swap".to_string(), + )); } } @@ -297,11 +303,10 @@ where let _l = swap_lock.lock(); if trades::get_swap_trade(swap_id.as_str(), &skey, &*swap_lock).is_ok() { // Should be impossible, uuid suppose to be unique. But we don't want to overwrite anything - return Err(ErrorKind::TradeIoError( + return Err(Error::TradeIoError( swap_id.clone(), "This trade record already exist".to_string(), - ) - .into()); + )); } if params.dry_run { @@ -545,13 +550,13 @@ where return Ok((swap.state.clone(), Action::None)); } _ => { - return Err(ErrorKind::Generic("Non BTC family coins".to_string()).into()); + return Err(Error::Generic("Non BTC family coins".to_string())); } } } "eth_infura_project_id" => match swap.secondary_currency.is_btc_family() { true => { - return Err(ErrorKind::Generic("Not Ethereum family coins".to_string()).into()); + return Err(Error::Generic("Not Ethereum family coins".to_string())); } _ => { let eth_swap_contract_address = trades::get_eth_swap_contract_address( @@ -583,10 +588,9 @@ where }, "destination" => { if method.is_none() || destination.is_none() { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Please define both '--method' and '--dest' values".to_string(), - ) - .into()); + )); } let method = method.unwrap(); @@ -597,11 +601,10 @@ where } "secondary_address" => { if secondary_address.is_none() { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Please define '--buyer_refund_address' or '--secondary_address' values" .to_string(), - ) - .into()); + )); } let secondary_address = secondary_address.unwrap(); @@ -622,18 +625,16 @@ where } "secondary_fee" => { if secondary_fee.is_none() { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Please define '--secondary_fee' values".to_string(), - ) - .into()); + )); } let secondary_fee = secondary_fee.unwrap(); if secondary_fee <= 0.0 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Please define positive '--secondary_fee' value".to_string(), - ) - .into()); + )); } if !swap.secondary_currency.is_btc_family() { @@ -643,9 +644,9 @@ where secondary_fee, balance_gwei ); if secondary_fee > balance_gwei as f32 { - return Err( - ErrorKind::Generic("No enough ether as gas for swap".to_string()).into(), - ); + return Err(Error::Generic( + "No enough ether as gas for swap".to_string(), + )); } } @@ -655,7 +656,7 @@ where } "tag" => { if tag.is_none() { - return Err(ErrorKind::Generic("Please define '--tag' values".to_string()).into()); + return Err(Error::Generic("Please define '--tag' values".to_string())); } swap.tag = tag; @@ -711,10 +712,9 @@ where match adjust_cmd { "cancel" => { if !fsm.is_cancellable(&swap)? { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Swap Trade is not cancellable at current stage".to_string(), - ) - .into()); + )); } // Cancelling the trade @@ -734,11 +734,10 @@ where adjusted_state => { let state = StateId::from_cmd_str(adjusted_state)?; if !fsm.has_state(&state) { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "State {} is invalid for this trade", adjusted_state - )) - .into()); + ))); } swap.add_journal_message(format!("State is manually adjusted to {}", adjusted_state)); swap.state = state; @@ -804,10 +803,9 @@ where // Checking if MWC node is available let mwc_tip = node_client.get_chain_tip()?.0; if mwc_tip == 0 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Unable contact healthy MWC node. The node probably in sync process".to_string(), - ) - .into()); + )); } let swap_id = trades::import_trade(trade_file_name, &skey, &*swap_lock)?; @@ -897,11 +895,11 @@ where let tx_conf = swap_api.request_tx_confirmations(&keychain, &swap)?; if tx_conf.mwc_tip == 0 { // here the swap trade is written, there is not much what we can do - return Err(ErrorKind::Generic("Unable contact healthy MWC node. Please fix the problem and retry to restore this swap trade".to_string()).into()); + return Err(Error::Generic("Unable contact healthy MWC node. Please fix the problem and retry to restore this swap trade".to_string())); } if tx_conf.secondary_tip == 0 { // here the swap trade is written, there is not much what we can do - return Err(ErrorKind::Generic(format!("Unable contact {} ElectrumX node. Please fix the problem and retry to restore this swap trade", swap.secondary_currency)).into()); + return Err(Error::Generic(format!("Unable contact {} ElectrumX node. Please fix the problem and retry to restore this swap trade", swap.secondary_currency))); } if swap.is_seller() { @@ -1380,14 +1378,14 @@ where Action::SellerWaitingForOfferMessage | Action::SellerWaitingForInitRedeemMessage | Action::BuyerWaitingForRedeemMessage => { - let message_fn = message_file_name.ok_or(ErrorKind::Generic("Wallet is waiting for the response from the Buyer. Make sure that your wallet is online and able to receive the messages. If you are using files for messages exchange, please specify income message file name with '--message_file_name' value".to_string()))?; + let message_fn = message_file_name.ok_or(Error::Generic("Wallet is waiting for the response from the Buyer. Make sure that your wallet is online and able to receive the messages. If you are using files for messages exchange, please specify income message file name with '--message_file_name' value".to_string()))?; let mut file = File::open(message_fn.clone()).map_err(|e| { - ErrorKind::Generic(format!("Unable to open file {}, {}", message_fn, e)) + Error::Generic(format!("Unable to open file {}, {}", message_fn, e)) })?; let mut contents = String::new(); file.read_to_string(&mut contents).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to read a message from the file {}, {}", message_fn, e )) @@ -1396,11 +1394,10 @@ where let message = Message::from_json(&contents)?; if message.id != swap.id { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Message id {} doesn't match selected trade id", message.id - )) - .into()); + ))); } swap_income_message( @@ -1540,11 +1537,10 @@ where } => { //only btc family need to check refund address. if swap.secondary_currency.is_btc_family() && swap.unwrap_buyer()?.is_none() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Please specify '--buyer_refund_address' {} address for your refund", swap.secondary_currency - )) - .into()); + ))); } process_respond = fsm.process( @@ -1706,12 +1702,11 @@ where K: Keychain + 'a, { // Updating wallet state first because we need to select outputs. - let mut file = File::open(message_filename.clone()).map_err(|e| { - ErrorKind::Generic(format!("Unable to open file {}, {}", message_filename, e)) - })?; + let mut file = File::open(message_filename.clone()) + .map_err(|e| Error::Generic(format!("Unable to open file {}, {}", message_filename, e)))?; let mut contents = String::new(); file.read_to_string(&mut contents).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to read a message from the file {}, {}", message_filename, e )) @@ -1721,9 +1716,9 @@ where // but first let's check if the message type matching expected let message = Message::from_json(&contents)?; if !message.is_offer() { - return Err( - ErrorKind::Generic("Expected offer message, get different one".to_string()).into(), - ); + return Err(Error::Generic( + "Expected offer message, get different one".to_string(), + )); } swap_income_message(wallet_inst, keychain_mask, &contents, None)?; @@ -1752,7 +1747,7 @@ where K: Keychain + 'a, { let json_msg: serde_json::Value = serde_json::from_str(message) - .map_err(|e| ErrorKind::Generic(format!("Unable to parse json request, {}", e)))?; + .map_err(|e| Error::Generic(format!("Unable to parse json request, {}", e)))?; // For response we need to enumerate all swaps. Let's start from that let swap_id = trades::list_swap_trades()?; @@ -1776,9 +1771,10 @@ where let from = json_get_str(&json_msg, "from"); let offer_id = json_get_str(&json_msg, "offer_id"); if from.is_empty() || offer_id.is_empty() { - return Err( - ErrorKind::Generic(format!("Incomplete marketplace message {}", message)).into(), - ); + return Err(Error::Generic(format!( + "Incomplete marketplace message {}", + message + ))); } if ONLINE_OFFERS.read().unwrap().contains_key(&offer_id) { @@ -1797,9 +1793,10 @@ where let from = json_get_str(&json_msg, "from"); let offer_id = json_get_str(&json_msg, "offer_id"); if from.is_empty() || offer_id.is_empty() { - return Err( - ErrorKind::Generic(format!("Incomplete marketplace message {}", message)).into(), - ); + return Err(Error::Generic(format!( + "Incomplete marketplace message {}", + message + ))); } println!("Get fail_bidding message from {} for {}", from, offer_id); // Let's cancel swap if we sell. For Buy we can't cancel automatically @@ -1877,11 +1874,10 @@ where } "".to_string() } else { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "marketplace message contains unknown command {}, message: {}", command, message - )) - .into()); + ))); }; debug!("marketplace_message response: {}", response); Ok(response) @@ -1926,14 +1922,14 @@ where let ack_msg = match &message.inner { Update::None => { - return Err( - ErrorKind::Generic("Get empty message, nothing to process".to_string()).into(), - ) + return Err(Error::Generic( + "Get empty message, nothing to process".to_string(), + )) } Update::Offer(offer_update) => { // We get an offer if trades::get_swap_trade(swap_id.as_str(), &skey, &*lock).is_ok() { - return Err( ErrorKind::Generic(format!("trade with SwapID {} already exist. Probably you already processed this message", swap_id)).into()); + return Err( Error::Generic(format!("trade with SwapID {} already exist. Probably you already processed this message", swap_id))); } let mut swap_api = match offer_update.secondary_currency.is_btc_family() { @@ -2018,11 +2014,10 @@ where } } _ => { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Get unknown message group {} at 'MessageAcknowledge'", msg_id - )) - .into()) + ))) } } trades::store_swap_trade(&context, &swap, &skey, &*lock)?; diff --git a/libwallet/src/error.rs b/libwallet/src/error.rs index 15e52be34..a09057ec2 100644 --- a/libwallet/src/error.rs +++ b/libwallet/src/error.rs @@ -17,30 +17,15 @@ 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::swap::error::ErrorKind as SwapErrorKind; -use crate::util; -use failure::{Backtrace, Context, Fail}; -use std::env; -use std::error::Error as StdError; -use std::fmt::{self, Display}; +use crate::util::{self, grin_store}; use std::io; -/// Error definition -#[derive(Debug, Fail)] -pub struct Error { - inner: Context, -} - /// 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, @@ -53,256 +38,247 @@ pub enum ErrorKind { }, /// Too large slate - #[fail( - display = "Slate inputs and outputs number is more then {}. Please reduce number of outputs or reduce sending amount", - _0 - )] + #[error("Slate inputs and outputs number is more then {0}. Please reduce number of outputs or reduce sending amount")] TooLargeSlate(usize), /// Fee error - #[fail(display = "Fee Error: {}", _0)] + #[error("Fee Error: {0}")] Fee(String), /// LibTX Error - #[fail(display = "LibTx Error, {}", _0)] - LibTX(crate::grin_core::libtx::Error), + #[error("LibTx Error, {0}")] + LibTX(#[from] libtx::Error), /// Keychain error - #[fail(display = "Keychain error, {}", _0)] - Keychain(grin_keychain::Error), + #[error("Keychain error, {0}")] + Keychain(#[from] grin_keychain::Error), /// Transaction Error - #[fail(display = "Transaction error, {}", _0)] - Transaction(transaction::Error), + #[error("Transaction error, {0}")] + 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, {}", _0)] + #[error("Secp error, {0}")] Secp(String), /// Onion V3 Address Error - #[fail(display = "Onion V3 Address Error, {}", _0)] - OnionV3Address(util::OnionV3AddressError), + #[error("Onion V3 Address Error, {0}")] + OnionV3Address(#[from] util::OnionV3AddressError), /// Callback implementation error conversion - #[fail(display = "Trait Implementation error, {}", _0)] + #[error("Trait Implementation error, {0}")] CallbackImpl(String), /// 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, {}", _0)] - Deser(crate::grin_core::ser::Error), + #[error("Ser/Deserialization error, {0}")] + Deser(#[from] crate::grin_core::ser::Error), /// IO Error - #[fail(display = "I/O error, {}", _0)] + #[error("I/O error, {0}")] IO(String), /// Error when contacting a node through its API - #[fail(display = "Node API error: {}", _0)] + #[error("Node API error: {0}")] Node(String), /// Error when not found ready to process sync data node - #[fail(display = "Node not ready or not available")] + #[error("Node not ready or not available")] NodeNotReady, /// Error originating from hyper. - #[fail(display = "Hyper error, {}", _0)] + #[error("Hyper error, {0}")] Hyper(String), /// 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 = "API encryption error, {}", _0)] + #[error("API encryption 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), /// Transaction with same offset has already been received - #[fail( - display = "Transaction with offset hex string {} has already been received", - _0 - )] + #[error("Transaction with offset hex string {0} has already been received")] TransactionWithSameOffsetAlreadyReceived(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), /// Try to rename/delete unknown account - #[fail(display = "error: Account label {} doesn't exist!", _0)] + #[error("error: Account label {0} doesn't exist!")] AccountLabelNotExists(String), /// Account with can't be renamed - #[fail(display = "error: default account cannot be renamed!")] + #[error("error: default account cannot be renamed!")] AccountDefaultCannotBeRenamed, /// 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, {}", _0)] - Committed(committed::Error), + #[error("Committed Error, {0}")] + Committed(#[from] committed::Error), /// Can't parse slate version - #[fail(display = "Can't parse slate version, {}", _0)] + #[error("Can't parse slate version, {0}")] SlateVersionParse(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(String), /// Can't serialize slate - #[fail(display = "Can't Serialize slate, {}", _0)] + #[error("Can't Serialize slate, {0}")] SlateSer(String), /// Can't deserialize slate - #[fail(display = "Can't Deserialize slate, {}", _0)] + #[error("Can't Deserialize slate, {0}")] SlateDeser(String), /// Unknown slate version - #[fail(display = "Unknown Slate Version: {}", _0)] + #[error("Unknown Slate Version: {0}")] SlateVersion(u16), /// Slate Validation error - #[fail(display = "Unable to validate slate, {}", _0)] + #[error("Unable to validate slate, {0}")] SlateValidation(String), /// Attempt to use slate transaction data that doesn't exists - #[fail(display = "Get empty slate, Slate transaction required in this context")] + #[error("Get empty slate, 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, /// 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), /// Can't convert payment proof message - #[fail(display = "Can't convert payment proof message, {}", _0)] + #[error("Can't convert payment proof message, {0}")] PaymentProofMessageSer(String), /// Payment Proof address - #[fail(display = "Payment Proof address error: {}", _0)] + #[error("Payment Proof address error: {0}")] PaymentProofAddress(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, /// Stored Transaction issues - #[fail(display = "Stored transaction error, {}", _0)] + #[error("Stored transaction error, {0}")] StoredTransactionError(String), /// Claim prepare call with wrong amount value - #[fail( - display = "error: Amount specified does not match slate! slate = {} / sum = {}", - amount, sum - )] + #[error("error: Amount specified does not match slate! slate = {amount} / sum = {sum}")] AmountMismatch { /// Amount that pass as a prameter amount: u64, @@ -311,201 +287,90 @@ pub enum ErrorKind { }, /// Other - #[fail(display = "Generic error, {}", _0)] + #[error("Generic error, {0}")] GenericError(String), /// Fail to parse any type of proofable address - #[fail(display = "Unable to parse address {}", _0)] + #[error("Unable to parse address {0}")] ProofableAddressParsingError(String), /// Tx Proof error - #[fail(display = "Tx Proof error, {}", _0)] + #[error("Tx Proof error, {0}")] TxProofGenericError(String), /// Unable to verify signature for the proof - #[fail(display = "Tx Proof unable to verify signature, {}", _0)] + #[error("Tx Proof unable to verify signature, {0}")] TxProofVerifySignature(String), /// Expected destinatin address doesn't match expected value - #[fail( - display = "Tx Proof unable to verify destination address. Expected {}, found {}", - _0, _1 - )] + #[error("Tx Proof unable to verify destination address. Expected {0}, found {1}")] TxProofVerifyDestination(String, String), /// Expected sender address doesn't match expected value - #[fail( - display = "Tx Proof unable to verify sender address. Expected {}, found {}", - _0, _1 - )] + #[error("Tx Proof unable to verify sender address. Expected {0}, found {1}")] TxProofVerifySender(String, String), /// Not found Tx Proof file - #[fail(display = "transaction doesn't have a proof, file {} not found", _0)] + #[error("transaction doesn't have a proof, file {0} not found")] TransactionHasNoProof(String), /// Base58 generic error - #[fail(display = "Base58 error, {}", _0)] + #[error("Base58 error, {0}")] Base58Error(String), /// Hex conversion error - #[fail(display = "Hex conversion error, {}", _0)] + #[error("Hex conversion error, {0}")] HexError(String), /// Derive key error - #[fail(display = "Derive key error, {}", _0)] + #[error("Derive key error, {0}")] DeriveKeyError(String), /// Swap error - #[fail(display = "Swap Error , {}", _0)] + #[error("Swap Error, {0}")] SwapError(String), /// Slatepack Decoding Error - #[fail(display = "Slatepack decode error, {}", _0)] + #[error("Slatepack decode error, {0}")] SlatepackDecodeError(String), /// Slatepack Encoding Error - #[fail(display = "Slatepack encode error, {}", _0)] + #[error("Slatepack encode error, {0}")] SlatepackEncodeError(String), /// Ethereum Wallet Error - #[fail(display = "Ethereum wallet error, {}", _0)] + #[error("Ethereum wallet error, {0}")] EthereumWalletError(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), } -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 - pub fn cause(&self) -> Option<&dyn Fail> { - self.inner.cause() - } - /// get backtrace - pub fn backtrace(&self) -> Option<&Backtrace> { - self.inner.backtrace() - } -} - -impl From for Error { - fn from(kind: ErrorKind) -> Error { - Error { - inner: Context::new(kind), - } - } -} - -impl From> for Error { - fn from(inner: Context) -> Error { - Error { inner: inner } - } -} - impl From for Error { fn from(error: io::Error) -> Error { - Error { - inner: Context::new(ErrorKind::IO(format!("{}", error))), - } - } -} - -impl From for Error { - fn from(error: grin_keychain::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Keychain(error)), - } - } -} - -impl From for Error { - fn from(error: crate::grin_core::libtx::Error) -> Error { - Error { - inner: Context::new(ErrorKind::LibTX(error)), - } - } -} - -impl From for Error { - fn from(error: transaction::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Transaction(error)), - } - } -} - -impl From for Error { - fn from(error: crate::grin_core::ser::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Deser(error)), - } + Error::IO(format!("{}", error)) } } -// we have to use e.description because of the bug at rust-secp256k1-zkp -#[allow(deprecated)] - impl From for Error { fn from(error: secp::Error) -> Error { - Error { - // secp::Error to_string is broken, in past biilds. - inner: Context::new(ErrorKind::Secp(format!("{}", error.description()))), - } - } -} - -#[warn(deprecated)] - -impl From for Error { - fn from(error: committed::Error) -> Error { - Error { - inner: Context::new(ErrorKind::Committed(error)), - } + Error::Secp(format!("{}", error)) } } impl From for Error { fn from(error: grin_store::Error) -> Error { - Error::from(ErrorKind::Backend(format!("{}", error))) - } -} - -impl From for Error { - fn from(error: util::OnionV3AddressError) -> Error { - Error::from(ErrorKind::OnionV3Address(error)) + Error::Backend(format!("{}", error)) } } -impl From for Error { - fn from(error: SwapErrorKind) -> Error { - Error::from(ErrorKind::SwapError(format!("{}", error))) +impl From for Error { + fn from(error: crate::swap::error::Error) -> Error { + Error::Backend(format!("{}", error)) } } diff --git a/libwallet/src/internal/keys.rs b/libwallet/src/internal/keys.rs index 86a651365..e535d718d 100644 --- a/libwallet/src/internal/keys.rs +++ b/libwallet/src/internal/keys.rs @@ -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}; @@ -75,12 +75,12 @@ where { let label = label.to_string(); if let Some(_) = wallet.acct_path_iter().find(|l| l.label == label) { - return Err(ErrorKind::AccountLabelAlreadyExists(label.clone()).into()); + return Err(Error::AccountLabelAlreadyExists(label.clone())); } let old_label = old_label.to_string(); if old_label == "default" { - return Err(ErrorKind::AccountDefaultCannotBeRenamed.into()); + return Err(Error::AccountDefaultCannotBeRenamed); } let found = wallet @@ -93,7 +93,7 @@ where batch.rename_acct_path(accounts, &old_label, &label)?; batch.commit()?; } else { - return Err(ErrorKind::AccountLabelNotExists(old_label.clone()).into()); + return Err(Error::AccountLabelNotExists(old_label.clone())); } Ok(()) @@ -112,7 +112,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 @@ -124,7 +124,7 @@ where let id = (1..65536) .filter(|v| !acc_ids.contains(v)) .next() - .ok_or(ErrorKind::GenericError( + .ok_or(Error::GenericError( "Unable create a new account. Too many already exist".to_string(), ))?; diff --git a/libwallet/src/internal/scan.rs b/libwallet/src/internal/scan.rs index c5d831383..f3fa92269 100644 --- a/libwallet/src/internal/scan.rs +++ b/libwallet/src/internal/scan.rs @@ -34,7 +34,7 @@ use crate::internal::tx; use crate::internal::{keys, updater}; use crate::types::*; use crate::ReplayMitigationConfig; -use crate::{wallet_lock, Error, ErrorKind}; +use crate::{wallet_lock, Error}; use blake2_rfc::blake2b::blake2b; use std::cmp; use std::collections::{HashMap, HashSet}; @@ -300,12 +300,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() { @@ -661,9 +660,7 @@ where None => { non_uuid_tx_counter += 1; Uuid::from_fields(non_uuid_tx_counter, 0, 0, &temp_uuid_data) - .map_err(|e| { - ErrorKind::GenericError(format!("Unable to create UUID, {}", e)) - })? + .map_err(|e| Error::GenericError(format!("Unable to create UUID, {}", e)))? .to_string() } }; @@ -796,19 +793,19 @@ where let mut block_heights: Vec = blocks.iter().map(|b| b.header.height).collect(); block_heights.sort(); if block_heights.len() as u64 != end_height - start_height + 1 { - return Err(ErrorKind::Node("Unable to get all blocks data".to_string()))?; + return Err(Error::Node("Unable to get all blocks data".to_string()))?; } if block_heights[0] != start_height || block_heights[block_heights.len() - 1] != end_height { - return Err(ErrorKind::Node( + return Err(Error::Node( "Get not expected blocks from the node".to_string(), ))?; } if block_heights.len() > 1 { for i in 1..block_heights.len() { if block_heights[i - 1] != block_heights[i] - 1 { - return Err(ErrorKind::Node( + return Err(Error::Node( "Get duplicated blocks from the node".to_string(), ))?; } @@ -1113,11 +1110,9 @@ where client.get_outputs_from_node(&wallet_outputs_to_check)?; for (active_commit, _, _) in active_commits.values() { - let output = outputs - .get_mut(active_commit) - .ok_or(ErrorKind::GenericError( - "Node return unknown commit value".to_string(), - ))?; + let output = outputs.get_mut(active_commit).ok_or(Error::GenericError( + "Node return unknown commit value".to_string(), + ))?; if output.output.status != OutputStatus::Locked { output.output.status = OutputStatus::Locked; output.updated = true; @@ -2019,7 +2014,7 @@ where let over_commit = secp.commit_value(w_out.output.value)?; let commit = pedersen::Commitment::from_vec( util::from_hex(w_out.output.commit.as_ref().unwrap()).map_err(|e| { - ErrorKind::GenericError(format!("Output commit parse error, {}", e)) + Error::GenericError(format!("Output commit parse error, {}", e)) })?, ); t.output_commits = vec![commit.clone()]; diff --git a/libwallet/src/internal/selection.rs b/libwallet/src/internal/selection.rs index dbec984cf..f5b4960b1 100644 --- a/libwallet/src/internal/selection.rs +++ b/libwallet/src/internal/selection.rs @@ -14,7 +14,7 @@ //! Selection of inputs for building transactions -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_core::core::amount_to_hr_string; use crate::grin_core::libtx::{ build, @@ -81,12 +81,9 @@ where true, // Legacy value is true )?; 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( + "Transaction amount is too small to include fee".into(), + ))?; }; // Update the fee on the slate so we account for this when building the tx. @@ -249,10 +246,9 @@ 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()); + )); } }; // MQS type because public key is requred @@ -341,7 +337,7 @@ where } if sum != slate.amount { println!("mismatch sum = {}, amount = {}", sum, slate.amount); - return Err(ErrorKind::AmountMismatch { + return Err(Error::AmountMismatch { amount: slate.amount, sum: sum, })?; @@ -379,11 +375,10 @@ where debug_assert!(key_vec_amounts.len() == num_outputs); if slate.amount == 0 || num_outputs == 0 || key_vec_amounts.len() != num_outputs { - return Err(ErrorKind::GenericError(format!( + return Err(Error::GenericError(format!( "Unable to build transaction for amount {} and outputs number {}", slate.amount, num_outputs - )) - .into()); + ))); } let keychain = wallet.keychain(keychain_mask)?; @@ -438,7 +433,7 @@ where let commit = wallet.calc_commit_for_cache(keychain_mask, kva.1, &kva.0)?; if let Some(cm) = commit.clone() { commit_ped.push(Commitment::from_vec(util::from_hex(&cm).map_err(|e| { - ErrorKind::GenericError(format!("Output commit parse error, {}", e)) + Error::GenericError(format!("Output commit parse error, {}", e)) })?)); } commit_vec.push(commit); @@ -607,7 +602,7 @@ where ); if coins.len() + routputs + change_outputs > max_outputs { - return Err(ErrorKind::TooLargeSlate(max_outputs))?; + return Err(Error::TooLargeSlate(max_outputs))?; } // sender is responsible for setting the fee on the partial tx @@ -685,7 +680,7 @@ where } if total < amount_with_fee { - return Err(ErrorKind::NotEnoughFunds { + return Err(Error::NotEnoughFunds { available: total as u64, available_disp: amount_to_hr_string(total, true), needed: amount_with_fee as u64, @@ -696,8 +691,8 @@ 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( - format!("Transaction amount is too small to include fee").into(), + true => amount.checked_sub(fee).ok_or(Error::GenericError( + "Transaction amount is too small to include fee".into(), ))?, false => amount, }; diff --git a/libwallet/src/internal/tx.rs b/libwallet/src/internal/tx.rs index 80a72564c..4e747eeda 100644 --- a/libwallet/src/internal/tx.rs +++ b/libwallet/src/internal/tx.rs @@ -31,8 +31,8 @@ use crate::proof::proofaddress::{get_address_index, ProvableAddress}; use crate::proof::tx_proof::{push_proof_for_slate, TxProof}; use crate::slate::Slate; use crate::types::{Context, NodeClient, StoredProofInfo, TxLogEntryType, WalletBackend}; +use crate::Error; use crate::InitTxArgs; -use crate::{Error, ErrorKind}; use ed25519_dalek::Keypair as DalekKeypair; use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::SecretKey as DalekSecretKey; @@ -453,15 +453,15 @@ where None, )?; 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( @@ -516,14 +516,13 @@ 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())), }; if tx.tx_slate_id.is_none() { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Transaction doesn't have stored tx slate id".to_string(), - ) - .into()); + )); } wallet.store_tx(&format!("{}", tx.tx_slate_id.unwrap()), slate.tx_or_err()?)?; @@ -603,7 +602,7 @@ where None, )?; if tx_vec.is_empty() { - return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()).into()); + return Err(Error::TransactionDoesntExist(slate.id.to_string())); } let mut batch = wallet.batch(keychain_mask)?; for mut tx in tx_vec.into_iter() { @@ -649,7 +648,7 @@ pub fn payment_proof_message( // amount, // pedersen::Commitment::from_vec(commit_bytes.to_vec()), // DalekPublicKey::from_bytes(&sender_address_bytes) -// .map_err(|e| ErrorKind::Signature(format!("Failed to build public key, {}", e)))?, +// .map_err(|e| Error::Signature(format!("Failed to build public key, {}", e)))?, // )) //} @@ -676,7 +675,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(); @@ -715,39 +714,35 @@ where )?; 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()); + )); } }; // Normal public key is needed @@ -758,19 +753,17 @@ where )?; if p.sender_address.public_key != orig_sender_a.public_key { - 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.public_key != p.receiver_address.public_key && orig_proof_info.receiver_address.public_key != p.sender_address.public_key { - return Err(ErrorKind::PaymentProof( + return Err(Error::PaymentProof( "Recipient address on slate does not match original recipient address".to_owned(), - ) - .into()); + )); } let (current_height, _, _) = wallet.w2n_client().get_chain_tip()?; @@ -784,37 +777,36 @@ where let sig = match p.clone().receiver_signature { Some(s) => s, None => { - return Err(ErrorKind::PaymentProof( + return Err(Error::PaymentProof( "Recipient did not provide requested proof signature".to_owned(), - ) - .into()); + )); } }; //verify the proof signature if p.receiver_address.public_key.len() == 52 { let signature_ser = util::from_hex(&sig).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build signature from HEX {}, {}", &sig, e )) })?; let signature = Signature::from_der(keychain.secp(), &signature_ser).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to build signature, {}", e)) + Error::TxProofGenericError(format!("Unable to build signature, {}", e)) })?; debug!( "the receiver pubkey is {}", p.receiver_address.clone().public_key ); let receiver_pubkey = p.receiver_address.public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to get receiver address, {}", e)) + Error::TxProofGenericError(format!("Unable to get receiver address, {}", e)) })?; crypto::verify_signature(&msg, &signature, &receiver_pubkey, keychain.secp()) - .map_err(|e| ErrorKind::TxProofVerifySignature(format!("{}", e)))?; + .map_err(|e| Error::TxProofVerifySignature(format!("{}", e)))?; } else { //the signature is generated using Dalek public key let dalek_sig_vec = util::from_hex(&sig).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to deserialize tor payment proof signature, {}", e )) @@ -822,20 +814,20 @@ where let dalek_sig_vec: &[u8] = &dalek_sig_vec; let dalek_sig = DalekSignature::try_from(dalek_sig_vec).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to deserialize tor payment proof receiver signature, {}", e )) })?; let receiver_dalek_pub_key = p.receiver_address.tor_public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to deserialize tor payment proof receiver address, {}", e )) })?; if let Err(e) = receiver_dalek_pub_key.verify(&msg.as_bytes(), &dalek_sig) { - return Err(ErrorKind::PaymentProof(format!( + return Err(Error::PaymentProof(format!( "Invalid proof signature, {}", e )))?; @@ -851,7 +843,7 @@ where //this should be a tor sending let onion_address = OnionV3Address::from_private(&sender_address_secret_key.0) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to generate onion address for sender address, {}", e )) @@ -867,7 +859,7 @@ where keychain.secp(), ) .map_err(|e| { - ErrorKind::TxProofVerifySignature(format!("Cannot create tx_proof using slate, {}", e)) + Error::TxProofVerifySignature(format!("Cannot create tx_proof using slate, {}", e)) })?; debug!("tx_proof = {:?}", tx_proof); diff --git a/libwallet/src/internal/updater.rs b/libwallet/src/internal/updater.rs index 71ddf155e..afe02677e 100644 --- a/libwallet/src/internal/updater.rs +++ b/libwallet/src/internal/updater.rs @@ -18,7 +18,7 @@ use std::collections::{HashMap, HashSet}; use uuid::Uuid; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_core::consensus::reward; use crate::grin_core::core::{Output, TxKernel}; use crate::grin_core::global; @@ -104,7 +104,7 @@ where let commit = match out.commit.clone() { Some(c) => pedersen::Commitment::from_vec(util::from_hex(&c).map_err(|e| { - ErrorKind::GenericError(format!("Unable to parse HEX commit {}, {}", c, e)) + Error::GenericError(format!("Unable to parse HEX commit {}, {}", c, e)) })?), None => keychain // TODO: proper support for different switch commitment schemes .commit(out.value, &out.key_id, SwitchCommitmentType::Regular)?, diff --git a/libwallet/src/lib.rs b/libwallet/src/lib.rs index 6bbc47b7a..4db300798 100644 --- a/libwallet/src/lib.rs +++ b/libwallet/src/lib.rs @@ -27,16 +27,12 @@ use grin_wallet_util::grin_api; use grin_wallet_util::grin_core; use grin_wallet_util::grin_keychain; use grin_wallet_util::grin_p2p; -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] @@ -73,7 +69,7 @@ pub use crate::slatepack::{SlatePurpose, Slatepack, SlatepackArmor, Slatepacker} pub use bitcoin::Address as BitcoinAddress; -pub use crate::error::{Error, ErrorKind}; +pub use crate::error::Error; pub use crate::slate::{ParticipantData, ParticipantMessageData, ParticipantMessages, Slate}; pub use crate::slate_versions::{ SlateVersion, VersionedCoinbase, VersionedSlate, CURRENT_SLATE_VERSION, diff --git a/libwallet/src/proof/base58.rs b/libwallet/src/proof/base58.rs index a6081f937..fe9b64d46 100644 --- a/libwallet/src/proof/base58.rs +++ b/libwallet/src/proof/base58.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_keychain::base58; use crate::grin_util::secp::key::PublicKey; use grin_wallet_util::grin_util::secp::{ContextFlag, Secp256k1}; @@ -33,9 +33,8 @@ fn to_base58_check(data: &[u8], version: Vec) -> String { /// fn from_base58_check(data: &str, version_bytes: usize) -> Result<(Vec, Vec), Error> { - let payload: Vec = base58::from_check(data).map_err(|e| { - ErrorKind::Base58Error(format!("Unable decode base58 string {}, {}", data, e)) - })?; + let payload: Vec = base58::from_check(data) + .map_err(|e| Error::Base58Error(format!("Unable decode base58 string {}, {}", data, e)))?; Ok(( payload[..version_bytes].to_vec(), payload[version_bytes..].to_vec(), @@ -53,14 +52,13 @@ impl Base58 for PublicKey { let n_version = version_expect.len(); let (version_actual, key_bytes) = from_base58_check(str, n_version)?; if version_actual != version_expect { - return Err( - ErrorKind::Base58Error("Address belong to another network".to_string()).into(), - ); + return Err(Error::Base58Error( + "Address belong to another network".to_string(), + )); } let secp = Secp256k1::with_caps(ContextFlag::None); - PublicKey::from_slice(&secp, &key_bytes).map_err(|e| { - ErrorKind::Base58Error(format!("Unable to build key from Base58, {}", e)).into() - }) + PublicKey::from_slice(&secp, &key_bytes) + .map_err(|e| Error::Base58Error(format!("Unable to build key from Base58, {}", e))) } fn to_base58_check(&self, version: Vec) -> String { diff --git a/libwallet/src/proof/crypto.rs b/libwallet/src/proof/crypto.rs index a8399a91f..e12e35c57 100644 --- a/libwallet/src/proof/crypto.rs +++ b/libwallet/src/proof/crypto.rs @@ -17,7 +17,7 @@ use grin_wallet_util::grin_util::secp::pedersen::Commitment; use grin_wallet_util::grin_util::secp::{ContextFlag, Message, Secp256k1, Signature}; use super::base58; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_util as util; use sha2::{Digest, Sha256}; @@ -59,13 +59,13 @@ pub fn sign_challenge( /// convert to a signature from string pub fn signature_from_string(sig_str: &str, secp: &Secp256k1) -> Result { let signature_ser = util::from_hex(sig_str).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build signature from HEX {}, {}", sig_str, e )) })?; let signature = Signature::from_der(secp, &signature_ser) - .map_err(|e| ErrorKind::TxProofGenericError(format!("Unable to build signature, {}", e)))?; + .map_err(|e| Error::TxProofGenericError(format!("Unable to build signature, {}", e)))?; Ok(signature) } @@ -81,16 +81,14 @@ pub trait Hex { impl Hex for PublicKey { fn from_hex(str: &str) -> Result { - let hex = util::from_hex(str).map_err(|e| { - ErrorKind::HexError(format!("Unable convert Publi Key HEX {}, {}", str, e)) - })?; + let hex = util::from_hex(str) + .map_err(|e| Error::HexError(format!("Unable convert Publi Key HEX {}, {}", str, e)))?; let secp = Secp256k1::with_caps(ContextFlag::None); PublicKey::from_slice(&secp, &hex).map_err(|e| { - ErrorKind::HexError(format!( + Error::HexError(format!( "Unable to build public key from HEX {}, {}", str, e )) - .into() }) } @@ -102,12 +100,11 @@ impl Hex for PublicKey { impl Hex for Signature { fn from_hex(str: &str) -> Result { - let hex = util::from_hex(str).map_err(|e| { - ErrorKind::HexError(format!("Unable convert Signature HEX {}, {}", str, e)) - })?; + let hex = util::from_hex(str) + .map_err(|e| Error::HexError(format!("Unable convert Signature HEX {}, {}", str, e)))?; let secp = Secp256k1::with_caps(ContextFlag::None); Signature::from_der(&secp, &hex).map_err(|e| { - ErrorKind::HexError(format!("Unable to build Signature from HEX {}, {}", str, e)).into() + Error::HexError(format!("Unable to build Signature from HEX {}, {}", str, e)) }) } @@ -121,10 +118,10 @@ impl Hex for Signature { impl Hex for SecretKey { fn from_hex(str: &str) -> Result { let data = util::from_hex(str) - .map_err(|e| ErrorKind::HexError(format!("Unable convert key HEX, {}", e)))?; + .map_err(|e| Error::HexError(format!("Unable convert key HEX, {}", e)))?; let secp = Secp256k1::with_caps(ContextFlag::None); SecretKey::from_slice(&secp, &data) - .map_err(|e| ErrorKind::HexError(format!("Unable to build Key from HEX, {}", e)).into()) + .map_err(|e| Error::HexError(format!("Unable to build Key from HEX, {}", e))) } fn to_hex(&self) -> String { @@ -135,7 +132,7 @@ impl Hex for SecretKey { impl Hex for Commitment { fn from_hex(str: &str) -> Result { let data = util::from_hex(str).map_err(|e| { - ErrorKind::HexError(format!("Unable convert Commitment HEX {}, {}", str, e)) + Error::HexError(format!("Unable convert Commitment HEX {}, {}", str, e)) })?; Ok(Commitment::from_vec(data)) } diff --git a/libwallet/src/proof/hasher.rs b/libwallet/src/proof/hasher.rs index 4812a240d..d29351c2a 100644 --- a/libwallet/src/proof/hasher.rs +++ b/libwallet/src/proof/hasher.rs @@ -9,7 +9,7 @@ use crate::grin_keychain::Keychain; use crate::grin_keychain::SwitchCommitmentType; use crate::grin_util::secp::key::SecretKey; -use crate::{Error, ErrorKind}; +use crate::Error; type HmacSha512 = Hmac; @@ -77,13 +77,13 @@ impl BIP32Hasher for BIP32GrinboxHasher { pub fn derive_address_key(keychain: &K, index: u32) -> Result { let root = keychain .derive_key(713, &K::root_key_id(), SwitchCommitmentType::Regular) - .map_err(|e| ErrorKind::DeriveKeyError(format!("Derive key error, {}", e)))?; + .map_err(|e| Error::DeriveKeyError(format!("Derive key error, {}", e)))?; let mut hasher = BIP32GrinboxHasher::new(is_floonet()); let secp = keychain.secp(); let master = ExtendedPrivKey::new_master(secp, &mut hasher, &root.0) - .map_err(|e| ErrorKind::DeriveKeyError(format!("Derive key error, {}", e)))?; + .map_err(|e| Error::DeriveKeyError(format!("Derive key error, {}", e)))?; let private_key = master .ckd_priv(secp, &mut hasher, ChildNumber::from_normal_idx(index)) - .map_err(|e| ErrorKind::DeriveKeyError(format!("Derive key error, {}", e)))?; + .map_err(|e| Error::DeriveKeyError(format!("Derive key error, {}", e)))?; Ok(private_key.secret_key) } diff --git a/libwallet/src/proof/message.rs b/libwallet/src/proof/message.rs index 6fc047533..f82850978 100644 --- a/libwallet/src/proof/message.rs +++ b/libwallet/src/proof/message.rs @@ -18,7 +18,7 @@ use crate::grin_util::secp::Secp256k1; use rand::{thread_rng, Rng}; use super::proofaddress; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use ring::aead; use ring::pbkdf2; @@ -50,9 +50,9 @@ impl EncryptedMessage { secp: &Secp256k1, ) -> Result { let mut common_secret = receiver_public_key.clone(); - common_secret.mul_assign(&secp, secret_key).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to encrypt message, {}", e)) - })?; + common_secret + .mul_assign(&secp, secret_key) + .map_err(|e| Error::TxProofGenericError(format!("Unable to encrypt message, {}", e)))?; let common_secret_ser = common_secret.serialize_vec(secp, true); let common_secret_slice = &common_secret_ser[1..33]; @@ -68,7 +68,7 @@ impl EncryptedMessage { ); let mut enc_bytes = message.as_bytes().to_vec(); let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &key) - .map_err(|e| ErrorKind::TxProofGenericError(format!("Unable to build a key, {}", e)))?; + .map_err(|e| Error::TxProofGenericError(format!("Unable to build a key, {}", e)))?; let sealing_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key); let aad = aead::Aad::from(&[]); sealing_key @@ -77,7 +77,7 @@ impl EncryptedMessage { aad, &mut enc_bytes, ) - .map_err(|e| ErrorKind::TxProofGenericError(format!("Unable to encrypt, {}", e)))?; + .map_err(|e| Error::TxProofGenericError(format!("Unable to encrypt, {}", e)))?; Ok(EncryptedMessage { destination: destination.clone(), @@ -95,16 +95,16 @@ impl EncryptedMessage { secp: &Secp256k1, ) -> Result<[u8; 32], Error> { let salt = util::from_hex(&self.salt).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to decode salt from HEX {}, {}", self.salt, e )) })?; let mut common_secret = sender_public_key.clone(); - common_secret.mul_assign(&secp, secret_key).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Key manipulation error, {}", e)) - })?; + common_secret + .mul_assign(&secp, secret_key) + .map_err(|e| Error::TxProofGenericError(format!("Key manipulation error, {}", e)))?; let common_secret_ser = common_secret.serialize_vec(secp, true); let common_secret_slice = &common_secret_ser[1..33]; @@ -122,13 +122,13 @@ impl EncryptedMessage { /// Decrypt/verify message with a key pub fn decrypt_with_key(&self, key: &[u8; 32]) -> Result { let mut encrypted_message = util::from_hex(&self.encrypted_message).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable decode message from HEX {}, {}", self.encrypted_message, e )) })?; let nonce = util::from_hex(&self.nonce).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable decode nonce from HEX {}, {}", self.nonce, e )) @@ -137,7 +137,7 @@ impl EncryptedMessage { n.copy_from_slice(&nonce[0..12]); let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, key) - .map_err(|e| ErrorKind::TxProofGenericError(format!("Unable to build a key, {}", e)))?; + .map_err(|e| Error::TxProofGenericError(format!("Unable to build a key, {}", e)))?; let opening_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key); let aad = aead::Aad::from(&[]); let decrypted_data = opening_key @@ -147,11 +147,11 @@ impl EncryptedMessage { &mut encrypted_message, ) .map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to decrypt the message, {}", e)) + Error::TxProofGenericError(format!("Unable to decrypt the message, {}", e)) })?; let res_msg = String::from_utf8(decrypted_data.to_vec()).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Decrypted message is corrupted, {}", e)) + Error::TxProofGenericError(format!("Decrypted message is corrupted, {}", e)) })?; Ok(res_msg) } diff --git a/libwallet/src/proof/proofaddress.rs b/libwallet/src/proof/proofaddress.rs index 40ff51cec..4d28c6387 100644 --- a/libwallet/src/proof/proofaddress.rs +++ b/libwallet/src/proof/proofaddress.rs @@ -20,7 +20,6 @@ use crate::grin_util::secp::key::PublicKey; use crate::grin_util::secp::key::SecretKey; use crate::proof::crypto; use crate::proof::hasher; -use crate::ErrorKind; use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::SecretKey as DalekSecretKey; use grin_wallet_util::OnionV3Address; @@ -225,7 +224,7 @@ where { let sk = payment_proof_address_secret(keychain, address_index)?; let dalek_sk = DalekSecretKey::from_bytes(&sk.0).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to convert key to decrypt, {}", e)) + Error::SlatepackDecodeError(format!("Unable to convert key to decrypt, {}", e)) })?; Ok(dalek_sk) } @@ -242,7 +241,7 @@ where /// Build Tor public Key from the secret pub fn secret_2_tor_pub(secret: &SecretKey) -> Result { let secret = DalekSecretKey::from_bytes(&secret.0) - .map_err(|e| ErrorKind::GenericError(format!("Unable build dalek public key, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable build dalek public key, {}", e)))?; let d_pub_key: DalekPublicKey = (&secret).into(); Ok(d_pub_key) } @@ -266,9 +265,9 @@ pub fn tor_pub_2_slatepack_pub(tor_pub_key: &DalekPublicKey) -> Result 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()); diff --git a/libwallet/src/proof/tx_proof.rs b/libwallet/src/proof/tx_proof.rs index 368d50580..3b1922b63 100644 --- a/libwallet/src/proof/tx_proof.rs +++ b/libwallet/src/proof/tx_proof.rs @@ -22,7 +22,7 @@ use crate::proof::crypto::Hex; use super::crypto; use super::message::EncryptedMessage; use super::proofaddress::ProvableAddress; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::slate_versions::VersionedSlate; use crate::Slate; use ed25519_dalek::Verifier; @@ -99,7 +99,7 @@ impl TxProof { &self, secp: &Secp256k1, expected_destination: Option<&ProvableAddress>, - ) -> Result<(ProvableAddress, Slate), ErrorKind> { + ) -> Result<(ProvableAddress, Slate), Error> { let mut challenge = String::new(); challenge.push_str(self.message.as_str()); challenge.push_str(self.challenge.as_str()); @@ -113,7 +113,7 @@ impl TxProof { if tor_proof { if let Some(signature) = &self.tor_proof_signature { let dalek_sig_vec = util::from_hex(&signature).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to deserialize tor payment proof signature, {}", e )) @@ -121,20 +121,20 @@ impl TxProof { let dalek_sig = ed25519_dalek::Signature::from_bytes(dalek_sig_vec.as_ref()) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to deserialize tor payment proof receiver signature, {}", e )) })?; let receiver_dalek_pub_key = self.address.tor_public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to deserialize tor payment proof receiver address, {}", e )) })?; if let Err(e) = receiver_dalek_pub_key.verify(&challenge.as_bytes(), &dalek_sig) { - return Err(ErrorKind::PaymentProof(format!( + return Err(Error::PaymentProof(format!( "Invalid proof signature, {}", e )))?; @@ -142,16 +142,16 @@ impl TxProof { } } else { let public_key = self.address.public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key from address {}, {}", self.address, e )) })?; if let Some(signature) = &self.signature { crypto::verify_signature(&challenge, &signature, &public_key, secp) - .map_err(|e| ErrorKind::TxProofVerifySignature(format!("{}", e)))?; + .map_err(|e| Error::TxProofVerifySignature(format!("{}", e)))?; } else { - return Err(ErrorKind::TxProofVerifySignature(format!( + return Err(Error::TxProofVerifySignature(format!( "empty proof signature!" ))); } @@ -162,14 +162,14 @@ impl TxProof { //this is the newer version tx_proof encrypted_message = serde_json::from_str(&self.slate_message.clone().unwrap()) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Fail to convert Json to EncryptedMessage {}, {}", self.message, e )) })?; } else { encrypted_message = serde_json::from_str(&self.message.clone()).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Fail to convert proof message Json to EncryptedMessage {}, {}", self.message, e )) @@ -182,21 +182,21 @@ impl TxProof { if expected_destination.is_some() && destination.public_key != expected_destination.clone().unwrap().public_key { - return Err(ErrorKind::TxProofVerifyDestination( + return Err(Error::TxProofVerifyDestination( expected_destination.unwrap().public_key.clone(), destination.public_key.clone(), )); } - let mut decrypted_message = encrypted_message.decrypt_with_key(&self.key).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to decrypt message, {}", e)) - })?; + let mut decrypted_message = encrypted_message + .decrypt_with_key(&self.key) + .map_err(|e| Error::TxProofGenericError(format!("Unable to decrypt message, {}", e)))?; //the decrypted_message cloud have been appended with the _tor let mut tor_key = "tor".to_string(); if decrypted_message.ends_with("tor") { let leng = decrypted_message.len(); if leng <= 59 { - return Err(ErrorKind::TxProofGenericError(format!( + return Err(Error::TxProofGenericError(format!( "Unable to build Slate form proof message" ))); } @@ -206,24 +206,15 @@ impl TxProof { } let slate = Slate::deserialize_upgrade_plain(&decrypted_message).map_err(|e| { - ErrorKind::TxProofGenericError(format!( - "Unable to build Slate form proof message, {}", - e - )) + Error::TxProofGenericError(format!("Unable to build Slate form proof message, {}", e)) })?; //for mwc713 display purpose. the destination needs to be onion address if let Some(onion_addr) = self.tor_sender_address.clone() { if tor_key != "tor" && tor_key != onion_addr { - return Err(ErrorKind::TxProofVerifySender( - tor_key.to_string(), - onion_addr, - )); + return Err(Error::TxProofVerifySender(tor_key.to_string(), onion_addr)); } let tor_sender = ProvableAddress::from_str(&onion_addr).map_err(|e| { - ErrorKind::TxProofGenericError(format!( - "Unable to create sender onion address, {}", - e - )) + Error::TxProofGenericError(format!("Unable to create sender onion address, {}", e)) })?; Ok((tor_sender, slate)) } else { @@ -240,28 +231,27 @@ impl TxProof { secret_key: &SecretKey, expected_destination: &ProvableAddress, secp: &Secp256k1, - ) -> Result<(Slate, TxProof), ErrorKind> { + ) -> Result<(Slate, TxProof), Error> { let address = from; let signature = util::from_hex(&signature).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build signature from HEX {}, {}", signature, e )) })?; - let signature = Signature::from_der(secp, &signature).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to build signature, {}", e)) - })?; + let signature = Signature::from_der(secp, &signature) + .map_err(|e| Error::TxProofGenericError(format!("Unable to build signature, {}", e)))?; let public_key = address.public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) })?; let encrypted_message: EncryptedMessage = serde_json::from_str(&message).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build message fom HEX {}, {}", message, e )) @@ -269,7 +259,7 @@ impl TxProof { let key = encrypted_message .key(&public_key, secret_key, secp) .map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to build a signature, {}", e)) + Error::TxProofGenericError(format!("Unable to build a signature, {}", e)) })?; let proof = TxProof { @@ -301,7 +291,7 @@ impl TxProof { expected_destination: &ProvableAddress, //sender address tor_destination: Option, //tor onion address secp: &Secp256k1, - ) -> Result { + ) -> Result { if let Some(p) = slate.payment_proof.clone() { if let Some(signature) = p.receiver_signature { //build the signature from signature string: @@ -309,7 +299,7 @@ impl TxProof { let address = p.receiver_address; let _public_key = address.tor_public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build dalek public key for address {}, {}", address, e )) @@ -321,14 +311,11 @@ impl TxProof { let version = slate.lowest_version(); let slate = VersionedSlate::into_version_plain(slate.clone(), version) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( - "Slate serialization error, {}", - e - )) + Error::TxProofGenericError(format!("Slate serialization error, {}", e)) })?; let mut slate_json_with_tor = serde_json::to_string(&slate).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) @@ -341,7 +328,7 @@ impl TxProof { slate_json_with_tor, expected_destination, //this is the sender address &expected_destination.public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) @@ -349,10 +336,10 @@ impl TxProof { &secret_key, secp, ) - .map_err(|e| ErrorKind::GenericError(format!("Unable encrypt slate, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable encrypt slate, {}", e)))?; let message_ser = &serde_json::to_string(&encrypted_message).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) @@ -364,7 +351,7 @@ impl TxProof { secp, ) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build a signature, {}", e )) @@ -392,17 +379,17 @@ impl TxProof { } else { let address = p.receiver_address; let signature = util::from_hex(&signature).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build signature from HEX {}, {}", signature, e )) })?; let signature = Signature::from_der(secp, &signature).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to build signature, {}", e)) + Error::TxProofGenericError(format!("Unable to build signature, {}", e)) })?; let _public_key = address.public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) @@ -414,22 +401,19 @@ impl TxProof { let version = slate.lowest_version(); let slate = VersionedSlate::into_version_plain(slate.clone(), version) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( - "Slate serialization error, {}", - e - )) + Error::TxProofGenericError(format!("Slate serialization error, {}", e)) })?; let encrypted_message = EncryptedMessage::new( serde_json::to_string(&slate).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) })?, expected_destination, //this is the sender address when receiver wallet sends the slate back &expected_destination.public_key().map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) @@ -437,10 +421,10 @@ impl TxProof { &secret_key, secp, ) - .map_err(|e| ErrorKind::GenericError(format!("Unable encrypt slate, {}", e)))?; + .map_err(|e| Error::GenericError(format!("Unable encrypt slate, {}", e)))?; let message_ser = &serde_json::to_string(&encrypted_message).map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build public key for address {}, {}", address, e )) @@ -452,7 +436,7 @@ impl TxProof { secp, ) .map_err(|e| { - ErrorKind::TxProofGenericError(format!( + Error::TxProofGenericError(format!( "Unable to build a signature, {}", e )) @@ -477,12 +461,12 @@ impl TxProof { Ok(proof) } } else { - return Err(ErrorKind::TxProofGenericError( + return Err(Error::TxProofGenericError( "No receiver signature in payment proof in slate".to_string(), )); } } else { - return Err(ErrorKind::TxProofGenericError( + return Err(Error::TxProofGenericError( "No pyament proof in slate".to_string(), )); } @@ -514,16 +498,15 @@ impl TxProof { .join(filename); let tx_proof_file = Path::new(&path).to_path_buf(); if !tx_proof_file.exists() { - return Err(ErrorKind::TransactionHasNoProof( + return Err(Error::TransactionHasNoProof( tx_proof_file.to_str().unwrap_or(&"UNKNOWN").to_string(), - ) - .into()); + )); } let mut tx_proof_f = File::open(tx_proof_file)?; let mut content = String::new(); tx_proof_f.read_to_string(&mut content)?; Ok(serde_json::from_str(&content).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to Build TxProof from Json, {}", e)) + Error::TxProofGenericError(format!("Unable to Build TxProof from Json, {}", e)) })?) } @@ -536,7 +519,7 @@ impl TxProof { let path_buf = Path::new(&path).to_path_buf(); let mut stored_tx = File::create(path_buf)?; let proof_ser = serde_json::to_string(self).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to conver TxProof to Json, {}", e)) + Error::TxProofGenericError(format!("Unable to conver TxProof to Json, {}", e)) })?; stored_tx.write_all(&proof_ser.as_bytes())?; stored_tx.sync_all()?; @@ -646,7 +629,7 @@ fn verify_tx_proof( Error, > { let (destination, slate) = tx_proof.verify_extract(secp, None).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to extract destination and slate, {}", e)) + Error::TxProofGenericError(format!("Unable to extract destination and slate, {}", e)) })?; let inputs_ex = tx_proof.inputs.iter().collect::>(); @@ -674,9 +657,8 @@ fn verify_tx_proof( .iter() .map(|p| &p.public_blind_excess) .collect(); - let excess_sum = PublicKey::from_combination(secp, excess_parts).map_err(|e| { - ErrorKind::TxProofGenericError(format!("Unable to combine public keys, {}", e)) - })?; + let excess_sum = PublicKey::from_combination(secp, excess_parts) + .map_err(|e| Error::TxProofGenericError(format!("Unable to combine public keys, {}", e)))?; let commit_amount = secp.commit_value(tx_proof.amount)?; inputs.push(commit_amount); @@ -691,7 +673,9 @@ fn verify_tx_proof( let excess_sum_com = Secp256k1::commit_sum(secp, output_com, input_com)?; if excess_sum_com.to_pubkey(secp)? != excess_sum { - return Err(ErrorKind::TxProofGenericError("Excess sum mismatch".to_string()).into()); + return Err(Error::TxProofGenericError( + "Excess sum mismatch".to_string(), + )); } return Ok(( diff --git a/libwallet/src/slate.rs b/libwallet/src/slate.rs index 3be7153d8..4f003ce21 100644 --- a/libwallet/src/slate.rs +++ b/libwallet/src/slate.rs @@ -16,7 +16,7 @@ //! around during an interactive wallet exchange use crate::blake2::blake2b::blake2b; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_core::core::amount_to_hr_string; use crate::grin_core::core::committed::Committed; use crate::grin_core::core::transaction::{ @@ -281,7 +281,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), } } @@ -289,7 +289,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), } } @@ -315,11 +315,10 @@ impl Slate { pub fn get_lock_height_check(&self) -> Result { match self.kernel_features { 2 => Ok(self.lock_height), - _ => Err(ErrorKind::InvalidKernelFeatures(format!( + _ => Err(Error::InvalidKernelFeatures(format!( "Expected legit Lock kernel, but get kernel {} and lock_height {}", self.kernel_features, self.lock_height - )) - .into()), + ))), } } @@ -338,16 +337,15 @@ impl Slate { /// Set lock height and LockHeight Kernel type pub fn set_lock_height(&mut self, lock_height: u64) -> Result<(), Error> { if lock_height == 0 { - return Err( - ErrorKind::InvalidKernelFeatures(format!("Setting zero lock height")).into(), - ); + return Err(Error::InvalidKernelFeatures(format!( + "Setting zero lock height" + ))); } if lock_height <= self.height { - return Err(ErrorKind::InvalidKernelFeatures(format!( + return Err(Error::InvalidKernelFeatures(format!( "Lock height {} is lower then slate height {}", lock_height, self.height - )) - .into()); + ))); } self.lock_height = lock_height; self.kernel_features = 2; @@ -359,11 +357,10 @@ impl Slate { /// Currently nobody expectign to call it pub fn set_related_height(&mut self, lock_height: u64) -> Result<(), Error> { if lock_height == 0 || lock_height >= WEEK_HEIGHT { - return Err(ErrorKind::InvalidKernelFeatures(format!( + return Err(Error::InvalidKernelFeatures(format!( "Setting wrong related height {}", lock_height - )) - .into()); + ))); } self.lock_height = lock_height; self.kernel_features = 3; @@ -373,7 +370,7 @@ impl Slate { /// Attempt to find slate version pub fn parse_slate_version(slate_json: &str) -> Result { let probe: SlateVersionProbe = serde_json::from_str(slate_json).map_err(|e| { - ErrorKind::SlateVersionParse(format!( + Error::SlateVersionParse(format!( "Unable to find slate version at {}, {}", slate_json, e )) @@ -417,14 +414,14 @@ impl Slate { let v3: SlateV3 = match version { 3 => serde_json::from_str(slate_json).map_err(|e| { - ErrorKind::SlateDeser(format!( + Error::SlateDeser(format!( "Json to SlateV3 conversion failed for {}, {}", slate_json, e )) })?, 2 => { let v2: SlateV2 = serde_json::from_str(slate_json).map_err(|e| { - ErrorKind::SlateDeser(format!( + Error::SlateDeser(format!( "Json to SlateV2 conversion failed for {}, {}", slate_json, e )) @@ -433,7 +430,7 @@ impl Slate { ret.ttl_cutoff_height = ttl_cutoff_height; ret } - _ => return Err(ErrorKind::SlateVersion(version).into()), + _ => return Err(Error::SlateVersion(version)), }; Ok(v3.to_slate(true)?) } @@ -474,54 +471,55 @@ impl Slate { /// Compare two slates for send: sended and responded. Just want to check if sender didn't mess with slate pub fn compare_slates_send(send_slate: &Self, respond_slate: &Self) -> Result<(), Error> { if send_slate.id != respond_slate.id { - return Err(ErrorKind::SlateValidation("uuid mismatch".to_string()).into()); + return Err(Error::SlateValidation("uuid mismatch".to_string())); } if !send_slate.compact_slate { if send_slate.amount != respond_slate.amount { - return Err(ErrorKind::SlateValidation("amount mismatch".to_string()).into()); + return Err(Error::SlateValidation("amount mismatch".to_string())); } if send_slate.fee != respond_slate.fee { - return Err(ErrorKind::SlateValidation("fee mismatch".to_string()).into()); + return Err(Error::SlateValidation("fee mismatch".to_string())); } // Checking transaction... // Inputs must match exactly if send_slate.tx_or_err()?.body.inputs != respond_slate.tx_or_err()?.body.inputs { - return Err(ErrorKind::SlateValidation("inputs mismatch".to_string()).into()); + return Err(Error::SlateValidation("inputs mismatch".to_string())); } // Checking if participant data match each other for pat_data in &send_slate.participant_data { if !respond_slate.participant_data.contains(&pat_data) { - return Err(ErrorKind::SlateValidation( + return Err(Error::SlateValidation( "participant data mismatch".to_string(), - ) - .into()); + )); } } // Respond outputs must include send_slate's. Expected that some was added for output in &send_slate.tx_or_err()?.body.outputs { if !respond_slate.tx_or_err()?.body.outputs.contains(&output) { - return Err(ErrorKind::SlateValidation("outputs mismatch".to_string()).into()); + return Err(Error::SlateValidation("outputs mismatch".to_string())); } } // Kernels must match exactly if send_slate.tx_or_err()?.body.kernels != respond_slate.tx_or_err()?.body.kernels { - return Err(ErrorKind::SlateValidation("kernels mismatch".to_string()).into()); + return Err(Error::SlateValidation("kernels mismatch".to_string())); } } if send_slate.kernel_features != respond_slate.kernel_features { - return Err(ErrorKind::SlateValidation("kernel_features mismatch".to_string()).into()); + return Err(Error::SlateValidation( + "kernel_features mismatch".to_string(), + )); } if send_slate.lock_height != respond_slate.lock_height { - return Err(ErrorKind::SlateValidation("lock_height mismatch".to_string()).into()); + return Err(Error::SlateValidation("lock_height mismatch".to_string())); } if send_slate.height != respond_slate.height { - return Err(ErrorKind::SlateValidation("height mismatch".to_string()).into()); + return Err(Error::SlateValidation("height mismatch".to_string())); } if send_slate.ttl_cutoff_height != respond_slate.ttl_cutoff_height { - return Err(ErrorKind::SlateValidation("ttl_cutoff mismatch".to_string()).into()); + return Err(Error::SlateValidation("ttl_cutoff mismatch".to_string())); } Ok(()) @@ -530,30 +528,30 @@ impl Slate { /// Compare two slates for invoice: sended and responded. Just want to check if sender didn't mess with slate pub fn compare_slates_invoice(invoice_slate: &Self, respond_slate: &Self) -> Result<(), Error> { if invoice_slate.id != respond_slate.id { - return Err(ErrorKind::SlateValidation("uuid mismatch".to_string()).into()); + return Err(Error::SlateValidation("uuid mismatch".to_string())); } if invoice_slate.amount != respond_slate.amount { - return Err(ErrorKind::SlateValidation("amount mismatch".to_string()).into()); + return Err(Error::SlateValidation("amount mismatch".to_string())); } if invoice_slate.height != respond_slate.height { - return Err(ErrorKind::SlateValidation("height mismatch".to_string()).into()); + return Err(Error::SlateValidation("height mismatch".to_string())); } if invoice_slate.ttl_cutoff_height != respond_slate.ttl_cutoff_height { - return Err(ErrorKind::SlateValidation("ttl_cutoff mismatch".to_string()).into()); + return Err(Error::SlateValidation("ttl_cutoff mismatch".to_string())); } assert!(invoice_slate.tx_or_err()?.body.inputs.is_empty()); // Respond outputs must include original ones. Expected that some was added for output in &invoice_slate.tx_or_err()?.body.outputs { if !respond_slate.tx_or_err()?.body.outputs.contains(&output) { - return Err(ErrorKind::SlateValidation("outputs mismatch".to_string()).into()); + return Err(Error::SlateValidation("outputs mismatch".to_string())); } } // Checking if participant data match each other for pat_data in &invoice_slate.participant_data { if !respond_slate.participant_data.contains(&pat_data) { - return Err( - ErrorKind::SlateValidation("participant data mismatch".to_string()).into(), - ); + return Err(Error::SlateValidation( + "participant data mismatch".to_string(), + )); } } @@ -648,26 +646,24 @@ impl Slate { match self.kernel_features { 0 => { if self.lock_height != 0 { - return Err(ErrorKind::SlateValidation(format!("Invalid lock_height for Plain kernel feature. lock_height expected to be zero, but has {}", self.lock_height)).into()); + return Err(Error::SlateValidation(format!("Invalid lock_height for Plain kernel feature. lock_height expected to be zero, but has {}", self.lock_height))); } Ok(KernelFeatures::Plain { fee: self.build_fee()?, }) } - 1 => Err(ErrorKind::InvalidKernelFeatures( + 1 => Err(Error::InvalidKernelFeatures( "Coinbase feature is not expected at Slate".into(), - ) - .into()), + )), 2 => Ok(KernelFeatures::HeightLocked { fee: self.build_fee()?, lock_height: if self.lock_height > self.height && self.height > 0 { self.lock_height } else { - return Err(ErrorKind::SlateValidation(format!( + return Err(Error::SlateValidation(format!( "Invalid lock_height, height value is {}, but lock_height is {}", self.height, self.lock_height - )) - .into()); + ))); }, }), 3 => Ok(KernelFeatures::NoRecentDuplicate { @@ -675,14 +671,13 @@ impl Slate { relative_height: if self.lock_height < WEEK_HEIGHT { NRDRelativeHeight::new(self.lock_height)? } else { - return Err(ErrorKind::SlateValidation(format!( + return Err(Error::SlateValidation(format!( "Invalid NRD relative_height, height value is {}, limit is {}", self.lock_height, WEEK_HEIGHT - )) - .into()); + ))); }, }), - n => Err(ErrorKind::UnknownKernelFeatures(n).into()), + n => Err(Error::UnknownKernelFeatures(n)), } } @@ -762,9 +757,9 @@ impl Slate { .map(|p| &p.public_nonce) .collect(); if pub_nonces.len() == 0 { - return Err( - ErrorKind::GenericError(format!("Participant nonces cannot be empty")).into(), - ); + return Err(Error::GenericError(format!( + "Participant nonces cannot be empty" + ))); } match PublicKey::from_combination(&secp, pub_nonces) { Ok(k) => Ok(k), @@ -780,9 +775,9 @@ impl Slate { .map(|p| &p.public_blind_excess) .collect(); if pub_blinds.len() == 0 { - return Err( - ErrorKind::GenericError(format!("Participant Blind sums cannot be empty")).into(), - ); + return Err(Error::GenericError(format!( + "Participant Blind sums cannot be empty" + ))); } match PublicKey::from_combination(secp, pub_blinds) { Ok(k) => Ok(k), @@ -964,9 +959,11 @@ impl Slate { let fee = tx_fee(tx.inputs().len(), tx.outputs().len(), tx.kernels().len()); if fee > tx.fee(height) { - return Err( - ErrorKind::Fee(format!("Fee Dispute Error: {}, {}", tx.fee(height), fee,)).into(), - ); + return Err(Error::Fee(format!( + "Fee Dispute Error: {}, {}", + tx.fee(height), + fee, + ))); } if fee > self.amount + self.fee { @@ -976,7 +973,7 @@ impl Slate { amount_to_hr_string(self.amount + self.fee, false) ); info!("{}", reason); - return Err(ErrorKind::Fee(reason).into()); + return Err(Error::Fee(reason)); } Ok(()) @@ -1012,10 +1009,9 @@ impl Slate { None => { error!("verify_messages - participant message doesn't have signature. Message: \"{}\"", String::from_utf8_lossy(&msg.as_bytes()[..])); - return Err(ErrorKind::Signature( + return Err(Error::Signature( "Optional participant messages doesn't have signature".to_owned(), - ) - .into()); + )); } Some(s) => s, }; @@ -1030,10 +1026,9 @@ impl Slate { ) { error!("verify_messages - participant message doesn't match signature. Message: \"{}\"", String::from_utf8_lossy(&msg.as_bytes()[..])); - return Err(ErrorKind::Signature( + return Err(Error::Signature( "Optional participant messages do not match signatures".to_owned(), - ) - .into()); + )); } else { info!( "verify_messages - signature verified ok. Participant message: \"{}\"", diff --git a/libwallet/src/slate_versions/mod.rs b/libwallet/src/slate_versions/mod.rs index 8817e010a..669c96f8a 100644 --- a/libwallet/src/slate_versions/mod.rs +++ b/libwallet/src/slate_versions/mod.rs @@ -22,8 +22,8 @@ use crate::slate_versions::v2::{CoinbaseV2, SlateV2}; use crate::slate_versions::v3::{CoinbaseV3, SlateV3}; use crate::slatepack::SlatePurpose; use crate::types::CbData; +use crate::Error; use crate::Slatepacker; -use crate::{Error, ErrorKind}; use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::SecretKey as DalekSecretKey; use grin_wallet_util::grin_util::secp::Secp256k1; @@ -135,9 +135,7 @@ impl VersionedSlate { version: SlateVersion, ) -> Result { match version { - SlateVersion::SP => { - return Err(ErrorKind::GenericError("Slate is encrypted".to_string()).into()) - } + SlateVersion::SP => return Err(Error::GenericError("Slate is encrypted".to_string())), SlateVersion::V3B | SlateVersion::V3 => Ok(VersionedSlate::V3(slate.into())), // Left here as a reminder of what needs to be inserted on // the release of a new slate @@ -178,7 +176,7 @@ impl VersionedSlate { pub fn into_slate_plain(&self, fix_kernel: bool) -> Result { match self { VersionedSlate::SP(_) => { - return Err(ErrorKind::GenericError("Slate is encrypted".to_string()).into()) + return Err(Error::GenericError("Slate is encrypted".to_string())) } VersionedSlate::V3(s) => Ok(s.clone().to_slate(fix_kernel)?), VersionedSlate::V2(s) => { @@ -193,10 +191,10 @@ impl VersionedSlate { let str = match self { VersionedSlate::SP(s) => s.clone(), VersionedSlate::V3(s) => serde_json::to_string(&s).map_err(|e| { - ErrorKind::GenericError(format!("Failed convert SlateV3 to Json, {}", e)) + Error::GenericError(format!("Failed convert SlateV3 to Json, {}", e)) })?, VersionedSlate::V2(s) => serde_json::to_string(&s).map_err(|e| { - ErrorKind::GenericError(format!("Failed convert SlateV2 to Json, {}", e)) + Error::GenericError(format!("Failed convert SlateV2 to Json, {}", e)) })?, }; Ok(str) diff --git a/libwallet/src/slate_versions/v3.rs b/libwallet/src/slate_versions/v3.rs index 23fc2471a..b6bbfbcf6 100644 --- a/libwallet/src/slate_versions/v3.rs +++ b/libwallet/src/slate_versions/v3.rs @@ -17,7 +17,7 @@ //! * Addition of payment_proof (PaymentInfo struct) //! * Addition of a u64 ttl_cutoff_height field -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_core::core::transaction::OutputFeatures; use crate::grin_core::global; use crate::grin_core::libtx::secp_ser; @@ -106,19 +106,18 @@ fn u8_is_blank(u: &u8) -> bool { impl SlateV3 { pub fn to_slate(self, fix_kernel: bool) -> Result { if self.coin_type.unwrap_or("mwc".to_string()) != "mwc" { - return Err( - ErrorKind::SlateDeser("slate doesn't belong to MWC network".to_string()).into(), - ); + return Err(Error::SlateDeser( + "slate doesn't belong to MWC network".to_string(), + )); } if let Some(network) = self.network_type { if network != global::get_network_name() { - return Err(ErrorKind::SlateDeser(format!( + return Err(Error::SlateDeser(format!( "slate from {} network, expected {} network", network, global::get_network_name() - )) - .into()); + ))); } } @@ -482,11 +481,10 @@ impl TryFrom<&SlateV3> for SlateV2 { panic!("Slate V3 to V2 conversion error. V2 doesn't support compact model"); } if !(*kernel_features == 0 || *kernel_features == 2) { - return Err(ErrorKind::SlateInvalidDowngrade(format!( + return Err(Error::SlateInvalidDowngrade(format!( "Only plain or height lock kernel features are supported, get {}", *kernel_features - )) - .into()); + ))); } let num_participants = *num_participants; @@ -508,10 +506,9 @@ impl TryFrom<&SlateV3> for SlateV2 { let tx = match tx { Some(t) => TransactionV2::from(t), None => { - return Err(ErrorKind::SlateInvalidDowngrade( + return Err(Error::SlateInvalidDowngrade( "Full transaction info required".to_owned(), - ) - .into()) + )) } }; Ok(SlateV2 { diff --git a/libwallet/src/slatepack/armor.rs b/libwallet/src/slatepack/armor.rs index f5c85501a..7177af7a9 100644 --- a/libwallet/src/slatepack/armor.rs +++ b/libwallet/src/slatepack/armor.rs @@ -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::grin_core::global::max_tx_weight; use regex::Regex; use sha2::{Digest, Sha256}; @@ -79,7 +79,7 @@ impl SlatepackArmor { // Get the length of the header let header_len = header_bytes.len() + 1; if armor_bytes.len() <= header_len { - return Err(ErrorKind::SlatepackDecodeError("Bad armor header".to_string()).into()); + return Err(Error::SlatepackDecodeError("Bad armor header".to_string())); } // Skip the length of the header to read for the payload until the next period let payload_bytes = armor_bytes[header_len as usize..] @@ -92,7 +92,7 @@ impl SlatepackArmor { // Get footer bytes and verify them let consumed_bytes = header_len + payload_len + 1; if armor_bytes.len() <= consumed_bytes { - return Err(ErrorKind::SlatepackDecodeError("Bad armor content".to_string()).into()); + return Err(Error::SlatepackDecodeError("Bad armor content".to_string())); } let footer_bytes = armor_bytes[consumed_bytes as usize..] .iter() @@ -101,10 +101,9 @@ impl SlatepackArmor { .collect::>(); let fenc = check_footer(&footer_bytes)?; if henc != fenc { - return Err(ErrorKind::SlatepackDecodeError( + return Err(Error::SlatepackDecodeError( "Non matched armor header and footer".to_string(), - ) - .into()); + )); } // Clean up the payload bytes to be deserialized let clean_payload = payload_bytes @@ -115,7 +114,7 @@ impl SlatepackArmor { // Decode payload from base58 let base_decode = bs58::decode(&clean_payload) .into_vec() - .map_err(|_| ErrorKind::SlatepackDecodeError("Invalid armored data".into()))?; + .map_err(|_| Error::SlatepackDecodeError("Invalid armored data".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 @@ -142,36 +141,35 @@ fn error_check(error_code: &[u8], slate_bytes: &[u8]) -> Result<(), Error> { if error_code.iter().eq(new_check.iter()) { Ok(()) } else { - Err(ErrorKind::SlatepackDecodeError( + Err(Error::SlatepackDecodeError( "Invalid armored data, 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 { let framing = str::from_utf8(header) - .map_err(|_| ErrorKind::SlatepackDecodeError("Bad bytes at armored data".into()))?; + .map_err(|_| Error::SlatepackDecodeError("Bad bytes at armored data".into()))?; if HEADER_REGEX_ENC.is_match(framing) { Ok(true) } else if HEADER_REGEX_BIN.is_match(framing) { Ok(false) } else { - Err(ErrorKind::SlatepackDecodeError("Bad armor header".to_string()).into()) + Err(Error::SlatepackDecodeError("Bad armor header".to_string())) } } // Checks footer framing bytes and returns an error if they are invalid fn check_footer(footer: &[u8]) -> Result { let framing = str::from_utf8(footer) - .map_err(|_| ErrorKind::SlatepackDecodeError("Bad bytes at armored data".into()))?; + .map_err(|_| Error::SlatepackDecodeError("Bad bytes at armored data".into()))?; if FOOTER_REGEX_ENC.is_match(framing) { Ok(true) } else if FOOTER_REGEX_BIN.is_match(framing) { Ok(false) } else { - Err(ErrorKind::SlatepackDecodeError("Bad armor footer".to_string()).into()) + Err(Error::SlatepackDecodeError("Bad armor footer".to_string())) } } diff --git a/libwallet/src/slatepack/slatepack.rs b/libwallet/src/slatepack/slatepack.rs index 85fa54c2b..55d0e2a60 100644 --- a/libwallet/src/slatepack/slatepack.rs +++ b/libwallet/src/slatepack/slatepack.rs @@ -18,8 +18,7 @@ use std::convert::TryInto; use crate::grin_util::secp::key::PublicKey; -use crate::{Error, ErrorKind}; -use crate::{ParticipantData, Slate, SlateVersion}; +use crate::{Error, ParticipantData, Slate, SlateVersion}; use crate::proof::proofaddress::ProvableAddress; use std::io; @@ -85,11 +84,10 @@ impl SlatePurpose { 3 => SlatePurpose::InvoiceResponse, 4 => SlatePurpose::FullSlate, _ => { - return Err(ErrorKind::SlatepackDecodeError(format!( + return Err(Error::SlatepackDecodeError(format!( "SlatePackPurpose wrong value {}", i - )) - .into()) + ))) } }; Ok(res) @@ -132,9 +130,9 @@ impl Slatepack { secp: &Secp256k1, ) -> Result { if encrypted && data.len() < SLATE_PACK_PLAIN_DATA_SIZE { - return Err( - ErrorKind::SlatepackDecodeError("Slatapack data is too short".to_string()).into(), - ); + return Err(Error::SlatepackDecodeError( + "Slatapack data is too short".to_string(), + )); } let mut digest = crc32::Digest::new(crc32::IEEE); @@ -145,9 +143,9 @@ impl Slatepack { let mut r = BitReader::endian(data.as_slice(), BigEndian); let version: u8 = r.read(8)?; if version != 0 { - return Err( - ErrorKind::SlatepackDecodeError("Wrong slatepack version".to_string()).into(), - ); + return Err(Error::SlatepackDecodeError( + "Wrong slatepack version".to_string(), + )); } let (payload, sender, recipient) = if encrypted { @@ -156,19 +154,13 @@ impl Slatepack { let mut data: [u8; 32] = [0; 32]; r.read_bytes(&mut data)?; let sender = DalekPublicKey::from_bytes(&data).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!( - "Unable to read a sender public key, {}", - e - )) + Error::SlatepackDecodeError(format!("Unable to read a sender public key, {}", e)) })?; // Receiver address, so this wallet open the message if it is in the archive let mut data: [u8; 32] = [0; 32]; r.read_bytes(&mut data)?; let recipient = DalekPublicKey::from_bytes(&data).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!( - "Unable to read a sender public key, {}", - e - )) + Error::SlatepackDecodeError(format!("Unable to read a sender public key, {}", e)) })?; let mut nonce: [u8; 12] = [0; 12]; @@ -202,10 +194,9 @@ impl Slatepack { let read_crc32: u32 = crc_reader.read(32)?; let data_crc32 = digest.sum32(); if read_crc32 != data_crc32 { - return Err(ErrorKind::SlatepackDecodeError( + return Err(Error::SlatepackDecodeError( "Slatepack content is not consistent".to_string(), - ) - .into()); + )); } } @@ -261,16 +252,15 @@ impl Slatepack { secp: &Secp256k1, ) -> Result<(Vec, bool), Error> { if !self.slate.compact_slate { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Slatepack expecting only compact model".to_string(), - ) - .into()); + )); } // Here we can calculate the version of the slatepack that it needed. Currently there is no choices, just a single version. match slate_version { SlateVersion::SP => (), - _ => return Err(ErrorKind::SlatepackEncodeError("Slate is plain".to_string()).into()), + _ => return Err(Error::SlatepackEncodeError("Slate is plain".to_string())), } let mut encrypted_data = Vec::new(); @@ -378,10 +368,9 @@ impl Slatepack { // recipient is define, so we can do encryption if self.sender.is_none() { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Not found expected sender value".to_string(), - ) - .into()); + )); } let sender = self.sender.clone().unwrap(); // Sender address, so other party can open the message @@ -416,10 +405,9 @@ impl Slatepack { let enc_len = encrypted_data.len(); if enc_len > 65534 { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Slate too large for encoding".to_string(), - ) - .into()); + )); } w_pack.write(16, enc_len as u32)?; // Need to keep byte aligned w_pack.write_bytes(&encrypted_data)?; @@ -432,10 +420,9 @@ impl Slatepack { let enc_len = encrypted_data.len(); if enc_len > 65534 { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Slate too large for encoding".to_string(), - ) - .into()); + )); } w_pack.write(16, enc_len as u32)?; // Need to keep byte aligned w_pack.write_bytes(&encrypted_data)?; @@ -511,10 +498,9 @@ impl Slatepack { let sig_dt = sig.serialize_compact(secp); w.write_bytes(&sig_dt)?; } else { - return Err(ErrorKind::GenericError( + return Err(Error::GenericError( "Not found message signature at participant data".to_string(), - ) - .into()); + )); } } None => w.write::(1, 0)?, @@ -675,10 +661,9 @@ impl Slatepack { Self::write_u64(fee.into(), true, w)?; } _ => { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Slatepack expecting only Plain Kernels".to_string(), - ) - .into()) + )) } } w.write_bytes(&kernel.excess.0)?; @@ -691,7 +676,7 @@ impl Slatepack { if write_participan_data_0 { let part_data = slate .participant_with_id(0) - .ok_or(ErrorKind::SlatepackEncodeError( + .ok_or(Error::SlatepackEncodeError( "Not found slate participant data".to_string(), ))?; Self::write_participant_data(&part_data, w, secp)?; @@ -699,7 +684,7 @@ impl Slatepack { if write_participan_data_1 { let part_data = slate .participant_with_id(1) - .ok_or(ErrorKind::SlatepackEncodeError( + .ok_or(Error::SlatepackEncodeError( "Not found slate participant data".to_string(), ))?; Self::write_participant_data(&part_data, w, secp)?; @@ -725,23 +710,19 @@ impl Slatepack { let sign_str = pp.receiver_signature .clone() - .ok_or(ErrorKind::SlatepackEncodeError( + .ok_or(Error::SlatepackEncodeError( "Not found expected payment proof signature".to_string(), ))?; let sign_v = from_hex(&sign_str).map_err(|e| { - ErrorKind::SlatepackEncodeError(format!( - "Wrong signature at slate data, {}", - e - )) + Error::SlatepackEncodeError(format!("Wrong signature at slate data, {}", e)) })?; // Signature length can be different (so far it is 64 bytes or 70) because the PK might be from different families. // That is why let's save the size let sign_len = sign_v.len(); if sign_len < 64 || sign_len >= 64 + 16 { - return Err(ErrorKind::SlatepackEncodeError( + return Err(Error::SlatepackEncodeError( "Invalid Signature length".to_string(), - ) - .into()); + )); } let sign_len: u32 = sign_len as u32 - 64; w.write(4, sign_len)?; @@ -791,13 +772,13 @@ impl Slatepack { let mut msg: Vec = vec![0; sz as usize]; r.read_bytes(&mut msg)?; let msg = smaz::decompress(&msg).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to decode message, {}", e)) + Error::SlatepackDecodeError(format!("Unable to decode message, {}", e)) })?; let mut sig_dt: [u8; 64] = [0; 64]; r.read_bytes(&mut sig_dt)?; ( Some(String::from_utf8(msg).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to decode message, {}", e)) + Error::SlatepackDecodeError(format!("Unable to decode message, {}", e)) })?), Some(Signature::from_compact(secp, &sig_dt)?), ) @@ -838,7 +819,7 @@ impl Slatepack { let mut pk: [u8; PUBLIC_KEY_LENGTH] = [0; PUBLIC_KEY_LENGTH]; r.read_bytes(&mut pk)?; let dalek_pk = DalekPublicKey::from_bytes(&pk).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable decode Public Key data, {}", e)) + Error::SlatepackDecodeError(format!("Unable decode Public Key data, {}", e)) })?; ProvableAddress::from_tor_pub_key(&dalek_pk) @@ -865,15 +846,13 @@ impl Slatepack { let mut slate_id: [u8; 16] = [0; 16]; r.read_bytes(&mut slate_id)?; slate.id = Uuid::from_slice(&slate_id).map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to encode UUID data, {}", e)) + Error::SlatepackDecodeError(format!("Unable to encode UUID data, {}", e)) })?; let network: u8 = r.read(1)?; if (network == 1) ^ global::is_mainnet() { - return Err( - ErrorKind::SlatepackDecodeError("Slate from wrong network".to_string()).into(), - ); + return Err(Error::SlatepackDecodeError("Slate from wrong network".to_string()).into()); } if read_amount { @@ -1076,9 +1055,7 @@ impl Slatepack { let mut enc_bytes = payload; let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, shared_secret.as_bytes()) - .map_err(|e| { - ErrorKind::SlatepackEncodeError(format!("Unable to build a key, {}", e)) - })?; + .map_err(|e| Error::SlatepackEncodeError(format!("Unable to build a key, {}", e)))?; let sealing_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key); let aad = aead::Aad::from(&[]); sealing_key @@ -1087,7 +1064,7 @@ impl Slatepack { aad, &mut enc_bytes, ) - .map_err(|e| ErrorKind::SlatepackEncodeError(format!("Unable to encrypt, {}", e)))?; + .map_err(|e| Error::SlatepackEncodeError(format!("Unable to encrypt, {}", e)))?; Ok((enc_bytes, nonce)) } @@ -1107,9 +1084,7 @@ impl Slatepack { let shared_secret = secret.diffie_hellman(&sender); let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, shared_secret.as_bytes()) - .map_err(|e| { - ErrorKind::SlatepackDecodeError(format!("Unable to build a key, {}", e)) - })?; + .map_err(|e| Error::SlatepackDecodeError(format!("Unable to build a key, {}", e)))?; let opening_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key); let aad = aead::Aad::from(&[]); @@ -1121,7 +1096,7 @@ impl Slatepack { aad, &mut encrypted_message, ) - .map_err(|e| ErrorKind::SlatepackDecodeError(format!("Unable to decrypt, {}", e)))?; + .map_err(|e| Error::SlatepackDecodeError(format!("Unable to decrypt, {}", e)))?; Ok(decrypted_data.to_vec()) } diff --git a/libwallet/src/swap/api.rs b/libwallet/src/swap/api.rs index 4bd1777e6..421831bad 100644 --- a/libwallet/src/swap/api.rs +++ b/libwallet/src/swap/api.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::error::ErrorKind; +use super::error::Error; use super::swap::Swap; use super::types::{Context, Currency}; use super::Keychain; @@ -38,7 +38,7 @@ pub trait SwapApi: Sync + Send { _keychain: &K, secondary_currency: Currency, is_seller: bool, - ) -> Result; + ) -> Result; /// Creating buyer/seller context. Keys are used to generate this session secrets. /// Number of them defined by context_key_count @@ -52,7 +52,7 @@ pub trait SwapApi: Sync + Send { change_amount: u64, keys: Vec, parent_key_id: Identifier, - ) -> Result; + ) -> Result; /// Seller creates a swap offer and creates the core Swap Object. /// It is a starting point for Seller swap workflow @@ -79,7 +79,7 @@ pub trait SwapApi: Sync + Send { eth_redirect_out_wallet: Option, dry_run: bool, tag: Option, - ) -> Result; + ) -> Result; /// get state machine fro this trade. fn get_fsm(&self, keychain: &K, swap: &Swap) -> StateMachine; @@ -89,7 +89,7 @@ pub trait SwapApi: Sync + Send { &self, _keychain: &K, swap: &Swap, - ) -> Result; + ) -> Result; /// Check How much BTC coins are locked on the chain /// Return output with at least 1 confirmations because it is needed for refunds or redeems. Both party want to take everything @@ -99,7 +99,7 @@ pub trait SwapApi: Sync + Send { swap: &Swap, confirmations_needed: u64, secp: &Secp256k1, - ) -> Result<(u64, u64, u64), ErrorKind>; + ) -> Result<(u64, u64, u64), Error>; /// Build secondary update part of the offer message fn build_offer_message_secondary_update( @@ -123,7 +123,7 @@ pub trait SwapApi: Sync + Send { swap: &mut Swap, context: &Context, post_tx: bool, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /// Get a secondary addresses for the lock account /// We can have several addresses because of different formats @@ -131,11 +131,11 @@ pub trait SwapApi: Sync + Send { &self, swap: &Swap, secp: &Secp256k1, - ) -> Result, ErrorKind>; + ) -> Result, Error>; /// Check if tx fee for the secondary is different from the posted. compare swap.secondary_fee with /// posted BTC secondary_fee - fn is_secondary_tx_fee_changed(&self, swap: &Swap) -> Result; + fn is_secondary_tx_fee_changed(&self, swap: &Swap) -> Result; /// Post Refund transaction. fn post_secondary_refund_tx( @@ -145,16 +145,16 @@ pub trait SwapApi: Sync + Send { swap: &mut Swap, refund_address: Option, post_tx: bool, - ) -> Result<(), ErrorKind>; + ) -> Result<(), Error>; /// deposit secondary currecny to lock account. - fn post_secondary_lock_tx(&self, swap: &mut Swap) -> Result<(), ErrorKind>; + fn post_secondary_lock_tx(&self, swap: &mut Swap) -> Result<(), Error>; /// transfer amount to dedicated address. - fn transfer_scondary(&self, swap: &mut Swap) -> Result<(), ErrorKind>; + fn transfer_scondary(&self, swap: &mut Swap) -> Result<(), Error>; /// Validate clients. We want to be sure that the clients able to acceess the servers - fn test_client_connections(&self) -> Result<(), ErrorKind>; + fn test_client_connections(&self) -> Result<(), Error>; } /// Create an appropriate instance for the Currency @@ -165,7 +165,7 @@ pub fn create_btc_instance<'a, C, K>( node_client: C, electrum_node_uri1: String, electrum_node_uri2: String, -) -> Result + 'a>, ErrorKind> +) -> Result + 'a>, Error> where C: NodeClient + 'a, K: Keychain + 'a, @@ -193,7 +193,7 @@ where Arc::new(Mutex::new(secondary_currency_node_client2)), ))) } - _ => Err(ErrorKind::InvalidCurrency( + _ => Err(Error::InvalidCurrency( "unknow btc family coins".to_string(), )), } @@ -209,7 +209,7 @@ pub fn create_eth_instance<'a, C, K>( eth_swap_contract_addr: String, erc20_swap_contract_addr: String, eth_infura_project_id: String, -) -> Result + 'a>, ErrorKind> +) -> Result + 'a>, Error> where C: NodeClient + 'a, K: Keychain + 'a, @@ -247,7 +247,7 @@ where Arc::new(Mutex::new(secondary_currency_node_client)), ))) } - _ => Err(ErrorKind::InvalidCurrency( + _ => Err(Error::InvalidCurrency( "unknow ethereum family coins".to_string(), )), } diff --git a/libwallet/src/swap/bitcoin/api.rs b/libwallet/src/swap/bitcoin/api.rs index 79e7c9247..f34dd737c 100644 --- a/libwallet/src/swap/bitcoin/api.rs +++ b/libwallet/src/swap/bitcoin/api.rs @@ -30,11 +30,11 @@ use crate::swap::types::{ BuyerContext, Context, Currency, RoleContext, SecondaryBuyerContext, SecondarySellerContext, SellerContext, SwapTransactionsConfirmations, }; -use crate::swap::{ErrorKind, SellApi, Swap, SwapApi}; +use crate::swap::{Error, SellApi, Swap, SwapApi}; use crate::{NodeClient, Slate}; use bitcoin::{Script, Txid}; -use failure::_core::marker::PhantomData; use grin_wallet_util::grin_util::secp::Secp256k1; +use std::marker::PhantomData; use std::sync::Arc; /// SwapApi trait implementation for BTC @@ -100,15 +100,12 @@ where } /// Update swap.secondary_data with a roll back script. - pub(crate) fn script(&self, swap: &Swap, secp: &Secp256k1) -> Result { + pub(crate) fn script(&self, swap: &Swap, secp: &Secp256k1) -> Result { let btc_data = swap.secondary_data.unwrap_btc()?; Ok(btc_data.script( - swap.redeem_public - .as_ref() - .ok_or(ErrorKind::UnexpectedAction( - "swap.redeem_public value is not defined. Method BtcSwapApi::script" - .to_string(), - ))?, + swap.redeem_public.as_ref().ok_or(Error::UnexpectedAction( + "swap.redeem_public value is not defined. Method BtcSwapApi::script".to_string(), + ))?, swap.get_time_secondary_lock_script() as u64, secp, )?) @@ -121,7 +118,7 @@ where swap: &Swap, input_script: &Script, confirmations_needed: u64, - ) -> Result<(u64, u64, u64, Vec), ErrorKind> { + ) -> Result<(u64, u64, u64, Vec), Error> { let btc_data = swap.secondary_data.unwrap_btc()?; let address = btc_data.address(self.secondary_currency, input_script, swap.network)?; debug_assert!(address.len() > 0); @@ -186,7 +183,7 @@ where swap: &Swap, context: &Context, input_script: &Script, - ) -> Result { + ) -> Result { let cosign_id = &context.unwrap_seller()?.unwrap_btc()?.cosign; let redeem_address_str = swap.unwrap_seller()?.0.clone(); @@ -200,7 +197,7 @@ where let (pending_amount, confirmed_amount, _, mut conf_outputs) = self.btc_balance(swap, input_script, 0)?; if pending_amount + confirmed_amount == 0 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Not found outputs to redeem. Probably Buyer already refund it".to_string(), )); } @@ -241,12 +238,12 @@ where refund_address: &String, input_script: &Script, post_tx: bool, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let (pending_amount, confirmed_amount, _, conf_outputs) = self.btc_balance(swap, input_script, 0)?; if pending_amount + confirmed_amount == 0 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Not found outputs to refund. Probably Seller already redeem it".to_string(), )); } @@ -298,7 +295,7 @@ where mwc_tip: &u64, slate: &Slate, outputs_ok: bool, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let result: Option = if slate.tx_or_err()?.kernels().is_empty() { None } else { @@ -340,7 +337,7 @@ where &self, btc_tip: &u64, tx_hash: Option, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let result: Option = match tx_hash { None => None, Some(tx_hash) => { @@ -370,10 +367,10 @@ where _keychain: &K, secondary_currency: Currency, _is_seller: bool, - ) -> Result { + ) -> Result { match secondary_currency.is_btc_family() { true => Ok(4), - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } } @@ -387,10 +384,10 @@ where change_amount: u64, keys: Vec, parent_key_id: Identifier, - ) -> Result { + ) -> Result { match secondary_currency.is_btc_family() { true => (), - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } let secp = keychain.secp(); @@ -399,7 +396,7 @@ where let role_context = if is_seller { RoleContext::Seller(SellerContext { parent_key_id: parent_key_id, - inputs: inputs.ok_or(ErrorKind::UnexpectedRole( + inputs: inputs.ok_or(Error::UnexpectedRole( "Fn create_context() for seller not found inputs".to_string(), ))?, change_output: keys.next().unwrap(), @@ -454,13 +451,13 @@ where _eth_redirect_out_wallet: Option, dry_run: bool, tag: Option, - ) -> Result { + ) -> Result { // Checking if address is valid secondary_currency .validate_address(&secondary_redeem_address) .map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to parse secondary currency redeem address {}, {}", secondary_redeem_address, e )) @@ -468,7 +465,7 @@ where match secondary_currency.is_btc_family() { true => (), - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } let height = self.node_client.get_chain_tip()?.0; @@ -535,7 +532,7 @@ where swap: &mut Swap, context: &Context, post_tx: bool, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(swap.is_seller()); let input_script = self.script(swap, keychain.secp())?; @@ -559,7 +556,7 @@ where &self, keychain: &K, // keychain is kept for Type. Compiler need to understand all types swap: &Swap, - ) -> Result { + ) -> Result { let mwc_tip = self.node_client.get_chain_tip()?.0; let is_seller = swap.is_seller(); @@ -642,7 +639,7 @@ where swap: &Swap, confirmations_needed: u64, secp: &Secp256k1, - ) -> Result<(u64, u64, u64), ErrorKind> { + ) -> Result<(u64, u64, u64), Error> { let input_script = self.script(swap, secp)?; let (pending_amount, confirmed_amount, least_confirmations, _outputs) = @@ -741,7 +738,7 @@ where &self, swap: &Swap, secp: &Secp256k1, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let input_script = self.script(swap, secp)?; let address = swap.secondary_data.unwrap_btc()?.address( swap.secondary_currency, @@ -752,7 +749,7 @@ where } /// Check if tx fee for the secondary is different from the posted - fn is_secondary_tx_fee_changed(&self, swap: &Swap) -> Result { + fn is_secondary_tx_fee_changed(&self, swap: &Swap) -> Result { Ok(swap.secondary_data.unwrap_btc()?.tx_fee != Some(swap.secondary_fee)) } @@ -764,12 +761,11 @@ where swap: &mut Swap, refund_address: Option, post_tx: bool, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(!swap.is_seller()); - let refund_address_str = refund_address.ok_or(ErrorKind::Generic( - "Please define refund address".to_string(), - ))?; + let refund_address_str = + refund_address.ok_or(Error::Generic("Please define refund address".to_string()))?; swap.secondary_currency .validate_address(&refund_address_str)?; @@ -787,22 +783,22 @@ where } /// deposit secondary currecny to lock account. - fn post_secondary_lock_tx(&self, _swap: &mut Swap) -> Result<(), ErrorKind> { + fn post_secondary_lock_tx(&self, _swap: &mut Swap) -> Result<(), Error> { Ok(()) } /// transfer amount to dedicated address. - fn transfer_scondary(&self, _swap: &mut Swap) -> Result<(), ErrorKind> { + fn transfer_scondary(&self, _swap: &mut Swap) -> Result<(), Error> { Ok(()) } /// Validate clients. We want to be sure that the clients able to acceess the servers - fn test_client_connections(&self) -> Result<(), ErrorKind> { + fn test_client_connections(&self) -> Result<(), Error> { { let mut c = self.btc_node_client1.lock(); let name = c.name(); let _ = c.height().map_err(|e| { - ErrorKind::ElectrumNodeClient(format!( + Error::ElectrumNodeClient(format!( "Unable to contact the primary ElectrumX client {}, {}", name, e )) @@ -812,7 +808,7 @@ where let mut c = self.btc_node_client2.lock(); let name = c.name(); let _ = c.height().map_err(|e| { - ErrorKind::ElectrumNodeClient(format!( + Error::ElectrumNodeClient(format!( "Unable to contact the secondary ElectrumX client {}, {}", name, e )) diff --git a/libwallet/src/swap/bitcoin/client.rs b/libwallet/src/swap/bitcoin/client.rs index b2ec9cd29..726abda5a 100644 --- a/libwallet/src/swap/bitcoin/client.rs +++ b/libwallet/src/swap/bitcoin/client.rs @@ -14,7 +14,7 @@ use crate::grin_util::Mutex; use crate::swap::types::Currency; -use crate::swap::ErrorKind; +use crate::swap::Error; use bitcoin::consensus::Decodable; use bitcoin::{OutPoint, Transaction, Txid}; use std::collections::HashMap; @@ -60,11 +60,11 @@ pub trait BtcNodeClient: Sync + Send + 'static { /// Name of this client. Normally it is URL fn name(&self) -> String; /// Get node height - fn height(&mut self) -> Result; + fn height(&mut self) -> Result; /// Get unspent outputs for the address - fn unspent(&mut self, currency: Currency, address: &String) -> Result, ErrorKind>; + fn unspent(&mut self, currency: Currency, address: &String) -> Result, Error>; /// Post BTC tranaction, - fn post_tx(&mut self, tx: Vec) -> Result<(), ErrorKind>; + fn post_tx(&mut self, tx: Vec) -> Result<(), Error>; /// Get BTC transaction info. /// Return (height) /// Note: we can't return transaction because it is not Only BTC now, so we don't have parser @@ -72,7 +72,7 @@ pub trait BtcNodeClient: Sync + Send + 'static { fn transaction( &mut self, tx_hash: &Txid, // tx hash - ) -> Result, ErrorKind>; + ) -> Result, Error>; } /// Mock BTC node for the testing @@ -197,11 +197,11 @@ impl BtcNodeClient for TestBtcNodeClient { String::from("BTC test client") } - fn height(&mut self) -> Result { + fn height(&mut self) -> Result { Ok(self.state.lock().height) } - fn unspent(&mut self, currency: Currency, address: &String) -> Result, ErrorKind> { + fn unspent(&mut self, currency: Currency, address: &String) -> Result, Error> { let state = self.state.lock(); let script_pubkey = currency.address_2_script_pubkey(address)?; @@ -242,21 +242,21 @@ impl BtcNodeClient for TestBtcNodeClient { Ok(outputs) } - fn post_tx(&mut self, tx: Vec) -> Result<(), ErrorKind> { + fn post_tx(&mut self, tx: Vec) -> Result<(), Error> { let mut state = self.state.lock(); let cursor = Cursor::new(tx); let tx = Transaction::consensus_decode(cursor).map_err(|e| { - ErrorKind::ElectrumNodeClient(format!("Unable to parse transaction, {}", e)) + Error::ElectrumNodeClient(format!("Unable to parse transaction, {}", e)) })?; let txid = tx.txid(); /* It is expected, transaction repost does work, especially if fees are different... if state.pending.contains_key(&txid) { - return Err(ErrorKind::ElectrumNodeClient("Already in mempool".into())); + return Err(Error::ElectrumNodeClient("Already in mempool".into())); }*/ if state.txs.contains_key(&txid) { - return Err(ErrorKind::ElectrumNodeClient("Already in chain".into())); + return Err(Error::ElectrumNodeClient("Already in chain".into())); } let verify_fn = |out_point: &OutPoint| match state.txs.get(&out_point.txid) { @@ -268,13 +268,13 @@ impl BtcNodeClient for TestBtcNodeClient { }; tx.verify(verify_fn) - .map_err(|e| ErrorKind::ElectrumNodeClient(format!("{}", e)))?; + .map_err(|e| Error::ElectrumNodeClient(format!("{}", e)))?; state.pending.insert(txid, tx.clone()); Ok(()) } - fn transaction(&mut self, tx_hash: &Txid) -> Result, ErrorKind> { + fn transaction(&mut self, tx_hash: &Txid) -> Result, Error> { let state = self.state.lock(); if state.pending.contains_key(tx_hash) { diff --git a/libwallet/src/swap/bitcoin/electrum.rs b/libwallet/src/swap/bitcoin/electrum.rs index 757f77e55..e1d16b41e 100644 --- a/libwallet/src/swap/bitcoin/electrum.rs +++ b/libwallet/src/swap/bitcoin/electrum.rs @@ -16,7 +16,7 @@ use super::client::*; use super::rpc::*; use crate::grin_util::{from_hex, to_hex}; use crate::swap::types::Currency; -use crate::swap::ErrorKind; +use crate::swap::Error; use bitcoin::{OutPoint, Script, Txid}; use bitcoin_hashes::sha256d::Hash; use serde::{Deserialize, Serialize}; @@ -33,11 +33,11 @@ struct ElectrumRpcClient { enum ElectrumError { Response(ElectrumResponseError), - Other(ErrorKind), + Other(Error), } -impl From for ElectrumError { - fn from(error: ErrorKind) -> ElectrumError { +impl From for ElectrumError { + fn from(error: Error) -> ElectrumError { ElectrumError::Other(error) } } @@ -48,11 +48,11 @@ impl From for ElectrumError { } } -impl From for ErrorKind { - fn from(error: ElectrumError) -> ErrorKind { +impl From for Error { + fn from(error: ElectrumError) -> Error { match error { ElectrumError::Response(e) => { - ErrorKind::ElectrumNodeClient(format!("ElectrumX error response: {}", e.message)) + Error::ElectrumNodeClient(format!("ElectrumX error response: {}", e.message)) } ElectrumError::Other(e) => e, } @@ -60,7 +60,7 @@ impl From for ErrorKind { } impl ElectrumRpcClient { - pub fn new(address: String) -> Result { + pub fn new(address: String) -> Result { let mut client = Self { inner: RpcClient::new(address)?, id: 0, @@ -81,10 +81,7 @@ impl ElectrumRpcClient { if e.id.map(|res_id| res_id == id).unwrap_or(true) { let err: ElectrumResponseError = serde_json::from_value(e.error).map_err(|e| { - ErrorKind::ElectrumNodeClient(format!( - "ElectrumX error response, {}", - e - )) + Error::ElectrumNodeClient(format!("ElectrumX error response, {}", e)) })?; return Err(err.into()); } @@ -94,7 +91,7 @@ impl ElectrumRpcClient { if o.id.map(|res_id| res_id == id).unwrap_or(false) { let res_copy = o.result.clone(); let obj: T = serde_json::from_value(o.result).map_err(|e| { - ErrorKind::ElectrumNodeClient(format!( + Error::ElectrumNodeClient(format!( "Unable to decode response '{}', {}", res_copy, e )) @@ -103,7 +100,7 @@ impl ElectrumRpcClient { } } }; - Err(ErrorKind::ElectrumNodeClient(format!("No response received")).into()) + Err(Error::ElectrumNodeClient(format!("No response received")).into()) } fn next_id(&mut self) -> u32 { @@ -111,7 +108,7 @@ impl ElectrumRpcClient { self.id } - fn version(&mut self) -> Result, ErrorKind> { + fn version(&mut self) -> Result, Error> { let params = VersionRequestParams::new("Electrum 3.3.8".into(), "1.4".into()); let request = RpcRequest::new(self.next_id(), "server.version", params)?; self.write(&request)?; @@ -119,11 +116,11 @@ impl ElectrumRpcClient { Ok(version) } - fn write(&mut self, request: &RpcRequest) -> Result<(), ErrorKind> { + fn write(&mut self, request: &RpcRequest) -> Result<(), Error> { self.inner.write(request) } - pub fn unspent(&mut self, script_pubkey: &Script) -> Result, ErrorKind> { + pub fn unspent(&mut self, script_pubkey: &Script) -> Result, Error> { let params = ScriptHashParams::new(script_pubkey); let request = RpcRequest::new(self.next_id(), "blockchain.scripthash.listunspent", params)?; self.write(&request)?; @@ -132,20 +129,20 @@ impl ElectrumRpcClient { Ok(utxos) } - pub fn post_tx(&mut self, tx: Vec) -> Result<(), ErrorKind> { + pub fn post_tx(&mut self, tx: Vec) -> Result<(), Error> { let params = BroadcastParams::new(tx); let request = RpcRequest::new(self.next_id(), "blockchain.transaction.broadcast", params)?; self.write(&request)?; let hash: String = self.wait(request.id)?; let hash = from_hex(hash.as_str()).map_err(|e| { - ErrorKind::ElectrumNodeClient(format!( + Error::ElectrumNodeClient(format!( "Unable to post tx, wrong hash value {}, {}", hash, e )) })?; if hash.len() != 32 { - return Err(ErrorKind::ElectrumNodeClient(format!( + return Err(Error::ElectrumNodeClient(format!( "Unable to post tx, wrong hash {:?}", hash ))); @@ -154,10 +151,7 @@ impl ElectrumRpcClient { Ok(()) } - pub fn transaction( - &mut self, - tx_hash: String, - ) -> Result, ErrorKind> { + pub fn transaction(&mut self, tx_hash: String) -> Result, Error> { let params = TransactionParams::new(tx_hash); let request = RpcRequest::new(self.next_id(), "blockchain.transaction.get", params)?; self.write(&request)?; @@ -284,12 +278,12 @@ impl ElectrumNodeClient { } } /// Connect to the ElectrumX node - pub fn connect(&mut self) -> Result<(), ErrorKind> { + pub fn connect(&mut self) -> Result<(), Error> { self.client()?; Ok(()) } - fn client(&mut self) -> Result<&mut ElectrumRpcClient, ErrorKind> { + fn client(&mut self) -> Result<&mut ElectrumRpcClient, Error> { // Reset connection if it disconnected or if we haven't used it for a while if self .client @@ -320,7 +314,7 @@ impl BtcNodeClient for ElectrumNodeClient { } /// Fetch the current chain height - fn height(&mut self) -> Result { + fn height(&mut self) -> Result { // The proper way to do this is to download all the block headers // and validate them. Since we assume the server can be trusted, // instead we simply ask for the number of confirmations on the @@ -333,18 +327,16 @@ impl BtcNodeClient for ElectrumNodeClient { .to_owned();*/ let hash = self.check_tx_hash.clone(); let client = self.client()?; - let tx = client - .transaction(hash)? - .ok_or(ErrorKind::ElectrumNodeClient( - "Unable to determine height".into(), - ))?; - tx.confirmations.ok_or(ErrorKind::ElectrumNodeClient( + let tx = client.transaction(hash)?.ok_or(Error::ElectrumNodeClient( + "Unable to determine height".into(), + ))?; + tx.confirmations.ok_or(Error::ElectrumNodeClient( "Unable to determine height".into(), )) } /// Fetch a list of unspent outputs belonging to this address - fn unspent(&mut self, currency: Currency, address: &String) -> Result, ErrorKind> { + fn unspent(&mut self, currency: Currency, address: &String) -> Result, Error> { // A full SPV client should validate the Merkle proofs of the transactions // that created these outputs let client = self.client()?; @@ -358,7 +350,7 @@ impl BtcNodeClient for ElectrumNodeClient { .take(address.len() - prefix_len - 4 - 8) .collect(); let script_bin = from_hex(&script_hex).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to convert bitcoin-script address '{}' into Script hex, {}", address, e )) @@ -392,12 +384,12 @@ impl BtcNodeClient for ElectrumNodeClient { Ok(outputs) } /// Post BTC transaction - fn post_tx(&mut self, tx: Vec) -> Result<(), ErrorKind> { + fn post_tx(&mut self, tx: Vec) -> Result<(), Error> { let client = self.client()?; client.post_tx(tx) } /// Request a transaction from the node - fn transaction(&mut self, tx_hash: &Txid) -> Result, ErrorKind> { + fn transaction(&mut self, tx_hash: &Txid) -> Result, Error> { let head_height = self.height()?; let client = self.client()?; diff --git a/libwallet/src/swap/bitcoin/rpc.rs b/libwallet/src/swap/bitcoin/rpc.rs index 322c534fc..3aebcbbb9 100644 --- a/libwallet/src/swap/bitcoin/rpc.rs +++ b/libwallet/src/swap/bitcoin/rpc.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::swap::ErrorKind; +use crate::swap::Error; use native_tls::{TlsConnector, TlsStream}; use serde::Serialize; use serde_json::Value; @@ -31,18 +31,18 @@ pub struct LineStream { } impl LineStream { - pub fn new(address: String) -> Result { + pub fn new(address: String) -> Result { match Self::create_as_ssl(&address) { Ok(s) => Ok(s), Err(_) => return Self::create_as_plain(&address), } } - fn create_tcp_stream(address: &String) -> Result { + fn create_tcp_stream(address: &String) -> Result { let address = address .to_socket_addrs()? .next() - .ok_or(ErrorKind::Generic("Unable to parse address".into()))?; + .ok_or(Error::Generic("Unable to parse address".into()))?; let timeout = Duration::from_secs(10); let stream = TcpStream::connect_timeout(&address, timeout)?; @@ -52,18 +52,18 @@ impl LineStream { } // If SSL failed, we can't reuse the tcp connection for the plain because the RPC feed is broken - fn create_as_ssl(address: &String) -> Result { + fn create_as_ssl(address: &String) -> Result { // Trying to use SSL, in case of failure, will use plain connection let host: Vec<&str> = address.split(':').collect(); let host = host[0]; let connector = TlsConnector::new().map_err(|e| { - ErrorKind::ElectrumNodeClient(format!("Unable to create TLS connector, {}", e)) + Error::ElectrumNodeClient(format!("Unable to create TLS connector, {}", e)) })?; let stream = Self::create_tcp_stream(address)?; let tls_stream = connector.connect(host, stream.try_clone()?).map_err(|e| { - ErrorKind::ElectrumNodeClient(format!( + Error::ElectrumNodeClient(format!( "Unable to establesh SSL connection with host {}, {}", host, e )) @@ -76,7 +76,7 @@ impl LineStream { } // If SSL failed, we can't reuse the tcp connection for the plain because the RPC feed is broken - fn create_as_plain(address: &String) -> Result { + fn create_as_plain(address: &String) -> Result { let stream = Self::create_tcp_stream(address)?; Ok(Self { reader: StreamReader::PlainReader(Some(BufReader::new(stream.try_clone()?))), @@ -88,7 +88,7 @@ impl LineStream { self.connected } - pub fn read_line(&mut self) -> Result { + pub fn read_line(&mut self) -> Result { let mut line = String::new(); let read_res = match &mut self.reader { @@ -109,7 +109,7 @@ impl LineStream { } Ok(c) if c == 0 => { self.connected = false; - return Err(ErrorKind::Generic("Connection closed".into())); + return Err(Error::Generic("Connection closed".into())); } Ok(_) => {} } @@ -117,7 +117,7 @@ impl LineStream { Ok(line) } - pub fn write_line(&mut self, mut line: String) -> Result<(), ErrorKind> { + pub fn write_line(&mut self, mut line: String) -> Result<(), Error> { line.push_str("\n"); let bytes = line.into_bytes(); @@ -145,7 +145,7 @@ impl LineStream { } Ok(c) if c == 0 => { self.connected = false; - Err(ErrorKind::Generic("Connection closed".into())) + Err(Error::Generic("Connection closed".into())) } Ok(_) => Ok(()), } @@ -157,9 +157,9 @@ pub struct RpcClient { } impl RpcClient { - pub fn new(address: String) -> Result { + pub fn new(address: String) -> Result { let inner = LineStream::new(address.clone()) - .map_err(|e| ErrorKind::Rpc(format!("Unable connect to {}, {}", address, e)))?; + .map_err(|e| Error::Rpc(format!("Unable connect to {}, {}", address, e)))?; Ok(Self { inner }) } @@ -167,22 +167,22 @@ impl RpcClient { self.inner.is_connected() } - pub fn read(&mut self) -> Result { + pub fn read(&mut self) -> Result { let line = self .inner .read_line() - .map_err(|e| ErrorKind::Rpc(format!("Unable to read line, {}", e)))?; + .map_err(|e| Error::Rpc(format!("Unable to read line, {}", e)))?; let result: RpcResponse = serde_json::from_str(&line) - .map_err(|e| ErrorKind::Rpc(format!("Unable to deserialize '{}', {}", line, e)))?; + .map_err(|e| Error::Rpc(format!("Unable to deserialize '{}', {}", line, e)))?; Ok(result) } - pub fn write(&mut self, request: &RpcRequest) -> Result<(), ErrorKind> { + pub fn write(&mut self, request: &RpcRequest) -> Result<(), Error> { let line = serde_json::to_string(request) - .map_err(|e| ErrorKind::Rpc(format!("Unable to serialize, {}", e)))?; + .map_err(|e| Error::Rpc(format!("Unable to serialize, {}", e)))?; self.inner .write_line(line) - .map_err(|e| ErrorKind::Rpc(format!("Unable to write line, {}", e)))?; + .map_err(|e| Error::Rpc(format!("Unable to write line, {}", e)))?; Ok(()) } } @@ -196,7 +196,7 @@ pub struct RpcRequest { } impl RpcRequest { - pub fn new(id: u32, method: &str, params: T) -> Result { + pub fn new(id: u32, method: &str, params: T) -> Result { Ok(Self { id: format!("{}", id), jsonrpc: "2.0".into(), diff --git a/libwallet/src/swap/bitcoin/types.rs b/libwallet/src/swap/bitcoin/types.rs index cb34c8e3b..6a1fbfca1 100644 --- a/libwallet/src/swap/bitcoin/types.rs +++ b/libwallet/src/swap/bitcoin/types.rs @@ -20,7 +20,7 @@ use crate::swap::message::SecondaryUpdate; use crate::swap::ser::*; use crate::swap::swap; use crate::swap::types::{Currency, Network, SecondaryData}; -use crate::swap::{ErrorKind, Keychain}; +use crate::swap::{Error, Keychain}; use bitcoin::blockdata::opcodes::{all::*, OP_FALSE, OP_TRUE}; use bitcoin::blockdata::script::Builder; use bitcoin::consensus::Encodable; @@ -73,7 +73,7 @@ impl BtcData { pub(crate) fn new( keychain: &K, // Private key context: &BtcSellerContext, // Derivarive index - ) -> Result + ) -> Result where K: Keychain, { @@ -96,7 +96,7 @@ impl BtcData { keychain: &K, offer: BtcOfferUpdate, context: &BtcBuyerContext, - ) -> Result + ) -> Result where K: Keychain, { @@ -115,7 +115,7 @@ impl BtcData { pub(crate) fn accepted_offer( &mut self, accepted_offer: BtcAcceptOfferUpdate, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { self.refund = Some(accepted_offer.refund); Ok(()) } @@ -130,17 +130,17 @@ impl BtcData { redeem: &PublicKey, btc_lock_time: u64, secp: &Secp256k1, - ) -> Result { + ) -> Result { // Don't lock for more than 4 weeks. 4 weeks + 2 day, because max locking is expecting 2 weeks and 1 day to do the swap and 1 extra day for Byer if btc_lock_time > (swap::get_cur_time() + 3600 * 24 * (7 * 4 + 2)) as u64 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "BTC locking time interval is larger than 4 weeks. Rejecting, looks like a scam." .to_string(), )); } if btc_lock_time >= u32::MAX as u64 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "BTC locking time is out of range. Rejecting, looks like a scam.".to_string(), )); } @@ -153,7 +153,7 @@ impl BtcData { let refund = self .refund - .ok_or(ErrorKind::SecondaryDataIncomplete)? + .ok_or(Error::SecondaryDataIncomplete)? .serialize_vec(secp, true); let cosign = self.cosign.serialize_vec(secp, true); let redeem = redeem.serialize_vec(secp, true); @@ -182,7 +182,7 @@ impl BtcData { currency: Currency, script: &Script, network: Network, - ) -> Result, ErrorKind> { + ) -> Result, Error> { match currency { Currency::Btc => { let address = Address::new_btc().p2sh(script, btc_network(network)); @@ -197,7 +197,7 @@ impl BtcData { bch_network(network), ) .map_err(|e| { - ErrorKind::BchError(format!( + Error::BchError(format!( "Unable to encode BCH address from script hash, {}", e )) @@ -249,7 +249,7 @@ impl BtcData { let address = Address::new_doge().p2sh(script, btc_network(network)); Ok(vec![address.to_string()]) } - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } } @@ -259,7 +259,7 @@ impl BtcData { currency: &Currency, redeem_address: &String, conf_outputs: &Vec, - ) -> Result<(Vec<(TxIn, u64)>, Vec, u64), ErrorKind> { + ) -> Result<(Vec<(TxIn, u64)>, Vec, u64), Error> { // Input(s) let mut input = Vec::with_capacity(conf_outputs.len()); let mut total_amount = 0; @@ -277,7 +277,7 @@ impl BtcData { } if input.is_empty() { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Unable to build refund transaction, no inputs are found".to_string(), )); } @@ -337,7 +337,7 @@ impl BtcData { cosign_signature: &mut Signature, redeem_signature: &mut Signature, secp: &Secp256k1, - ) -> Result { + ) -> Result { let (cosign_ser, redeem_ser) = match currency { Currency::Btc | Currency::Ltc | Currency::Dash | Currency::ZCash | Currency::Doge => { let mut cosign_ser = cosign_signature.serialize_der(secp); @@ -371,7 +371,7 @@ impl BtcData { | Currency::Usdc | Currency::Trx | Currency::Tst => { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Ether/Erc20-token is not supported".to_string(), )); } @@ -399,7 +399,7 @@ impl BtcData { fee: f32, btc_lock_time: i64, conf_outputs: &Vec, - script_sig: impl Fn(&Message) -> Result, + script_sig: impl Fn(&Message) -> Result, ) -> Result< ( BtcTtansaction, @@ -407,7 +407,7 @@ impl BtcData { Option, Option, ), - ErrorKind, + Error, > { let (input, output, total_amount) = Self::build_input_outputs(currency, address, conf_outputs)?; @@ -450,7 +450,7 @@ impl BtcData { tx.input .get_mut(idx) - .ok_or(ErrorKind::Generic("Not found expected input".to_string()))? + .ok_or(Error::Generic("Not found expected input".to_string()))? .script_sig = script_sig(&msg)?; } } @@ -472,13 +472,13 @@ impl BtcData { sighash_type, &mut cache, ) - .map_err(|e| ErrorKind::BchError(format!("sighash failed, {}", e)))?; + .map_err(|e| Error::BchError(format!("sighash failed, {}", e)))?; let msg = Message::from_slice(&hash.0)?; tx.input .get_mut(idx) - .ok_or(ErrorKind::Generic("Not found expected input".to_string()))? + .ok_or(Error::Generic("Not found expected input".to_string()))? .script_sig = script_sig(&msg)?; } } @@ -504,7 +504,7 @@ impl BtcData { for out in &tx.output { zcash_tx_data.vout.push(zcash_tx::components::TxOut { value: zcash_tx::components::Amount::from_u64(out.value).map_err(|_| { - ErrorKind::Generic("Unable convert amount for ZCash".to_string()) + Error::Generic("Unable convert amount for ZCash".to_string()) })?, script_pubkey: zcash_primitives::legacy::Script( out.script_pubkey.to_bytes(), @@ -522,9 +522,8 @@ impl BtcData { zcash_tx::SignableInput::transparent( idx, &zcash_primitives::legacy::Script(input_script.to_bytes()), - zcash_tx::components::Amount::from_u64(input[idx].1).map_err(|_| { - ErrorKind::Generic("Invalid input amount".to_string()) - })?, + zcash_tx::components::Amount::from_u64(input[idx].1) + .map_err(|_| Error::Generic("Invalid input amount".to_string()))?, ), )); @@ -541,10 +540,7 @@ impl BtcData { return Ok(( BtcTtansaction { txid: sha256d::Hash::from_slice(&zcash_tx.txid().0).map_err(|e| { - ErrorKind::Generic(format!( - "Unable to convert Hash data for ZCash, {}", - e - )) + Error::Generic(format!("Unable to convert Hash data for ZCash, {}", e)) })?, tx: raw_tx, }, @@ -565,7 +561,7 @@ impl BtcData { | Currency::Usdc | Currency::Trx | Currency::Tst => { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Ether/Erc20-tonken is not supported".to_string(), )); } @@ -574,7 +570,7 @@ impl BtcData { let mut cursor = Cursor::new(Vec::with_capacity(tx_size)); let actual_size = tx .consensus_encode(&mut cursor) - .map_err(|e| ErrorKind::Generic(format!("Unable to encode redeem tx, {}", e)))?; + .map_err(|e| Error::Generic(format!("Unable to encode redeem tx, {}", e)))?; // By some reasons length is floating, probably encoding can do some optimization . Let'e keep an eye on it, we don't want to calcucate fee badly. debug_assert!(actual_size <= tx_size + 4); @@ -596,7 +592,7 @@ impl BtcData { signature: &mut Signature, input_script: &Script, secp: &Secp256k1, - ) -> Result { + ) -> Result { let sign_ser = match currency { Currency::Bch => { signature.normalize_s(secp); @@ -621,7 +617,7 @@ impl BtcData { | Currency::Usdc | Currency::Trx | Currency::Tst => { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Ether/Erc20-token is not supported".to_string(), )); } @@ -679,20 +675,20 @@ pub enum BtcUpdate { impl BtcUpdate { /// Unwrap BtcOfferUpdate with data type verification - pub fn unwrap_offer(self) -> Result { + pub fn unwrap_offer(self) -> Result { match self { BtcUpdate::Offer(u) => Ok(u), - _ => Err(ErrorKind::UnexpectedMessageType( + _ => Err(Error::UnexpectedMessageType( "Fn unwrap_offer() expecting BtcUpdate::Offer".to_string(), )), } } /// Unwrap BtcAcceptOfferUpdate with data type verification - pub fn unwrap_accept_offer(self) -> Result { + pub fn unwrap_accept_offer(self) -> Result { match self { BtcUpdate::AcceptOffer(u) => Ok(u), - _ => Err(ErrorKind::UnexpectedMessageType( + _ => Err(Error::UnexpectedMessageType( "Fn unwrap_accept_offer() expecting BtcUpdate::AcceptOffer".to_string(), )), } diff --git a/libwallet/src/swap/buyer.rs b/libwallet/src/swap/buyer.rs index 97835b09c..341437627 100644 --- a/libwallet/src/swap/buyer.rs +++ b/libwallet/src/swap/buyer.rs @@ -18,7 +18,7 @@ use super::message::*; use super::swap; use super::swap::{tx_add_input, tx_add_output, Swap}; use super::types::*; -use super::{ErrorKind, Keychain, CURRENT_VERSION}; +use super::{Error, Keychain, CURRENT_VERSION}; use crate::api_impl::owner_eth::get_eth_balance; use crate::grin_core::core::Committed; use crate::grin_core::core::KernelFeatures; @@ -50,17 +50,14 @@ impl BuyApi { offer: OfferUpdate, secondary_update: SecondaryUpdate, node_client: &C, - ) -> Result { + ) -> Result { if offer.version != CURRENT_VERSION { - return Err(ErrorKind::IncompatibleVersion( - offer.version, - CURRENT_VERSION, - )); + return Err(Error::IncompatibleVersion(offer.version, CURRENT_VERSION)); } // Checking if the network match expected value if offer.network != Network::current_network()? { - return Err(ErrorKind::UnexpectedNetwork(format!( + return Err(Error::UnexpectedNetwork(format!( ", get offer for wrong network {:?}", offer.network ))); @@ -72,7 +69,7 @@ impl BuyApi { // Tolerating 15 seconds clock difference. We don't want surprises with clocks. if offer.start_time.timestamp() > (now_ts + 15) { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Buyer/Seller clock are out of sync".to_string(), )); } @@ -80,10 +77,10 @@ impl BuyApi { // Multisig tx needs to be unlocked and valid. Let's take a look at what we get. let lock_slate: Slate = offer.lock_slate.into_slate_plain(true)?; if lock_slate.get_lock_height() > 0 { - return Err(ErrorKind::InvalidLockHeightLockTx); + return Err(Error::InvalidLockHeightLockTx); } if lock_slate.amount != offer.primary_amount { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate amount doesn't match offer".to_string(), )); } @@ -93,18 +90,18 @@ impl BuyApi { lock_slate.tx_or_err()?.body.outputs.len() + 1, 1, ) { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate fee doesn't match expected value".to_string(), )); } if lock_slate.num_participants != 2 { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate participans doesn't match expected value".to_string(), )); } if lock_slate.tx_or_err()?.body.kernels.len() != 1 { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate invalid kernels".to_string(), )); } @@ -114,13 +111,13 @@ impl BuyApi { match lock_slate.tx_or_err()?.body.kernels[0].features { KernelFeatures::Plain { fee } => { if fee.fee(current_height) != lock_slate.fee { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate invalid kernel fee".to_string(), )); } } _ => { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate invalid kernel feature".to_string(), )) } @@ -129,18 +126,18 @@ impl BuyApi { // Let's check inputs. They must exist, we want real inspent coins. We can't check amount, that will be later when we cound validate the sum. // Height of the inputs is not important, we are relaying on locking transaction confirmations that is weaker. if lock_slate.tx_or_err()?.body.inputs.is_empty() { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate empty inputs".to_string(), )); } let res = node_client.get_outputs_from_node(&lock_slate.tx_or_err()?.inputs_committed())?; if res.len() != lock_slate.tx_or_err()?.body.inputs.len() { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate inputs are not found at the chain".to_string(), )); } if lock_slate.height > current_height { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Lock Slate height is invalid".to_string(), )); } @@ -154,7 +151,7 @@ impl BuyApi { // Lock_height will be verified later if refund_slate.tx_or_err()?.body.kernels.len() != 1 { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund Slate invalid kernel".to_string(), )); } @@ -163,29 +160,29 @@ impl BuyApi { if fee.fee(current_height) != refund_slate.fee || lock_height != refund_slate.get_lock_height_check()? { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund Slate invalid kernel fee or height".to_string(), )); } } _ => { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund Slate invalid kernel feature".to_string(), )) } } if refund_slate.num_participants != 2 { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund Slate participants doesn't match expected value".to_string(), )); } if refund_slate.amount + refund_slate.fee != lock_slate.amount { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund Slate amount doesn't match offer".to_string(), )); } if refund_slate.fee != tx_fee(1, 1, 1) { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund Slate fee doesn't match expected value".to_string(), )); } @@ -240,9 +237,9 @@ impl BuyApi { if !offer.secondary_currency.is_btc_family() { let balance_gwei = get_eth_balance(ethereum_wallet.unwrap())?; if secondary_fee > balance_gwei as f32 { - return Err( - ErrorKind::Generic("No enough ether as gas for swap".to_string()).into(), - ); + return Err(Error::Generic( + "No enough ether as gas for swap".to_string(), + )); } } @@ -373,7 +370,7 @@ impl BuyApi { let expected_lock_height = current_height + (swap.get_time_mwc_lock() - now_ts) as u64 / 60; if swap.refund_slate.get_lock_height_check()? < expected_lock_height * 9 / 10 { - return Err(ErrorKind::InvalidMessageData( + return Err(Error::InvalidMessageData( "Refund lock slate doesn't meet required number of confirmations".to_string(), )); } @@ -390,7 +387,7 @@ impl BuyApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(!swap.is_seller()); Self::build_redeem_slate(keychain, swap, context)?; Self::calculate_adaptor_signature(keychain, swap, context)?; @@ -402,7 +399,7 @@ impl BuyApi { pub fn accept_offer_message( swap: &Swap, inner_secondary: SecondaryUpdate, - ) -> Result { + ) -> Result { let id = swap.participant_id; swap.message( Update::AcceptOffer(AcceptOfferUpdate { @@ -410,7 +407,7 @@ impl BuyApi { redeem_public: swap .redeem_public .clone() - .ok_or(ErrorKind::Generic("redeem_public is empty".to_string()))?, + .ok_or(Error::Generic("redeem_public is empty".to_string()))?, lock_participant: swap.lock_slate.participant_data[id].clone(), refund_participant: swap.refund_slate.participant_data[id].clone(), }), @@ -419,14 +416,14 @@ impl BuyApi { } /// Generate 'InitRedeem' slate message - pub fn init_redeem_message(swap: &Swap) -> Result { + pub fn init_redeem_message(swap: &Swap) -> Result { swap.message( Update::InitRedeem(InitRedeemUpdate { redeem_slate: VersionedSlate::into_version_plain( swap.redeem_slate.clone(), SlateVersion::V2, // V2 should satify our needs, dont adding extra )?, - adaptor_signature: swap.adaptor_signature.ok_or(ErrorKind::UnexpectedAction( + adaptor_signature: swap.adaptor_signature.ok_or(Error::UnexpectedAction( "Buyer Fn init_redeem_message(), multisig is empty".to_string(), ))?, }), @@ -435,10 +432,7 @@ impl BuyApi { } /// Secret that unlocks the funds on both chains - pub fn redeem_secret( - keychain: &K, - context: &Context, - ) -> Result { + pub fn redeem_secret(keychain: &K, context: &Context) -> Result { let bcontext = context.unwrap_buyer()?; let sec_key = keychain.derive_key(0, &bcontext.redeem, SwitchCommitmentType::None)?; @@ -450,7 +444,7 @@ impl BuyApi { swap: &mut Swap, context: &Context, part: MultisigParticipant, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let multisig_secret = swap.multisig_secret(keychain, context)?; let multisig = &mut swap.multisig; @@ -474,7 +468,7 @@ impl BuyApi { keychain: &K, swap: &Swap, context: &Context, - ) -> Result { + ) -> Result { // Partial multisig output let sum = BlindSum::new().add_blinding_factor(BlindingFactor::from_secret_key( swap.multisig_secret(keychain, context)?, @@ -488,17 +482,16 @@ impl BuyApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let mut sec_key = Self::lock_tx_secret(keychain, swap, context)?; // This function should only be called once let slate = &mut swap.lock_slate; if slate.participant_data.len() > 1 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Buyer Fn sign_lock_slate(), lock slate participant data is already initialized" .to_string(), - ) - .into()); + )); } // Add multisig output to slate (with invalid proof) @@ -531,7 +524,7 @@ impl BuyApi { keychain: &K, swap: &Swap, context: &Context, - ) -> Result { + ) -> Result { // Partial multisig input let sum = BlindSum::new().sub_blinding_factor(BlindingFactor::from_secret_key( swap.multisig_secret(keychain, context)?, @@ -545,14 +538,14 @@ impl BuyApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let commit = swap.multisig.commit(keychain.secp())?; let mut sec_key = Self::refund_tx_secret(keychain, swap, context)?; // This function should only be called once let slate = &mut swap.refund_slate; if slate.participant_data.len() > 1 { - return Err(ErrorKind::OneShot("Buyer Fn sign_refund_slate(), refund slate participant data is already initialized".to_string()).into()); + return Err(Error::OneShot("Buyer Fn sign_refund_slate(), refund slate participant data is already initialized".to_string())); } // Add multisig input to slate @@ -582,7 +575,7 @@ impl BuyApi { keychain: &K, swap: &Swap, context: &Context, - ) -> Result { + ) -> Result { let bcontext = context.unwrap_buyer()?; // Partial multisig input, redeem output, offset @@ -601,13 +594,13 @@ impl BuyApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let bcontext = context.unwrap_buyer()?; // This function should only be called once let slate = &mut swap.redeem_slate; if slate.participant_data.len() > 1 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Buyer Fn build_redeem_slate(), redeem slate participant data is not empty" .to_string(), )); @@ -665,7 +658,7 @@ impl BuyApi { context: &Context, part: TxParticipant, height: u64, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let id = swap.participant_id; let other_id = swap.other_participant_id(); let sec_key = Self::redeem_tx_secret(keychain, swap, context)?; @@ -675,10 +668,10 @@ impl BuyApi { if slate .participant_data .get(id) - .ok_or(ErrorKind::UnexpectedAction("Buyer Fn finalize_redeem_slate() redeem slate participant data is not initialized for this party".to_string()))? + .ok_or(Error::UnexpectedAction("Buyer Fn finalize_redeem_slate() redeem slate participant data is not initialized for this party".to_string()))? .is_complete() { - return Err(ErrorKind::OneShot("Buyer Fn finalize_redeem_slate() redeem slate is already initialized".to_string()).into()); + return Err(Error::OneShot("Buyer Fn finalize_redeem_slate() redeem slate is already initialized".to_string())); } // Replace participant @@ -686,7 +679,7 @@ impl BuyApi { slate .participant_data .get_mut(other_id) - .ok_or(ErrorKind::UnexpectedAction("Buyer Fn finalize_redeem_slate() redeem slate participant data is not initialized for other party".to_string()))?, + .ok_or(Error::UnexpectedAction("Buyer Fn finalize_redeem_slate() redeem slate participant data is not initialized for other party".to_string()))?, part, ); @@ -706,10 +699,10 @@ impl BuyApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { // This function should only be called once if swap.adaptor_signature.is_some() { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Buyer calculate_adaptor_signature(), miltisig is already initialized".to_string(), )); } diff --git a/libwallet/src/swap/error.rs b/libwallet/src/swap/error.rs index 283d4e657..c00aea7c6 100644 --- a/libwallet/src/swap/error.rs +++ b/libwallet/src/swap/error.rs @@ -15,234 +15,192 @@ use super::multisig; use crate::grin_core::core::committed; use crate::grin_util::secp; -use failure::Fail; -use std::error::Error as StdError; use std::io; /// Swap crate errors -#[derive(Clone, Eq, PartialEq, Debug, Fail)] -pub enum ErrorKind { +#[derive(Clone, Eq, PartialEq, Debug, thiserror::Error)] +pub enum Error { /// ElectrumX connection URI is not setup - #[fail( - display = "ElectrumX {} URI is not defined. Please specify it at wallet config or with swap arguments", - _0 - )] + #[error("ElectrumX {0} URI is not defined. Please specify it at wallet config or with swap arguments")] UndefinedElectrumXURI(String), /// Unexpected state or status. Business logic is broken - #[fail(display = "Swap Unexpected action, {}", _0)] + #[error("Swap Unexpected action, {0}")] UnexpectedAction(String), /// Unexpected network - #[fail(display = "Swap Unexpected network {}", _0)] + #[error("Swap Unexpected network {0}")] UnexpectedNetwork(String), /// Unexpected role. Business logic is broken - #[fail(display = "Swap Unexpected role, {}", _0)] + #[error("Swap Unexpected role, {0}")] UnexpectedRole(String), /// Not enough MWC to start swap - #[fail(display = "Insufficient funds. Required: {}, available: {}", _0, _1)] + #[error("Insufficient funds. Required: {0}, available: {1}")] InsufficientFunds(u64, u64), /// Message type is wrong. Business logic is broken or another party messing up with us. - #[fail(display = "Swap Unexpected message type, {}", _0)] + #[error("Swap Unexpected message type, {0}")] UnexpectedMessageType(String), /// Likely BTC data is not initialized. Or workflow for your new currenly is not defined - #[fail(display = "Swap Unexpected secondary coin type")] + #[error("Swap Unexpected secondary coin type")] UnexpectedCoinType, /// Yours swap version is different from other party. Somebody need to make an upgrade - #[fail( - display = "Swap engines version are different. Other party has version {}, you has {}. To make a deal, you need to have the same versions.", - _0, _1 - )] + #[error("Swap engines version are different. Other party has version {0}, you has {1}. To make a deal, you need to have the same versions.")] IncompatibleVersion(u8, u8), /// Message from different swap. Probably other party messing up with us. - #[fail(display = "Mismatch between swap and message IDs")] + #[error("Mismatch between swap and message IDs")] MismatchedId, /// Unable to parse the amount string - #[fail(display = "Invalid amount string, {}", _0)] + #[error("Invalid amount string, {0}")] InvalidAmountString(String), /// Wrong currency name - #[fail(display = "Swap Invalid currency: {}", _0)] + #[error("Swap Invalid currency: {0}")] InvalidCurrency(String), /// Lock slate can't be locked - #[fail(display = "Invalid lock height for Swap lock tx")] + #[error("Invalid lock height for Swap lock tx")] InvalidLockHeightLockTx, /// Schnorr signature is invalid - #[fail(display = "Swap Invalid adaptor signature (Schnorr signature)")] + #[error("Swap Invalid adaptor signature (Schnorr signature)")] InvalidAdaptorSignature, /// swap.refund is not defined - #[fail(display = "Swap secondary currency data not complete")] + #[error("Swap secondary currency data not complete")] SecondaryDataIncomplete, /// Expected singe call for that - #[fail(display = "Swap function should only be called once, {}", _0)] + #[error("Swap function should only be called once, {0}")] OneShot(String), /// Swap is already finalized - #[fail(display = "Swap is not active (finalized or cancelled)")] + #[error("Swap is not active (finalized or cancelled)")] NotActive, /// Multisig error - #[fail(display = "Swap Multisig error: {}", _0)] - Multisig(multisig::ErrorKind), + #[error("Swap Multisig error: {0}")] + Multisig(#[from] multisig::Error), /// Keychain failed - #[fail(display = "Swap Keychain error: {}", _0)] - Keychain(crate::grin_keychain::Error), + #[error("Swap Keychain error: {0}")] + Keychain(#[from] crate::grin_keychain::Error), /// LibWallet error - #[fail(display = "Swap LibWallet error: {}", _0)] - LibWallet(crate::ErrorKind), + #[error("Swap LibWallet error: {0}")] + LibWallet(String), /// Secp issue - #[fail(display = "Swap Secp error: {}", _0)] - Secp(String), + #[error("Swap Secp error: {0}")] + Secp(#[from] secp::Error), /// IO error - #[fail(display = "Swap I/O: {}", _0)] + #[error("Swap I/O: {0}")] IO(String), /// Serde error - #[fail(display = "Swap Serde error: {}", _0)] + #[error("Swap Serde error: {0}")] Serde(String), /// Rps error - #[fail(display = "Swap Rpc error: {}", _0)] + #[error("Swap Rpc error: {0}")] Rpc(String), /// Electrum Node client error - #[fail(display = "Electrum Node error, {}", _0)] + #[error("Electrum Node error, {0}")] ElectrumNodeClient(String), /// Requested swap trade not found - #[fail(display = "Swap trade {} not found", _0)] + #[error("Swap trade {0} not found")] TradeNotFound(String), /// swap trade IO error - #[fail(display = "Swap trade {} IO error, {}", _0, _1)] + #[error("Swap trade {0} IO error, {1}")] TradeIoError(String, String), /// swap trade encryption/decryption error - #[fail(display = "Swap trade {} encryption/decryption error", _0)] + #[error("Swap trade {0} encryption/decryption error")] TradeEncDecError(String), /// Message validation error. Likely somebody trying to cheat with as - #[fail(display = "Invalid Message data, {}", _0)] + #[error("Invalid Message data, {0}")] InvalidMessageData(String), /// Invalid Swap state input - #[fail(display = "Invalid Swap state input, {}", _0)] + #[error("Invalid Swap state input, {0}")] InvalidSwapStateInput(String), /// Invalid Swap state input - #[fail(display = "Swap state machine error, {}", _0)] + #[error("Swap state machine error, {0}")] SwapStateMachineError(String), /// Generic error - #[fail(display = "Swap generic error, {}", _0)] + #[error("Swap generic error, {0}")] Generic(String), + /// Message sending issues + #[error("Message sending error, {0}")] + MessageSender(String), + /// BCH tweks related error - #[fail(display = "BCH error, {}", _0)] + #[error("BCH error, {0}")] BchError(String), /// Infura Node client error - #[fail( - display = "Infura Project Id not defined. Please specify it at wallet config or with swap arguments" + #[error( + "Infura Project Id not defined. Please specify it at wallet config or with swap arguments" )] UndefinedInfuraProjectId, /// Eth SWap Contract Address error - #[fail( - display = "Eth Swap Contract Address is not defined. Please specify it at wallet config or with swap arguments" - )] + #[error("Eth Swap Contract Address is not defined. Please specify it at wallet config or with swap arguments")] UndefinedEthSwapContractAddress, /// ERC20 Swap Contract Address error - #[fail( - display = "ERC20 Swap Contract Address is not defined. Please specify it at wallet config or with swap arguments" - )] + #[error("ERC20 Swap Contract Address is not defined. Please specify it at wallet config or with swap arguments")] UndefinedERC20SwapContractAddress, /// Infura Node error - #[fail(display = "Infura Node error, {}", _0)] + #[error("Infura Node error, {0}")] InfuraNodeClient(String), /// Invalid Swap Trade Index - #[fail(display = "Ethereum Swap Trade Index error")] + #[error("Ethereum Swap Trade Index error")] InvalidEthSwapTradeIndex, /// Invalid Eth Address - #[fail(display = "Ethereum Address error")] + #[error("Ethereum Address error")] InvalidEthAddress, /// Eth balance is not enough - #[fail(display = "Eth Wallet Balance is not enough")] + #[error("Eth Wallet Balance is not enough")] EthBalanceNotEnough, /// ERC20 Token balance is not enough - #[fail(display = "ERC20 Token {} Balance is not enough", _0)] + #[error("ERC20 Token {0} Balance is not enough")] ERC20TokenBalanceNotEnough(String), /// Invalid Tx Hash - #[fail(display = "Invalid Eth Transaction Hash")] + #[error("Invalid Eth Transaction Hash")] InvalidTxHash, /// Contract error - #[fail(display = "Call Swap Contract error: {}", _0)] + #[error("Call Swap Contract error: {0}")] EthContractCallError(String), /// Retrieve TransactionRecipt error - #[fail(display = "Retrieve Eth TransactionReceipt error")] + #[error("Retrieve Eth TransactionReceipt error")] EthRetrieveTransReciptError, /// Unsupported ERC-20 Token - #[fail(display = "Unsupported ERC20 Token: {}", _0)] + #[error("Unsupported ERC20 Token: {0}")] EthUnsupportedERC20TokenError(String), /// ERC-20 Token Approve Failed - #[fail(display = "ERC20 Token Approve Failed!")] + #[error("ERC20 Token Approve Failed!")] EthERC20TokenApproveError, /// Refund Time Not Arrived - #[fail(display = "Refund Time Not Arrived")] + #[error("Refund Time Not Arrived")] EthRefundTimeNotArrived, /// Transaction in Pending status - #[fail(display = "Transaction Not Confirmed")] + #[error("Transaction Not Confirmed")] EthTransactionInPending, } -impl ErrorKind { - /// Check if this error network related - pub fn is_network_error(&self) -> bool { - use ErrorKind::*; - format!(""); - match self { - Rpc(_) | ElectrumNodeClient(_) | LibWallet(crate::ErrorKind::Node(_)) => true, - _ => false, - } - } -} - -impl From for ErrorKind { - fn from(error: crate::grin_keychain::Error) -> ErrorKind { - ErrorKind::Keychain(error) - } -} - -impl From for ErrorKind { - fn from(error: multisig::ErrorKind) -> ErrorKind { - ErrorKind::Multisig(error) - } -} - -impl From for ErrorKind { - fn from(error: crate::Error) -> ErrorKind { - ErrorKind::LibWallet(error.kind()) - } -} - -// we have to use e.description because of the bug at rust-secp256k1-zkp -#[allow(deprecated)] - -impl From for ErrorKind { - fn from(error: secp::Error) -> ErrorKind { - // secp::Error to_string is broken, in past biilds. - ErrorKind::Secp(format!("{}", error.description())) - } -} - #[warn(deprecated)] -impl From for ErrorKind { - fn from(error: io::Error) -> ErrorKind { - ErrorKind::IO(format!("{}", error)) +impl From for Error { + fn from(error: io::Error) -> Error { + Error::IO(format!("{}", error)) } } -impl From for ErrorKind { - fn from(error: serde_json::Error) -> ErrorKind { - ErrorKind::Serde(format!("{}", error)) +impl From for Error { + fn from(error: serde_json::Error) -> Error { + Error::Serde(format!("{}", error)) } } -impl From for ErrorKind { - fn from(error: committed::Error) -> ErrorKind { +impl From for Error { + fn from(error: committed::Error) -> Error { match error { committed::Error::Keychain(e) => e.into(), committed::Error::Secp(e) => e.into(), - e => ErrorKind::Generic(format!("{}", e)), + e => Error::Generic(format!("{}", e)), } } } +impl From for Error { + fn from(error: crate::Error) -> Error { + Error::LibWallet(format!("{}", error)) + } +} + /// Return generic error with formatted arguments #[macro_export] macro_rules! generic { diff --git a/libwallet/src/swap/ethereum/api.rs b/libwallet/src/swap/ethereum/api.rs index 40c5d321b..70b8283a0 100644 --- a/libwallet/src/swap/ethereum/api.rs +++ b/libwallet/src/swap/ethereum/api.rs @@ -27,11 +27,11 @@ use crate::swap::types::{ BuyerContext, Context, Currency, RoleContext, SecondaryBuyerContext, SecondarySellerContext, SellerContext, SwapTransactionsConfirmations, }; -use crate::swap::{ErrorKind, SellApi, Swap, SwapApi}; +use crate::swap::{Error, SellApi, Swap, SwapApi}; use crate::{NodeClient, Slate}; -use failure::_core::marker::PhantomData; use grin_wallet_util::grin_core::core::Committed; use grin_wallet_util::grin_util::secp::Secp256k1; +use std::marker::PhantomData; use std::sync::Arc; use web3::types::{Address, H256}; @@ -92,7 +92,7 @@ where } /// Get Eth Chain Height. - pub(crate) fn eth_height(&self) -> Result { + pub(crate) fn eth_height(&self) -> Result { let c = self.eth_node_client.lock(); c.height() } @@ -102,25 +102,21 @@ where &self, swap: &Swap, address_from_secret: Option
, - ) -> Result<(u64, Option
, Address, Address, u64), ErrorKind> { + ) -> Result<(u64, Option
, Address, Address, u64), Error> { if address_from_secret.is_none() { - return Err(ErrorKind::InvalidEthSwapTradeIndex); + return Err(Error::InvalidEthSwapTradeIndex); } let c = self.eth_node_client.lock(); let res = c.get_swap_details(swap.secondary_currency, address_from_secret.unwrap()); match res { Ok((_refund_time, _contract_address, _initiator, _participant, _value)) => res, - _ => Err(ErrorKind::InvalidEthSwapTradeIndex), + _ => Err(Error::InvalidEthSwapTradeIndex), } } /// Seller call contract function to redeem their Ethers, Status::Redeem - fn seller_post_redeem_tx( - &self, - keychain: &K, - swap: &Swap, - ) -> Result { + fn seller_post_redeem_tx(&self, keychain: &K, swap: &Swap) -> Result { let c = self.eth_node_client.lock(); let eth_data = swap.secondary_data.unwrap_eth()?; let redeem_secret = SellApi::calculate_redeem_secret(keychain, swap)?; @@ -135,7 +131,7 @@ where } /// Seller transfer eth from internal wallet to users' wallet - fn seller_transfer_secondary(&self, swap: &Swap) -> Result { + fn seller_transfer_secondary(&self, swap: &Swap) -> Result { let c = self.eth_node_client.lock(); let address = swap.unwrap_seller().unwrap().0; c.transfer( @@ -152,7 +148,7 @@ where _context: &Context, swap: &mut Swap, _post_tx: bool, - ) -> Result { + ) -> Result { let c = self.eth_node_client.lock(); let eth_data = swap.secondary_data.unwrap_eth()?; c.refund( @@ -163,7 +159,7 @@ where } /// buyer deposit eth to contract address - fn erc20_approve(&self, swap: &mut Swap) -> Result { + fn erc20_approve(&self, swap: &mut Swap) -> Result { let nc = self.eth_node_client.lock(); nc.erc20_approve( swap.secondary_currency, @@ -173,18 +169,18 @@ where } /// buyer deposit eth to contract address - fn buyer_deposit(&self, swap: &mut Swap) -> Result { + fn buyer_deposit(&self, swap: &mut Swap) -> Result { let eth_lock_time = swap.get_time_secondary_lock_script() as u64; // Don't lock for more than 4 weeks. 4 weeks + 2 day, because max locking is expecting 2 weeks and 1 day to do the swap and 1 extra day for Buyer if eth_lock_time > (swap::get_cur_time() + 3600 * 24 * (7 * 4 + 2)) as u64 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "ETH locking time interval is larger than 4 weeks. Rejecting, looks like a scam." .to_string(), )); } if eth_lock_time >= u32::MAX as u64 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "ETH locking time is out of range. Rejecting, looks like a scam.".to_string(), )); } @@ -221,7 +217,7 @@ where mwc_tip: &u64, slate: &Slate, outputs_ok: bool, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let result: Option = if slate.tx_or_err()?.kernels().is_empty() { None } else { @@ -259,12 +255,9 @@ where } /// Check transaction confirm status - pub(crate) fn check_eth_transaction_status( - &self, - tx_id: Option, - ) -> Result { + pub(crate) fn check_eth_transaction_status(&self, tx_id: Option) -> Result { if tx_id.is_none() { - return Err(ErrorKind::InvalidTxHash); + return Err(Error::InvalidTxHash); } let c = self.eth_node_client.lock(); @@ -281,14 +274,14 @@ where } _ => Ok(0), }, - _ => Err(ErrorKind::EthTransactionInPending), + _ => Err(Error::EthTransactionInPending), }, - _ => Err(ErrorKind::EthRetrieveTransReciptError), + _ => Err(Error::EthRetrieveTransReciptError), } } /// check deposit transaction status - fn get_eth_initiate_tx_status(&self, swap: &Swap) -> Result { + fn get_eth_initiate_tx_status(&self, swap: &Swap) -> Result { let eth_data = swap.secondary_data.unwrap_eth()?; let eth_tip = self.eth_height()?; match self.eth_swap_details(swap, eth_data.address_from_secret.clone()) { @@ -357,7 +350,7 @@ where _keychain: &K, secondary_currency: Currency, _is_seller: bool, - ) -> Result { + ) -> Result { match secondary_currency { Currency::Ether | Currency::Busd @@ -371,7 +364,7 @@ where | Currency::Usdc | Currency::Trx | Currency::Tst => Ok(3), - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } } @@ -385,7 +378,7 @@ where change_amount: u64, keys: Vec, parent_key_id: Identifier, - ) -> Result { + ) -> Result { match secondary_currency { Currency::Ether | Currency::Busd @@ -399,7 +392,7 @@ where | Currency::Usdc | Currency::Trx | Currency::Tst => (), - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } let secp = keychain.secp(); @@ -408,7 +401,7 @@ where let eth_address = to_eth_address(ethereum_wallet.unwrap().address.clone().unwrap())?; RoleContext::Seller(SellerContext { parent_key_id: parent_key_id, - inputs: inputs.ok_or(ErrorKind::UnexpectedRole( + inputs: inputs.ok_or(Error::UnexpectedRole( "Fn create_context() for seller not found inputs".to_string(), ))?, change_output: keys.next().unwrap(), @@ -471,7 +464,7 @@ where eth_redirect_out_wallet: Option, dry_run: bool, tag: Option, - ) -> Result { + ) -> Result { match secondary_currency { Currency::Ether | Currency::Busd @@ -485,7 +478,7 @@ where | Currency::Usdc | Currency::Trx | Currency::Tst => (), - _ => return Err(ErrorKind::UnexpectedCoinType), + _ => return Err(Error::UnexpectedCoinType), } let height = self.node_client.get_chain_tip()?.0; @@ -552,7 +545,7 @@ where swap: &mut Swap, _context: &Context, _post_tx: bool, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(swap.is_seller()); let eth_data = swap.secondary_data.unwrap_eth()?; if eth_data.redeem_tx.is_some() { @@ -574,7 +567,7 @@ where &self, _keychain: &K, // keychain is kept for Type. Compiler need to understand all types swap: &Swap, - ) -> Result { + ) -> Result { let mwc_tip = self.node_client.get_chain_tip()?.0; let is_seller = swap.is_seller(); @@ -637,7 +630,7 @@ where swap: &Swap, _confirmations_needed: u64, _secp: &Secp256k1, - ) -> Result<(u64, u64, u64), ErrorKind> { + ) -> Result<(u64, u64, u64), Error> { // check eth transaction status let amount = self.get_eth_initiate_tx_status(swap)?; Ok((0, amount, 0)) @@ -732,7 +725,7 @@ where &self, swap: &Swap, _secp: &Secp256k1, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let eth_data = swap.secondary_data.unwrap_eth()?; match eth_data.address_from_secret { @@ -742,7 +735,7 @@ where } /// Check if tx fee for the secondary is different from the posted - fn is_secondary_tx_fee_changed(&self, swap: &Swap) -> Result { + fn is_secondary_tx_fee_changed(&self, swap: &Swap) -> Result { Ok(swap.secondary_data.unwrap_eth()?.tx_fee != Some(swap.secondary_fee)) } @@ -754,7 +747,7 @@ where swap: &mut Swap, _refund_address: Option, post_tx: bool, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(!swap.is_seller()); let eth_data = swap.secondary_data.unwrap_eth()?; @@ -774,7 +767,7 @@ where } /// deposit secondary currecny to lock account. - fn post_secondary_lock_tx(&self, swap: &mut Swap) -> Result<(), ErrorKind> { + fn post_secondary_lock_tx(&self, swap: &mut Swap) -> Result<(), Error> { assert!(!swap.is_seller()); let eth_data = swap.secondary_data.unwrap_eth()?; @@ -794,7 +787,7 @@ where let eth_data = swap.secondary_data.unwrap_eth_mut()?; eth_data.lock_tx = Some(eth_tx); } else { - return Err(ErrorKind::EthERC20TokenApproveError); + return Err(Error::EthERC20TokenApproveError); } } else { let erc20_approve_tx = self.erc20_approve(swap)?; @@ -811,19 +804,19 @@ where } /// transfer amount to dedicated address. - fn transfer_scondary(&self, swap: &mut Swap) -> Result<(), ErrorKind> { + fn transfer_scondary(&self, swap: &mut Swap) -> Result<(), Error> { assert!(swap.is_seller()); self.seller_transfer_secondary(swap)?; Ok(()) } - fn test_client_connections(&self) -> Result<(), ErrorKind> { + fn test_client_connections(&self) -> Result<(), Error> { { let c = self.eth_node_client.lock(); let name = c.name(); let _ = c.height().map_err(|e| { - ErrorKind::InfuraNodeClient(format!( + Error::InfuraNodeClient(format!( "Unable to contact Ethereum client {}, {}", name, e )) diff --git a/libwallet/src/swap/ethereum/client.rs b/libwallet/src/swap/ethereum/client.rs index 2ec241f53..f0809e45e 100644 --- a/libwallet/src/swap/ethereum/client.rs +++ b/libwallet/src/swap/ethereum/client.rs @@ -14,7 +14,7 @@ use crate::grin_util::Mutex; use crate::swap::types::Currency; -use crate::swap::ErrorKind; +use crate::swap::Error; use secp256k1::SecretKey; use std::sync::Arc; use std::{collections::HashMap, u64}; @@ -27,15 +27,15 @@ pub trait EthNodeClient: Sync + Send + 'static { /// Name of this client. Normally it is URL fn name(&self) -> String; /// Get node height - fn height(&self) -> Result; + fn height(&self) -> Result; /// Get balance for the address - fn balance(&self, currency: Currency) -> Result<(String, u64), ErrorKind>; + fn balance(&self, currency: Currency) -> Result<(String, u64), Error>; /// Retrieve receipt - fn retrieve_receipt(&self, tx_hash: H256) -> Result; + fn retrieve_receipt(&self, tx_hash: H256) -> Result; /// Send coins to destination account - fn transfer(&self, currency: Currency, to: Address, value: u64) -> Result; + fn transfer(&self, currency: Currency, to: Address, value: u64) -> Result; /// erc20 approve - fn erc20_approve(&self, currency: Currency, value: u64, gas: f32) -> Result; + fn erc20_approve(&self, currency: Currency, value: u64, gas: f32) -> Result; /// initiate swap fn initiate( &self, @@ -45,7 +45,7 @@ pub trait EthNodeClient: Sync + Send + 'static { participant: Address, value: u64, gas: f32, - ) -> Result; + ) -> Result; /// redeem ether fn redeem( &self, @@ -53,20 +53,20 @@ pub trait EthNodeClient: Sync + Send + 'static { address_from_secret: Address, secret_key: SecretKey, gas: f32, - ) -> Result; + ) -> Result; /// refund ether fn refund( &self, currency: Currency, address_from_secret: Address, gas: f32, - ) -> Result; + ) -> Result; /// get swap info fn get_swap_details( &self, currency: Currency, address_from_secret: Address, - ) -> Result<(u64, Option
, Address, Address, u64), ErrorKind>; + ) -> Result<(u64, Option
, Address, Address, u64), Error>; } /// Mock Eth node for the testing @@ -121,17 +121,17 @@ impl EthNodeClient for TestEthNodeClient { } /// Fetch the current chain height - fn height(&self) -> Result { + fn height(&self) -> Result { Ok(self.state.lock().height) } /// get wallet balance - fn balance(&self, _currency: Currency) -> Result<(String, u64), ErrorKind> { + fn balance(&self, _currency: Currency) -> Result<(String, u64), Error> { Ok(("1.00".to_string(), 1_000_000_000_000_000_000u64)) } /// Retrieve receipt - fn retrieve_receipt(&self, tx_hash: H256) -> Result { + fn retrieve_receipt(&self, tx_hash: H256) -> Result { let receipt_str = r#"{ "blockHash": "0x83eaba432089a0bfe99e9fc9022d1cfcb78f95f407821be81737c84ae0b439c5", "blockNumber": "0x38", @@ -152,16 +152,11 @@ impl EthNodeClient for TestEthNodeClient { } /// Send coins - fn transfer(&self, _currency: Currency, _to: Address, _value: u64) -> Result { + fn transfer(&self, _currency: Currency, _to: Address, _value: u64) -> Result { unimplemented!() } - fn erc20_approve( - &self, - _currency: Currency, - _value: u64, - _gas: f32, - ) -> Result { + fn erc20_approve(&self, _currency: Currency, _value: u64, _gas: f32) -> Result { unimplemented!() } @@ -174,11 +169,11 @@ impl EthNodeClient for TestEthNodeClient { participant: Address, value: u64, _gas: f32, - ) -> Result { + ) -> Result { //todo need to check balance let mut store = self.swap_store.lock(); if store.contains_key(&address_from_secret) { - return Err(ErrorKind::InvalidEthSwapTradeIndex); + return Err(Error::InvalidEthSwapTradeIndex); } store.insert( address_from_secret, @@ -206,7 +201,7 @@ impl EthNodeClient for TestEthNodeClient { address_from_secret: Address, _secret_key: SecretKey, _gas: f32, - ) -> Result { + ) -> Result { let mut store = self.swap_store.lock(); if store.contains_key(&address_from_secret) { let mut txs = self.tx_store.lock(); @@ -224,7 +219,7 @@ impl EthNodeClient for TestEthNodeClient { _currency: Currency, address_from_secret: Address, _gas: f32, - ) -> Result { + ) -> Result { let mut store = self.swap_store.lock(); if store.contains_key(&address_from_secret) { let mut txs = self.tx_store.lock(); @@ -241,12 +236,12 @@ impl EthNodeClient for TestEthNodeClient { &self, _currency: Currency, address_from_secret: Address, - ) -> Result<(u64, Option
, Address, Address, u64), ErrorKind> { + ) -> Result<(u64, Option
, Address, Address, u64), Error> { let store = self.swap_store.lock(); if store.contains_key(&address_from_secret) { Ok(store[&address_from_secret]) } else { - Err(ErrorKind::InvalidEthSwapTradeIndex) + Err(Error::InvalidEthSwapTradeIndex) } } } diff --git a/libwallet/src/swap/ethereum/ethereum.rs b/libwallet/src/swap/ethereum/ethereum.rs index e2e262129..086517091 100644 --- a/libwallet/src/swap/ethereum/ethereum.rs +++ b/libwallet/src/swap/ethereum/ethereum.rs @@ -12,9 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::ErrorKind; +use crate::Error; use colored::*; -use failure::Fail; use rand::Rng; use serde::{Deserialize, Serialize}; use std::{fmt, fmt::Display, str::FromStr}; @@ -31,43 +30,43 @@ use wagyu_model::{ }; /// Ethereum Error -#[derive(Debug, Fail)] +#[derive(Debug, thiserror::Error)] pub enum EthError { /// Address error - #[fail(display = "{}", _0)] + #[error("{0}")] AddressError(AddressError), /// Amount error - #[fail(display = "{}", _0)] + #[error("#[from] {0}")] AmountError(AmountError), /// Crate error - #[fail(display = "{}: {}", _0, _1)] + #[error("{0}: {1}")] Crate(&'static str, String), /// Derivation Path Error - #[fail(display = "{}", _0)] + #[error("{0}")] DerivationPathError(DerivationPathError), /// ExtendedPrivateKey Error - #[fail(display = "{}", _0)] + #[error("{0}")] ExtendedPrivateKeyError(ExtendedPrivateKeyError), /// ExtendedPublicKey Error - #[fail(display = "{}", _0)] + #[error("{0}")] ExtendedPublicKeyError(ExtendedPublicKeyError), /// InvalidMnemonicForPrivateSpendKey - #[fail(display = "invalid derived mnemonic for a given private spend key")] + #[error("invalid derived mnemonic for a given private spend key")] InvalidMnemonicForPrivateSpendKey, /// PrivateKeyError - #[fail(display = "{}", _0)] + #[error("{0}")] PrivateKeyError(PrivateKeyError), /// PublicKeyError - #[fail(display = "{}", _0)] + #[error("{0}")] PublicKeyError(PublicKeyError), /// MnemonicError - #[fail(display = "{}", _0)] + #[error("{0}")] MnemonicError(MnemonicError), /// TransactionError - #[fail(display = "{}", _0)] + #[error("{0}")] TransactionError(TransactionError), /// Unsupported Mnemonic Language - #[fail(display = "unsupported mnemonic language")] + #[error("unsupported mnemonic language")] UnsupportedLanguage, } @@ -77,12 +76,6 @@ impl From for EthError { } } -impl From for EthError { - fn from(error: AmountError) -> Self { - EthError::AmountError(error) - } -} - impl From for EthError { fn from(error: core::num::ParseIntError) -> Self { EthError::Crate("parse_int", format!("{:?}", error)) @@ -142,6 +135,7 @@ impl From for EthError { EthError::TransactionError(error) } } + /// Represents parameters for an Ethereum transaction input #[derive(Debug, Serialize, Deserialize, Clone)] pub struct EthereumInput { @@ -452,7 +446,7 @@ pub fn generate_ethereum_wallet( mnemonic: &str, password: &str, path: &str, -) -> Result { +) -> Result { let ethereum_wallet = match network { "mainnet" => { EthereumWallet::from_mnemonic::(mnemonic, Some(password), path) @@ -462,10 +456,8 @@ pub fn generate_ethereum_wallet( match ethereum_wallet { Ok(w) => Ok(w), - Err(e) => Err(ErrorKind::EthereumWalletError(format!( - "create ethereum wallet failed!, {}", - e - )) - .into()), + Err(e) => { + Err(Error::EthereumWalletError(format!("create ethereum wallet failed!, {}", e)).into()) + } } } diff --git a/libwallet/src/swap/ethereum/infura.rs b/libwallet/src/swap/ethereum/infura.rs index 0417e4627..df785e1b1 100644 --- a/libwallet/src/swap/ethereum/infura.rs +++ b/libwallet/src/swap/ethereum/infura.rs @@ -20,7 +20,7 @@ use crate::swap::is_test_mode; #[cfg(test)] use crate::swap::set_test_mode; use crate::swap::types::Currency; -use crate::swap::ErrorKind; +use crate::swap::Error; use crossbeam_utils::thread::scope; use rand::thread_rng; use secp256k1::SecretKey; @@ -76,7 +76,7 @@ impl InfuraNodeClient { wallet: EthereumWallet, contract_addr: String, erc20_contract_addr: String, - ) -> Result { + ) -> Result { let client = Self { project_id, chain, @@ -89,7 +89,7 @@ impl InfuraNodeClient { } /// get ether balance - pub fn ether_balance(&self) -> Result<(String, u64), ErrorKind> { + pub fn ether_balance(&self) -> Result<(String, u64), Error> { let task = async move { let account = to_eth_address(self.wallet.address.clone().unwrap()).unwrap(); let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); @@ -122,22 +122,22 @@ impl InfuraNodeClient { let balance = to_norm(balance_gwei.to_string().as_str(), "9"); Ok((format!("{}", balance.with_scale(6)), balance_gwei.as_u64())) } - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get Ether Balance Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get Ether Balance Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get Ether Balance Failed!".to_string(), )), } } /// get erc20 token balance - pub fn erc20_balance(&self, currency: Currency) -> Result<(String, u64), ErrorKind> { + pub fn erc20_balance(&self, currency: Currency) -> Result<(String, u64), Error> { let token_address = currency.erc20_token_address()?; let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); @@ -197,22 +197,22 @@ impl InfuraNodeClient { ); Ok((format!("{}", balance_norm), balance.as_u64())) } - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get ERC20 Token Balance Of Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get ERC20 Token Balance Of Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get ERC20 Token Balance Of Failed!".to_string(), )), } } /// ether transfer - fn ether_transfer(&self, to: Address, value: U256, gas_limit: U256) -> Result { + fn ether_transfer(&self, to: Address, value: U256, gas_limit: U256) -> Result { let task = async move { // get web3 handle let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); @@ -268,22 +268,22 @@ impl InfuraNodeClient { Ok(res) => match res { Ok(res) => match res { Ok(tx_hash) => Ok(tx_hash), - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "eth transfer failure!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "eth transfer failure!".to_string(), )), }, Err(e) => { warn!("transfer error: --- {:?}", e); - Err(ErrorKind::EthContractCallError( + Err(Error::EthContractCallError( "eth transfer failure!".to_string(), )) } }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "eth transfer failure!".to_string(), )), } @@ -296,7 +296,7 @@ impl InfuraNodeClient { to: Address, value: U256, gas_limit: U256, - ) -> Result { + ) -> Result { let token_address = currency.erc20_token_address()?; let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); @@ -355,16 +355,16 @@ impl InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("erc20_transfer error: --- {:?}", e); - Err(ErrorKind::EthContractCallError( + Err(Error::EthContractCallError( "ERC20 Transfer Failed!".to_string(), )) } }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "ERC20 Transfer Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "ERC20 Transfer Failed!".to_string(), )), } @@ -378,7 +378,7 @@ impl InfuraNodeClient { participant: Address, value: U256, gas_limit: U256, - ) -> Result { + ) -> Result { let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); let transport = web3::transports::WebSocket::new(url.as_str()).await; @@ -443,16 +443,16 @@ impl InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("ether initiate error: --- {:?}", e); - Err(ErrorKind::EthContractCallError( + Err(Error::EthContractCallError( "Buyer Initiate Ether Swap Trade Failed!".to_string(), )) } }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Buyer Initiate Ether Swap Trade Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Buyer Initiate Ether Swap Trade Failed!".to_string(), )), } @@ -467,7 +467,7 @@ impl InfuraNodeClient { participant: Address, value: U256, gas_limit: U256, - ) -> Result { + ) -> Result { let token_address = currency.erc20_token_address()?; let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); @@ -539,18 +539,18 @@ impl InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("erc20 initiate error: --- {:?}", e); - Err(ErrorKind::EthContractCallError(format!( + Err(Error::EthContractCallError(format!( "Buyer Initiate {} Swap Trade Failed!", Currency::Btc ))) } }, - _ => Err(ErrorKind::EthContractCallError(format!( + _ => Err(Error::EthContractCallError(format!( "Buyer Initiate {} Swap Trade Failed!", Currency::Ether ))), }, - _ => Err(ErrorKind::EthContractCallError(format!( + _ => Err(Error::EthContractCallError(format!( "Buyer Initiate {} Swap Trade Failed!", Currency::Usdc ))), @@ -563,7 +563,7 @@ impl InfuraNodeClient { address_from_secret: Address, secret_key: SecretKey, gas_limit: U256, - ) -> Result { + ) -> Result { let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); let transport = web3::transports::WebSocket::new(url.as_str()).await; @@ -682,16 +682,16 @@ impl InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("redeem error: --- {:?}", e); - Err(ErrorKind::EthContractCallError( + Err(Error::EthContractCallError( "Seller Redeem Ether Failed!".to_string(), )) } }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Seller Redeem Ether Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Seller Redeem Ether Failed!".to_string(), )), } @@ -703,7 +703,7 @@ impl InfuraNodeClient { address_from_secret: Address, secret_key: SecretKey, gas_limit: U256, - ) -> Result { + ) -> Result { // let token_address = currency.erc20_token_address()?; let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); @@ -823,16 +823,16 @@ impl InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("redeem error: --- {:?}", e); - Err(ErrorKind::EthContractCallError( + Err(Error::EthContractCallError( "Seller Redeem ERC20-Token Failed!".to_string(), )) } }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Seller Redeem ERC20-Token Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Seller Redeem ERC20-Token Failed!".to_string(), )), } @@ -846,7 +846,7 @@ impl EthNodeClient for InfuraNodeClient { } /// Fetch the current chain height - fn height(&self) -> Result { + fn height(&self) -> Result { let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); let transport = web3::transports::WebSocket::new(url.as_str()).await; @@ -874,22 +874,22 @@ impl EthNodeClient for InfuraNodeClient { Ok(res) => match res { Ok(res) => match res { Ok(block_number) => Ok(block_number.as_u64()), - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get Ethereum Height Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get Ethereum Height Failed!".to_string(), )), }, - _ => Err(ErrorKind::EthContractCallError( + _ => Err(Error::EthContractCallError( "Get Ethereum Height Failed!".to_string(), )), } } /// get wallet balance - fn balance(&self, currency: Currency) -> Result<(String, u64), ErrorKind> { + fn balance(&self, currency: Currency) -> Result<(String, u64), Error> { if !currency.is_erc20() { self.ether_balance() } else { @@ -898,7 +898,7 @@ impl EthNodeClient for InfuraNodeClient { } /// Retrieve transaction receipt - fn retrieve_receipt(&self, tx_hash: H256) -> Result { + fn retrieve_receipt(&self, tx_hash: H256) -> Result { let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); let transport = web3::transports::WebSocket::new(url.as_str()).await; @@ -928,20 +928,20 @@ impl EthNodeClient for InfuraNodeClient { Some(res) => match res { Ok(res) => match res { Some(receipt) => Ok(receipt), - _ => Err(ErrorKind::EthRetrieveTransReciptError), + _ => Err(Error::EthRetrieveTransReciptError), }, - _ => Err(ErrorKind::EthRetrieveTransReciptError), + _ => Err(Error::EthRetrieveTransReciptError), }, - _ => Err(ErrorKind::EthRetrieveTransReciptError), + _ => Err(Error::EthRetrieveTransReciptError), }, - _ => Err(ErrorKind::EthRetrieveTransReciptError), + _ => Err(Error::EthRetrieveTransReciptError), }, - _ => Err(ErrorKind::EthRetrieveTransReciptError), + _ => Err(Error::EthRetrieveTransReciptError), } } /// Send coins - fn transfer(&self, currency: Currency, to: Address, value: u64) -> Result { + fn transfer(&self, currency: Currency, to: Address, value: u64) -> Result { let gas_limit = U256::from(TRANSACTION_DEFAULT_GAS_LIMIT * 1000_000_000u64); let balance_ether = self.balance(Currency::Ether)?; let balance_ether = U256::from(balance_ether.1) * U256::exp10(9); @@ -949,12 +949,12 @@ impl EthNodeClient for InfuraNodeClient { if !currency.is_erc20() { let value = U256::from(value) * U256::exp10(9); if balance_ether < gas_limit + value { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } self.ether_transfer(to, value, gas_limit) } else { if balance_ether < gas_limit { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } let balance_token = self.balance(currency)?; @@ -969,10 +969,7 @@ impl EthNodeClient for InfuraNodeClient { }; if balance_token < value { - return Err(ErrorKind::ERC20TokenBalanceNotEnough(format!( - "{}", - currency - ))); + return Err(Error::ERC20TokenBalanceNotEnough(format!("{}", currency))); } self.erc20_transfer(currency, to, value, gas_limit) @@ -980,13 +977,13 @@ impl EthNodeClient for InfuraNodeClient { } /// erc20 approve swap offer - fn erc20_approve(&self, currency: Currency, value: u64, gas: f32) -> Result { + fn erc20_approve(&self, currency: Currency, value: u64, gas: f32) -> Result { let gas_limit = U256::from(gas as u64) * 1000_000_000u64; let balance_ether = self.balance(Currency::Ether)?; let balance_ether = U256::from(balance_ether.1) * U256::exp10(9); if balance_ether < gas_limit { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } let balance_token = self.balance(currency)?; @@ -1002,10 +999,7 @@ impl EthNodeClient for InfuraNodeClient { }; if balance_token < value { - return Err(ErrorKind::ERC20TokenBalanceNotEnough(format!( - "{}", - currency - ))); + return Err(Error::ERC20TokenBalanceNotEnough(format!("{}", currency))); } let token_address = currency.erc20_token_address()?; @@ -1073,18 +1067,18 @@ impl EthNodeClient for InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("erc20 approve error: --- {:?}", e); - Err(ErrorKind::EthContractCallError(format!( + Err(Error::EthContractCallError(format!( "{}: ERC20 ApproveFailed!", currency ))) } }, - _ => Err(ErrorKind::EthContractCallError(format!( + _ => Err(Error::EthContractCallError(format!( "{}: ERC20 ApproveFailed!", currency ))), }, - _ => Err(ErrorKind::EthContractCallError(format!( + _ => Err(Error::EthContractCallError(format!( "{}: ERC20 ApproveFailed!", currency ))), @@ -1100,7 +1094,7 @@ impl EthNodeClient for InfuraNodeClient { participant: Address, value: u64, gas: f32, - ) -> Result { + ) -> Result { let gas_limit = U256::from(gas as u64) * 1000_000_000u64; let balance_ether = self.balance(Currency::Ether)?; let balance_ether = U256::from(balance_ether.1) * U256::exp10(9); @@ -1108,7 +1102,7 @@ impl EthNodeClient for InfuraNodeClient { if !currency.is_erc20() { let value = U256::from(value) * U256::exp10(9); if balance_ether < gas_limit + value { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } self.ether_initiate( @@ -1121,7 +1115,7 @@ impl EthNodeClient for InfuraNodeClient { } else { // one gas_limit for approve, the other one for initiate if balance_ether < gas_limit { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } let value = match currency.is_expo_shrinked18to9() { @@ -1147,12 +1141,12 @@ impl EthNodeClient for InfuraNodeClient { address_from_secret: Address, secret_key: SecretKey, gas_limit: f32, - ) -> Result { + ) -> Result { let gas_limit = U256::from(gas_limit as u64) * 1000_000_000u64; let balance_ether = self.balance(Currency::Ether)?; let balance_ether = U256::from(balance_ether.1) * U256::exp10(9); if balance_ether < gas_limit { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } if !currency.is_erc20() { @@ -1168,12 +1162,12 @@ impl EthNodeClient for InfuraNodeClient { currency: Currency, address_from_secret: Address, gas_limit: f32, - ) -> Result { + ) -> Result { let gas_limit = U256::from(gas_limit as u64) * U256::exp10(9); let balance_ether = self.balance(Currency::Ether)?; let balance_ether = U256::from(balance_ether.1) * U256::exp10(9); if balance_ether < gas_limit { - return Err(ErrorKind::EthBalanceNotEnough); + return Err(Error::EthBalanceNotEnough); } let height = self.height()?; @@ -1184,7 +1178,7 @@ impl EthNodeClient for InfuraNodeClient { height, refund_time_blocks ); if height < refund_time_blocks { - return Err(ErrorKind::EthRefundTimeNotArrived); + return Err(Error::EthRefundTimeNotArrived); } let task = async move { @@ -1262,18 +1256,18 @@ impl EthNodeClient for InfuraNodeClient { Ok(tx_hash) => Ok(tx_hash), Err(e) => { warn!("refund error: --- {:?}", e); - Err(ErrorKind::EthContractCallError(format!( + Err(Error::EthContractCallError(format!( "Buyer Refund {} Failed!", currency ))) } }, - _ => Err(ErrorKind::EthContractCallError(format!( + _ => Err(Error::EthContractCallError(format!( "Buyer Refund {} Failed!", currency ))), }, - _ => Err(ErrorKind::EthContractCallError(format!( + _ => Err(Error::EthContractCallError(format!( "Buyer Refund {} Failed!", currency ))), @@ -1285,7 +1279,7 @@ impl EthNodeClient for InfuraNodeClient { &self, currency: Currency, address_from_secret: Address, - ) -> Result<(u64, Option
, Address, Address, u64), ErrorKind> { + ) -> Result<(u64, Option
, Address, Address, u64), Error> { let task = async move { let url = format!("wss://{}.infura.io/ws/v3/{}", self.chain, self.project_id); let transport = web3::transports::WebSocket::new(url.as_str()).await; @@ -1372,22 +1366,22 @@ impl EthNodeClient for InfuraNodeClient { balance.as_u64(), )) } - _ => Err(ErrorKind::InfuraNodeClient(format!( + _ => Err(Error::InfuraNodeClient(format!( "Get Swap Details {} Failed!", currency ))), }, - _ => Err(ErrorKind::InfuraNodeClient(format!( + _ => Err(Error::InfuraNodeClient(format!( "Get Swap Details {} Failed!", currency ))), }, - _ => Err(ErrorKind::InfuraNodeClient(format!( + _ => Err(Error::InfuraNodeClient(format!( "Get Swap Details {} Failed!", currency ))), }, - _ => Err(ErrorKind::InfuraNodeClient(format!( + _ => Err(Error::InfuraNodeClient(format!( "Get Swap Details {} Failed!", currency ))), diff --git a/libwallet/src/swap/ethereum/types.rs b/libwallet/src/swap/ethereum/types.rs index dc240b890..98e383341 100644 --- a/libwallet/src/swap/ethereum/types.rs +++ b/libwallet/src/swap/ethereum/types.rs @@ -16,7 +16,7 @@ use crate::grin_util::to_hex; use crate::swap::message::SecondaryUpdate; use crate::swap::ser::*; use crate::swap::types::SecondaryData; -use crate::swap::ErrorKind; +use crate::swap::Error; use regex::Regex; use web3::types::{Address, H256}; @@ -50,7 +50,7 @@ pub struct EthData { impl EthData { /// Create seller ETH data (party that receive ETH). pub(crate) fn new(context: &EthSellerContext, // Derivarive index - ) -> Result { + ) -> Result { Ok(Self { redeem_address: context.redeem_address, address_from_secret: None, @@ -66,7 +66,7 @@ impl EthData { pub(crate) fn from_offer( offer: EthOfferUpdate, context: &EthBuyerContext, - ) -> Result { + ) -> Result { Ok(Self { redeem_address: offer.redeem_address, address_from_secret: context.address_from_secret, @@ -82,7 +82,7 @@ impl EthData { pub(crate) fn accepted_offer( &mut self, accepted_offer: EthAcceptOfferUpdate, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { self.lock_tx = accepted_offer.lock_tx; self.address_from_secret = accepted_offer.address_from_secret; Ok(()) @@ -133,20 +133,20 @@ pub enum EthUpdate { impl EthUpdate { /// Unwrap EthOfferUpdate with data type verification - pub fn unwrap_offer(self) -> Result { + pub fn unwrap_offer(self) -> Result { match self { EthUpdate::Offer(u) => Ok(u), - _ => Err(ErrorKind::UnexpectedMessageType( + _ => Err(Error::UnexpectedMessageType( "Fn unwrap_offer() expecting EthUpdate::Offer".to_string(), )), } } /// Unwrap EthAcceptOfferUpdate with data type verification - pub fn unwrap_accept_offer(self) -> Result { + pub fn unwrap_accept_offer(self) -> Result { match self { EthUpdate::AcceptOffer(u) => Ok(u), - _ => Err(ErrorKind::UnexpectedMessageType( + _ => Err(Error::UnexpectedMessageType( "Fn unwrap_accept_offer() expecting BtcUpdate::AcceptOffer".to_string(), )), } @@ -175,13 +175,13 @@ pub struct EthAcceptOfferUpdate { } /// to web3 Address -pub fn to_eth_address(address: String) -> Result { +pub fn to_eth_address(address: String) -> Result { let regex = Regex::new(r"^0x").unwrap(); let address = address.to_lowercase(); let address = regex.replace_all(&address, "").to_string(); if address.len() != 40 { - return Err(ErrorKind::InvalidEthAddress); + return Err(Error::InvalidEthAddress); } let mut address_slice = [0u8; 20]; address_slice.copy_from_slice(hex::decode(address).unwrap().as_slice()); @@ -198,12 +198,12 @@ pub fn eth_address(address: Address) -> String { } /// to eth transaction hash -pub fn to_eth_tx_hash(tx_hash: String) -> Result { +pub fn to_eth_tx_hash(tx_hash: String) -> Result { let regex = Regex::new(r"^0x").unwrap(); let hash = regex.replace_all(&tx_hash, "").to_string(); if hash.len() != 64 { - return Err(ErrorKind::InvalidTxHash); + return Err(Error::InvalidTxHash); } let mut hash_slice = [0u8; 32]; hash_slice.copy_from_slice(hex::decode(hash).unwrap().as_slice()); diff --git a/libwallet/src/swap/fsm/buyer_swap.rs b/libwallet/src/swap/fsm/buyer_swap.rs index 19c8b114c..0b9a77e3c 100644 --- a/libwallet/src/swap/fsm/buyer_swap.rs +++ b/libwallet/src/swap/fsm/buyer_swap.rs @@ -24,11 +24,11 @@ use crate::swap::fsm::state::{Input, State, StateEtaInfo, StateId, StateProcessR use crate::swap::message::Message; use crate::swap::swap; use crate::swap::types::{check_txs_confirmed, Action, SwapTransactionsConfirmations}; -use crate::swap::{BuyApi, Context, ErrorKind, Swap, SwapApi}; +use crate::swap::{BuyApi, Context, Error, Swap, SwapApi}; use crate::NodeClient; use chrono::{Local, TimeZone}; -use failure::_core::marker::PhantomData; use grin_wallet_util::grin_util::secp::Secp256k1; +use std::marker::PhantomData; use std::sync::Arc; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -63,7 +63,7 @@ impl State for BuyerOfferCreated { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -72,7 +72,7 @@ impl State for BuyerOfferCreated { Input::Check => Ok(StateProcessRespond::new( StateId::BuyerSendingAcceptOfferMessage, )), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerOfferCreated get {:?}", input ))), @@ -138,7 +138,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -194,7 +194,7 @@ where StateId::BuyerWaitingForSellerToLock, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerSendingAcceptOfferMessage get {:?}", input ))), @@ -246,7 +246,7 @@ impl State for BuyerWaitingForSellerToLock { _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -317,7 +317,7 @@ impl State for BuyerWaitingForSellerToLock { } } } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerWaitingForSellerToLock get {:?}", input ))), @@ -389,7 +389,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -487,7 +487,7 @@ where Input::Execute => { // for btc family, buyer should deposit secondary currency manually. if swap.secondary_currency.is_btc_family() { - return Err(ErrorKind::InvalidSwapStateInput(format!( + return Err(Error::InvalidSwapStateInput(format!( "BuyerPostingSecondaryToMultisigAccount get {:?}", input ))); @@ -497,7 +497,7 @@ where StateId::BuyerPostingSecondaryToMultisigAccount, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerPostingSecondaryToMultisigAccount get {:?}", input ))), @@ -557,7 +557,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -657,7 +657,7 @@ where StateId::BuyerSendingInitRedeemMessage, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerWaitingForLockConfirmations get {:?}", input ))), @@ -702,7 +702,7 @@ impl State for BuyerSendingInitRedeemMessage { _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -764,7 +764,7 @@ impl State for BuyerSendingInitRedeemMessage { StateId::BuyerWaitingForRespondRedeemMessage, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerSendingInitRedeemMessage get {:?}", input ))), @@ -813,7 +813,7 @@ impl State for BuyerWaitingForRespondRedeemMessage { height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -891,7 +891,7 @@ impl State for BuyerWaitingForRespondRedeemMessage { .is_ok()); Ok(StateProcessRespond::new(StateId::BuyerRedeemMwc)) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerWaitingForRespondRedeemMessage get {:?}", input ))), @@ -952,7 +952,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { let time_limit = swap.get_time_mwc_redeem(); match input { Input::Cancel => { @@ -1030,7 +1030,7 @@ where Ok(StateProcessRespond::new( StateId::BuyerWaitForRedeemMwcConfirmations, )) - } /*_ => Err(ErrorKind::InvalidSwapStateInput(format!( + } /*_ => Err(Error::InvalidSwapStateInput(format!( "BuyerRedeemMwc get {:?}", input ))),*/ @@ -1075,7 +1075,7 @@ impl State for BuyerWaitForRedeemMwcConfirmations { _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Check the deadline for locking @@ -1117,7 +1117,7 @@ impl State for BuyerWaitForRedeemMwcConfirmations { StateId::BuyerWaitForRedeemMwcConfirmations, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerWaitForRedeemMwcConfirmations get {:?}", input ))), @@ -1163,10 +1163,10 @@ impl State for BuyerSwapComplete { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => Ok(StateProcessRespond::new(StateId::BuyerSwapComplete)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerSwapComplete get {:?}", input ))), @@ -1213,10 +1213,10 @@ impl State for BuyerCancelled { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => Ok(StateProcessRespond::new(StateId::BuyerCancelled)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerCancelled get {:?}", input ))), @@ -1271,7 +1271,7 @@ impl State for BuyerWaitingForRefundTime { _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Just chilling. MWC redeem was never posted, so Seller can't get BTC. But still checking for what if @@ -1302,7 +1302,7 @@ impl State for BuyerWaitingForRefundTime { }) .time_limit(time_limit)) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerWaitingForRefundTime get {:?}", input ))), @@ -1373,7 +1373,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { let cur_time = swap::get_cur_time(); @@ -1420,7 +1420,7 @@ where StateId::BuyerWaitingForRefundConfirmations, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerPostingRefundForSecondary get {:?}", input ))), @@ -1486,7 +1486,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { if let Some(conf) = tx_conf.secondary_refund_conf { @@ -1537,7 +1537,7 @@ where ), ) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerWaitingForRefundConfirmations get {:?}", input ))), @@ -1584,10 +1584,10 @@ impl State for BuyerCancelledRefunded { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => Ok(StateProcessRespond::new(StateId::BuyerCancelledRefunded)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "BuyerCancelledRefunded get {:?}", input ))), diff --git a/libwallet/src/swap/fsm/machine.rs b/libwallet/src/swap/fsm/machine.rs index bc557ab29..f6a48062b 100644 --- a/libwallet/src/swap/fsm/machine.rs +++ b/libwallet/src/swap/fsm/machine.rs @@ -14,7 +14,7 @@ use crate::swap::fsm::state::{Input, State, StateEtaInfo, StateId, StateProcessRespond}; use crate::swap::types::SwapTransactionsConfirmations; -use crate::swap::{Context, ErrorKind, Swap}; +use crate::swap::{Context, Error, Swap}; use grin_wallet_util::grin_util::secp::Secp256k1; use std::collections::HashMap; @@ -47,11 +47,11 @@ impl<'a> StateMachine<'a> { } /// Check if this trade can be cancelled. - pub fn is_cancellable(&self, swap: &Swap) -> Result { + pub fn is_cancellable(&self, swap: &Swap) -> Result { let state = self .state_map .get(&swap.state) - .ok_or(ErrorKind::SwapStateMachineError(format!( + .ok_or(Error::SwapStateMachineError(format!( "Unknown state {:?}", swap.state )))?; @@ -72,7 +72,7 @@ impl<'a> StateMachine<'a> { height: u64, tx_conf: &SwapTransactionsConfirmations, secp: &Secp256k1, - ) -> Result { + ) -> Result { debug!( "Swap {} processing state {:?} for Input {:?}", swap.id, swap.state, input @@ -81,7 +81,7 @@ impl<'a> StateMachine<'a> { let state = self .state_map .get_mut(&swap.state) - .ok_or(ErrorKind::SwapStateMachineError(format!( + .ok_or(Error::SwapStateMachineError(format!( "Unknown state {:?}", swap.state )))?; @@ -90,13 +90,13 @@ impl<'a> StateMachine<'a> { while respond.next_state_id != swap.state { debug!("New state: {:?}", swap.state); swap.state = respond.next_state_id.clone(); - let state = - self.state_map - .get_mut(&swap.state) - .ok_or(ErrorKind::SwapStateMachineError(format!( - "Unknown state {:?}", - swap.state - )))?; + let state = self + .state_map + .get_mut(&swap.state) + .ok_or(Error::SwapStateMachineError(format!( + "Unknown state {:?}", + swap.state + )))?; respond = state.process(Input::Check, swap, context, height, tx_conf, secp)?; } respond.journal = swap.journal.clone(); @@ -110,11 +110,11 @@ impl<'a> StateMachine<'a> { &self, swap: &Swap, secp: &Secp256k1, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let state = self .state_map .get(&swap.state) - .ok_or(ErrorKind::SwapStateMachineError(format!( + .ok_or(Error::SwapStateMachineError(format!( "Unknown state {:?}", swap.state )))?; @@ -128,7 +128,7 @@ impl<'a> StateMachine<'a> { let prev_state = self .state_map .get(&psid) - .ok_or(ErrorKind::SwapStateMachineError(format!( + .ok_or(Error::SwapStateMachineError(format!( "Unknown state {:?}", psid )))?; @@ -148,7 +148,7 @@ impl<'a> StateMachine<'a> { let next_state = self .state_map .get(&nsid) - .ok_or(ErrorKind::SwapStateMachineError(format!( + .ok_or(Error::SwapStateMachineError(format!( "Unknown state {:?}", nsid )))?; diff --git a/libwallet/src/swap/fsm/seller_swap.rs b/libwallet/src/swap/fsm/seller_swap.rs index b9661dcda..76a60fe3f 100644 --- a/libwallet/src/swap/fsm/seller_swap.rs +++ b/libwallet/src/swap/fsm/seller_swap.rs @@ -23,11 +23,11 @@ use crate::swap::fsm::state; use crate::swap::fsm::state::{Input, State, StateEtaInfo, StateId, StateProcessRespond}; use crate::swap::message::Message; use crate::swap::types::{check_txs_confirmed, Action, Currency, SwapTransactionsConfirmations}; -use crate::swap::{swap, Context, ErrorKind, SellApi, Swap, SwapApi}; +use crate::swap::{swap, Context, Error, SellApi, Swap, SwapApi}; use crate::NodeClient; use chrono::{Local, TimeZone}; -use failure::_core::marker::PhantomData; use grin_wallet_util::grin_util::secp::Secp256k1; +use std::marker::PhantomData; use std::sync::Arc; /// State SellerOfferCreated @@ -60,14 +60,14 @@ impl State for SellerOfferCreated { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); Ok(StateProcessRespond::new(StateId::SellerCancelled)) } Input::Check => Ok(StateProcessRespond::new(StateId::SellerSendingOffer)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerOfferCreated get {:?}", input ))), @@ -131,7 +131,7 @@ where _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -180,7 +180,7 @@ where StateId::SellerWaitingForAcceptanceMessage, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerSendingOffer get {:?}", input ))), @@ -229,7 +229,7 @@ impl State for SellerWaitingForAcceptanceMessage { height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -298,7 +298,7 @@ impl State for SellerWaitingForAcceptanceMessage { debug_assert!(swap.redeem_public.is_some()); Ok(StateProcessRespond::new(StateId::SellerWaitingForBuyerLock)) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForAcceptanceMessage get {:?}", input ))), @@ -382,7 +382,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -463,7 +463,7 @@ where let _ = message.unwrap_accept_offer()?; Ok(StateProcessRespond::new(StateId::SellerWaitingForBuyerLock)) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForBuyerLock get {:?}", input ))), @@ -500,7 +500,7 @@ where } } - fn generate_cancel_respond(swap: &Swap) -> Result { + fn generate_cancel_respond(swap: &Swap) -> Result { if swap.posted_lock.is_none() { Ok(StateProcessRespond::new(StateId::SellerCancelled)) } else { @@ -536,7 +536,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { let time_limit = swap.get_time_start_lock(); match input { Input::Cancel => { @@ -589,7 +589,7 @@ where // Still checking the type of the message let _ = message.unwrap_accept_offer()?; Ok(StateProcessRespond::new(StateId::SellerPostingLockMwcSlate)) - } /*_ => Err(ErrorKind::InvalidSwapStateInput(format!( + } /*_ => Err(Error::InvalidSwapStateInput(format!( "SellerPostingLockMwcSlate get {:?}", input ))),*/ @@ -655,7 +655,7 @@ impl<'a, K: Keychain> State for SellerWaitingForLockConfirmations<'a, K> { height: u64, tx_conf: &SwapTransactionsConfirmations, secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -790,7 +790,7 @@ impl<'a, K: Keychain> State for SellerWaitingForLockConfirmations<'a, K> { StateId::SellerSendingInitRedeemMessage, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForLockConfirmations get {:?}", input ))), @@ -839,7 +839,7 @@ impl State for SellerWaitingForInitRedeemMessage { height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Cancel => { swap.add_journal_message(JOURNAL_CANCELLED_BY_USER.to_string()); @@ -896,7 +896,7 @@ impl State for SellerWaitingForInitRedeemMessage { StateId::SellerSendingInitRedeemMessage, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForInitRedeemMessage get {:?}", input ))), @@ -960,7 +960,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Checking if can redeem. The Buyer can be sneaky and try to fool us. We should assume that @@ -1044,7 +1044,7 @@ where StateId::SellerWaitingForBuyerToRedeemMwc, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerSendingInitRedeemMessage get {:?}", input ))), @@ -1063,7 +1063,7 @@ where pub(crate) fn check_mwc_redeem( swap: &mut Swap, node_client: &C, -) -> Result { +) -> Result { // Trying to find redeem if let Some((kernel, _h)) = swap.find_redeem_kernel(node_client)? { // Replace kernel @@ -1073,7 +1073,7 @@ pub(crate) fn check_mwc_redeem( .body .kernels .get_mut(0) - .ok_or(ErrorKind::UnexpectedAction( + .ok_or(Error::UnexpectedAction( "Seller Fn required_action() redeem slate not initialized, kernels are empty" .to_string(), ))?, @@ -1148,7 +1148,7 @@ where _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Redeem slate is already found, it's kernel updated, we can go forward @@ -1201,7 +1201,7 @@ where .time_limit(calc_mwc_unlock_time(swap, &height)), ) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForBuyerToRedeemMwc get {:?}", input ))), @@ -1224,7 +1224,7 @@ fn post_refund_if_possible( node_client: Arc, swap: &Swap, tx_conf: &SwapTransactionsConfirmations, -) -> Result<(), ErrorKind> { +) -> Result<(), Error> { let (height, _, _) = node_client.get_chain_tip()?; // intentionally no checking at refund step, no failure here if height > swap.refund_slate.get_lock_height() @@ -1307,7 +1307,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Be greedy, check the deadline for locking @@ -1371,7 +1371,7 @@ where StateId::SellerWaitingForRedeemConfirmations, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerRedeemSecondaryCurrency get {:?}", input ))), @@ -1440,7 +1440,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { if let Input::Check = input { // Be greedy, check the deadline for locking post_refund_if_possible(self.node_client.clone(), swap, tx_conf)?; @@ -1527,7 +1527,7 @@ where ), ); } else { - Err(ErrorKind::InvalidSwapStateInput(format!( + Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForRedeemConfirmations get {:?}", input ))) @@ -1571,10 +1571,10 @@ impl State for SellerSwapComplete { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => Ok(StateProcessRespond::new(StateId::SellerSwapComplete)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerSwapComplete get {:?}", input ))), @@ -1621,10 +1621,10 @@ impl State for SellerCancelled { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => Ok(StateProcessRespond::new(StateId::SellerCancelled)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerCancelled get {:?}", input ))), @@ -1695,7 +1695,7 @@ where _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Check the deadline for locking @@ -1716,7 +1716,7 @@ where .time_limit(calc_mwc_unlock_time(swap, &height)), ) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForRefundHeight get {:?}", input ))), @@ -1785,7 +1785,7 @@ where _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Check if mwc lock is already done @@ -1822,7 +1822,7 @@ where StateId::SellerWaitingForRefundConfirmations, )) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerPostingRefundSlate get {:?}", input ))), @@ -1867,7 +1867,7 @@ impl State for SellerWaitingForRefundConfirmations { _height: u64, tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => { // Check if mwc lock is already done @@ -1907,7 +1907,7 @@ impl State for SellerWaitingForRefundConfirmations { ), ) } - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerWaitingForRefundConfirmations get {:?}", input ))), @@ -1951,10 +1951,10 @@ impl State for SellerCancelledRefunded { _height: u64, _tx_conf: &SwapTransactionsConfirmations, _secp: &Secp256k1, - ) -> Result { + ) -> Result { match input { Input::Check => Ok(StateProcessRespond::new(StateId::SellerCancelledRefunded)), - _ => Err(ErrorKind::InvalidSwapStateInput(format!( + _ => Err(Error::InvalidSwapStateInput(format!( "SellerCancelled get {:?}", input ))), diff --git a/libwallet/src/swap/fsm/state.rs b/libwallet/src/swap/fsm/state.rs index df76af572..a32c25b3d 100644 --- a/libwallet/src/swap/fsm/state.rs +++ b/libwallet/src/swap/fsm/state.rs @@ -15,7 +15,7 @@ use crate::swap::message::Message; use crate::swap::swap::SwapJournalRecord; use crate::swap::types::{Action, SwapTransactionsConfirmations}; -use crate::swap::{Context, ErrorKind, Swap}; +use crate::swap::{Context, Error, Swap}; use grin_wallet_util::grin_util::secp::Secp256k1; use std::fmt; @@ -258,7 +258,7 @@ impl StateId { } /// Convert string name to State instance - pub fn from_cmd_str(str: &str) -> Result { + pub fn from_cmd_str(str: &str) -> Result { match str { "SellerOfferCreated" => Ok(StateId::SellerOfferCreated), "SellerSendingOffer" => Ok(StateId::SellerSendingOffer), @@ -300,7 +300,7 @@ impl StateId { "BuyerWaitingForRefundConfirmations" => Ok(StateId::BuyerWaitingForRefundConfirmations), "BuyerCancelledRefunded" => Ok(StateId::BuyerCancelledRefunded), "BuyerCancelled" => Ok(StateId::BuyerCancelled), - _ => Err(ErrorKind::Generic(format!("Unknown state value {}", str))), + _ => Err(Error::Generic(format!("Unknown state value {}", str))), } } } @@ -443,7 +443,7 @@ pub trait State { height: u64, tx_conf: &SwapTransactionsConfirmations, secp: &Secp256k1, - ) -> Result; + ) -> Result; /// Get the prev happy path State. fn get_prev_swap_state(&self) -> Option; diff --git a/libwallet/src/swap/message.rs b/libwallet/src/swap/message.rs index b3a838309..38267c2d0 100644 --- a/libwallet/src/swap/message.rs +++ b/libwallet/src/swap/message.rs @@ -17,7 +17,7 @@ use super::ethereum::EthUpdate; use super::multisig::ParticipantData as MultisigParticipant; use super::ser::*; use super::types::{Currency, Network}; -use super::ErrorKind; +use super::Error; use crate::grin_core::libtx::secp_ser; use crate::grin_util::secp::key::{PublicKey, SecretKey}; use crate::grin_util::secp::Signature; @@ -55,10 +55,10 @@ impl Message { } /// Unwrap message as Offer - pub fn unwrap_offer(self) -> Result<(Uuid, OfferUpdate, SecondaryUpdate), ErrorKind> { + pub fn unwrap_offer(self) -> Result<(Uuid, OfferUpdate, SecondaryUpdate), Error> { match self.inner { Update::Offer(u) => Ok((self.id, u, self.inner_secondary)), - _ => Err(ErrorKind::UnexpectedMessageType(format!( + _ => Err(Error::UnexpectedMessageType(format!( "expecting Update::Offer, get {:?}", self.inner ))), @@ -74,12 +74,10 @@ impl Message { } /// Unwrap message as Accepted Offer - pub fn unwrap_accept_offer( - self, - ) -> Result<(Uuid, AcceptOfferUpdate, SecondaryUpdate), ErrorKind> { + pub fn unwrap_accept_offer(self) -> Result<(Uuid, AcceptOfferUpdate, SecondaryUpdate), Error> { match self.inner { Update::AcceptOffer(u) => Ok((self.id, u, self.inner_secondary)), - _ => Err(ErrorKind::UnexpectedMessageType(format!( + _ => Err(Error::UnexpectedMessageType(format!( "expecting Update::AcceptOffer, get {:?}", self.inner ))), @@ -87,12 +85,10 @@ impl Message { } /// Unwrap message as Init Redeem - pub fn unwrap_init_redeem( - self, - ) -> Result<(Uuid, InitRedeemUpdate, SecondaryUpdate), ErrorKind> { + pub fn unwrap_init_redeem(self) -> Result<(Uuid, InitRedeemUpdate, SecondaryUpdate), Error> { match self.inner { Update::InitRedeem(u) => Ok((self.id, u, self.inner_secondary)), - _ => Err(ErrorKind::UnexpectedMessageType(format!( + _ => Err(Error::UnexpectedMessageType(format!( "expecting Update::InitRedeem, get {:?}", self.inner ))), @@ -100,10 +96,10 @@ impl Message { } /// Unwrap message as Redeem - pub fn unwrap_redeem(self) -> Result<(Uuid, RedeemUpdate, SecondaryUpdate), ErrorKind> { + pub fn unwrap_redeem(self) -> Result<(Uuid, RedeemUpdate, SecondaryUpdate), Error> { match self.inner { Update::Redeem(u) => Ok((self.id, u, self.inner_secondary)), - _ => Err(ErrorKind::UnexpectedMessageType(format!( + _ => Err(Error::UnexpectedMessageType(format!( "expecting Update::Redeem, get {:?}", self.inner ))), @@ -111,17 +107,16 @@ impl Message { } /// Message to Json String - pub fn to_json(&self) -> Result { + pub fn to_json(&self) -> Result { let str = serde_json::to_string(&self) - .map_err(|e| ErrorKind::Serde(format!("Unable to serialize a message, {}", e)))?; + .map_err(|e| Error::Serde(format!("Unable to serialize a message, {}", e)))?; Ok(str) } /// Build message from Json - pub fn from_json(s: &str) -> Result { - Ok(serde_json::from_str(s).map_err(|e| { - ErrorKind::Serde(format!("Unable to parse Swap Message from {}, {}", s, e)) - })?) + pub fn from_json(s: &str) -> Result { + Ok(serde_json::from_str(s) + .map_err(|e| Error::Serde(format!("Unable to parse Swap Message from {}, {}", s, e)))?) } } @@ -230,18 +225,18 @@ pub enum SecondaryUpdate { impl SecondaryUpdate { /// Helper to extract BtcUpdate with type validation - pub fn unwrap_btc(self) -> Result { + pub fn unwrap_btc(self) -> Result { match self { SecondaryUpdate::BTC(d) => Ok(d), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } /// Helper to extract EthUpdate with type validation - pub fn unwrap_eth(self) -> Result { + pub fn unwrap_eth(self) -> Result { match self { SecondaryUpdate::ETH(d) => Ok(d), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } } @@ -262,16 +257,16 @@ impl SwapMessage { _signature: String, secret_key: &SecretKey, secp: &Secp256k1, - ) -> Result { + ) -> Result { let public_key = from.public_key().map_err(|e| { - ErrorKind::TradeEncDecError(format!( + Error::TradeEncDecError(format!( "Unable to build public key for address {}, {}", from, e )) })?; let encrypted_message: EncryptedMessage = serde_json::from_str(&message).map_err(|e| { - ErrorKind::TradeEncDecError(format!( + Error::TradeEncDecError(format!( "Failed to extract the encrypted message from the received message {}, {}", message, e )) @@ -280,15 +275,15 @@ impl SwapMessage { let key = encrypted_message .key(&public_key, secret_key, &secp) .map_err(|e| { - ErrorKind::TradeEncDecError(format!("Unable to build the signature, {}", e)) + Error::TradeEncDecError(format!("Unable to build the signature, {}", e)) })?; let decrypted_message = encrypted_message.decrypt_with_key(&key).map_err(|e| { - ErrorKind::TradeEncDecError(format!("Unable to decrypt the swap message, {}", e)) + Error::TradeEncDecError(format!("Unable to decrypt the swap message, {}", e)) })?; let swap = serde_json::from_str(&decrypted_message).map_err(|e| { - ErrorKind::TradeEncDecError(format!( + Error::TradeEncDecError(format!( "Unable to build the swap message from the received message, {}", e )) diff --git a/libwallet/src/swap/mod.rs b/libwallet/src/swap/mod.rs index 8d5150a28..fe0b04c43 100644 --- a/libwallet/src/swap/mod.rs +++ b/libwallet/src/swap/mod.rs @@ -48,7 +48,7 @@ pub mod ser; /// Types used by swap library pub mod types; -pub use self::error::ErrorKind; +pub use self::error::Error; pub use self::swap::Swap; pub use self::types::Context; //pub use self::types::BtcSellerContext; @@ -403,20 +403,20 @@ mod tests { fn post_tx(&self, tx: &Transaction, _fluff: bool) -> Result<(), crate::Error> { let (height, _, _) = self.get_chain_tip()?; tx.validate(Weighting::AsTransaction, height) - .map_err(|e| crate::ErrorKind::Node(format!("Node failure, {}", e)))?; + .map_err(|e| crate::Error::Node(format!("Node failure, {}", e)))?; let mut state = self.state.lock(); for input in tx.inputs_committed() { // Output not unspent if !state.outputs.contains_key(&input) { - return Err(crate::ErrorKind::Node("Node failure".to_string()).into()); + return Err(crate::Error::Node("Node failure".to_string())); } // Double spend attempt for tx_pending in state.pending.iter() { for in_pending in tx_pending.inputs_committed() { if in_pending == input { - return Err(crate::ErrorKind::Node("Node failure".to_string()).into()); + return Err(crate::Error::Node("Node failure".to_string())); } } } @@ -424,13 +424,13 @@ mod tests { // Check for duplicate output for output in tx.outputs_committed() { if state.outputs.contains_key(&output) { - return Err(crate::ErrorKind::Node("Node failure".to_string()).into()); + return Err(crate::Error::Node("Node failure".to_string())); } for tx_pending in state.pending.iter() { for out_pending in tx_pending.outputs_committed() { if out_pending == output { - return Err(crate::ErrorKind::Node("Node failure".to_string()).into()); + return Err(crate::Error::Node("Node failure".to_string())); } } } @@ -439,13 +439,13 @@ mod tests { for kernel in tx.kernels() { // Duplicate kernel if state.kernels.contains_key(&kernel.excess) { - return Err(crate::ErrorKind::Node("Node failure".to_string()).into()); + return Err(crate::Error::Node("Node failure".to_string())); } for tx_pending in state.pending.iter() { for kernel_pending in tx_pending.kernels() { if kernel_pending.excess == kernel.excess { - return Err(crate::ErrorKind::Node("Node failure".to_string()).into()); + return Err(crate::Error::Node("Node failure".to_string())); } } } @@ -584,9 +584,7 @@ mod tests { assert_eq!( res.err().unwrap(), - ErrorKind::InvalidMessageData( - "Lock Slate inputs are not found at the chain".to_string() - ) + Error::InvalidMessageData("Lock Slate inputs are not found at the chain".to_string()) ); // Swap cannot be accepted } @@ -1637,13 +1635,13 @@ mod tests { input: Input, height: u64, secp: &Secp256k1, - ) -> Result { + ) -> Result { let tx_conf = self.api.request_tx_confirmations(&self.kc, &self.swap)?; self.fsm .process(input, &mut self.swap, &self.ctx, height, &tx_conf, secp) } - pub fn _get_tx_conf(&self) -> Result { + pub fn _get_tx_conf(&self) -> Result { self.api.request_tx_confirmations(&self.kc, &self.swap) } @@ -6791,9 +6789,7 @@ mod tests { assert_eq!( res.err().unwrap(), - ErrorKind::InvalidMessageData( - "Lock Slate inputs are not found at the chain".to_string() - ) + Error::InvalidMessageData("Lock Slate inputs are not found at the chain".to_string()) ); // Swap cannot be accepted } diff --git a/libwallet/src/swap/multisig/error.rs b/libwallet/src/swap/multisig/error.rs index 404a23799..513979dfe 100644 --- a/libwallet/src/swap/multisig/error.rs +++ b/libwallet/src/swap/multisig/error.rs @@ -13,53 +13,41 @@ // limitations under the License. use crate::grin_util::secp; -use failure::Fail; -use std::error::Error as StdError; /// Multisig error -#[derive(Clone, Eq, PartialEq, Debug, Fail)] -pub enum ErrorKind { +#[derive(Clone, Eq, PartialEq, Debug, thiserror::Error)] +pub enum Error { /// Reveal phase error - #[fail(display = "Multisig Invalid reveal")] + #[error("Multisig Invalid reveal")] Reveal, /// Not expected hash length, expected is 32 - #[fail(display = "Multisig Invalid hash length")] + #[error("Multisig Invalid hash length")] HashLength, /// Participant already exists - #[fail(display = "Multisig Participant already exists")] + #[error("Multisig Participant already exists")] ParticipantExists, /// Expected participant doesn't exist - #[fail(display = "Multisig Participant doesn't exist")] + #[error("Multisig Participant doesn't exist")] ParticipantDoesntExist, /// Participant created in the wrong order - #[fail(display = "Multisig Participant created in the wrong order")] + #[error("Multisig Participant created in the wrong order")] ParticipantOrdering, /// Participant invalid - #[fail(display = "Multisig Participant invalid")] + #[error("Multisig Participant invalid")] ParticipantInvalid, /// Multisig incomplete - #[fail(display = "Multisig incomplete")] + #[error("Multisig incomplete")] MultiSigIncomplete, /// Common nonce missing - #[fail(display = "Multisig Common nonce missing")] + #[error("Multisig Common nonce missing")] CommonNonceMissing, /// Round 1 missing field - #[fail(display = "Multisig Round 1 missing field")] + #[error("Multisig Round 1 missing field")] Round1Missing, /// Round 2 missing field - #[fail(display = "Multisig Round 2 missing field")] + #[error("Multisig Round 2 missing field")] Round2Missing, /// Secp error - #[fail(display = "Multisig Secp: {}", _0)] - Secp(String), -} - -// we have to use e.description because of the bug at rust-secp256k1-zkp -#[allow(deprecated)] - -impl From for ErrorKind { - fn from(error: secp::Error) -> ErrorKind { - // secp::Error to_string is broken, in past biilds. - ErrorKind::Secp(format!("{}", error.description())) - } + #[error("Multisig Secp: {0}")] + Secp(#[from] secp::Error), } diff --git a/libwallet/src/swap/multisig/mod.rs b/libwallet/src/swap/multisig/mod.rs index 6eaf3502e..3b649c657 100644 --- a/libwallet/src/swap/multisig/mod.rs +++ b/libwallet/src/swap/multisig/mod.rs @@ -16,5 +16,5 @@ mod error; /// Types used for multisig operations pub mod types; -pub use self::error::ErrorKind; +pub use self::error::Error; pub use self::types::{Builder, Hashed, ParticipantData}; diff --git a/libwallet/src/swap/multisig/types.rs b/libwallet/src/swap/multisig/types.rs index fb8b24689..8f7fb4955 100644 --- a/libwallet/src/swap/multisig/types.rs +++ b/libwallet/src/swap/multisig/types.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::error::ErrorKind; +use super::error::Error; use crate::blake2::blake2b::blake2b; use crate::grin_core::core::{ Input as TxInput, Output as TxOutput, OutputFeatures, OutputIdentifier, @@ -81,10 +81,10 @@ impl Builder { &mut self, secp: &Secp256k1, secret_key: &SecretKey, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let id = self.participants.len(); if id != self.participant_id { - return Err(ErrorKind::ParticipantOrdering); + return Err(Error::ParticipantOrdering); } let partial_commitment = secp.commit(0, secret_key.clone())?; self.participants.push(if self.commit_reveal { @@ -100,13 +100,13 @@ impl Builder { &mut self, id: usize, participant: &ParticipantData, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { if self.participants.len() > id { - return Err(ErrorKind::ParticipantExists); + return Err(Error::ParticipantExists); } if self.participants.len() != id || self.participants.len() >= self.num_participants { - return Err(ErrorKind::ParticipantOrdering); + return Err(Error::ParticipantOrdering); } self.participants.push(if self.commit_reveal { @@ -123,18 +123,18 @@ impl Builder { &mut self, id: usize, participant: &ParticipantData, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { if self.participants.len() <= id { - return Err(ErrorKind::ParticipantDoesntExist); + return Err(Error::ParticipantDoesntExist); } if self.commit_reveal && self.participants.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } match participant.partial_commitment.as_ref() { Some(p) => self.participants[id].reveal(p), - None => Err(ErrorKind::Reveal), + None => Err(Error::Reveal), } } @@ -143,17 +143,17 @@ impl Builder { &mut self, id: usize, participant: &ParticipantData, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { if self.participants.len() <= id { - return Err(ErrorKind::ParticipantDoesntExist); + return Err(Error::ParticipantDoesntExist); } if self.participants.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } if participant.t_1.is_none() || participant.t_2.is_none() { - return Err(ErrorKind::Round1Missing); + return Err(Error::Round1Missing); } self.participants[id].t_1 = participant.t_1.clone(); @@ -166,17 +166,17 @@ impl Builder { &mut self, id: usize, participant: &ParticipantData, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { if self.participants.len() <= id { - return Err(ErrorKind::ParticipantDoesntExist.into()); + return Err(Error::ParticipantDoesntExist); } if self.participants.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete.into()); + return Err(Error::MultiSigIncomplete); } if participant.tau_x.is_none() { - return Err(ErrorKind::Round2Missing.into()); + return Err(Error::Round2Missing); } self.participants[id].tau_x = participant.tau_x.clone(); @@ -184,18 +184,18 @@ impl Builder { } /// Export this party participant data - pub fn export(&self) -> Result { + pub fn export(&self) -> Result { if self.participants.len() <= self.participant_id { - return Err(ErrorKind::ParticipantDoesntExist); + return Err(Error::ParticipantDoesntExist); } Ok(self.participants[self.participant_id].clone()) } /// Checking revealed data - pub fn reveal(&mut self, secp: &Secp256k1, secret_key: &SecretKey) -> Result<(), ErrorKind> { + pub fn reveal(&mut self, secp: &Secp256k1, secret_key: &SecretKey) -> Result<(), Error> { if self.participants.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } let partial_commitment = secp.commit(0, secret_key.clone())?; @@ -204,7 +204,7 @@ impl Builder { } /// Mulisig buiding round 1 - pub fn round_1(&mut self, secp: &Secp256k1, blind: &SecretKey) -> Result<(), ErrorKind> { + pub fn round_1(&mut self, secp: &Secp256k1, blind: &SecretKey) -> Result<(), Error> { let mut t_1 = PublicKey::new(); let mut t_2 = PublicKey::new(); // Round 1 doesnt require knowledge of total commit or common nonce, we should allow NULL argument in libsecp @@ -232,7 +232,7 @@ impl Builder { } /// Mulisig buiding round 2 - pub fn round_2(&mut self, secp: &Secp256k1, blind: &SecretKey) -> Result<(), ErrorKind> { + pub fn round_2(&mut self, secp: &Secp256k1, blind: &SecretKey) -> Result<(), Error> { let mut t_1 = self.sum_t_1(secp)?; let mut t_2 = self.sum_t_2(secp)?; let mut tau_x = SecretKey([0; SECRET_KEY_SIZE]); @@ -255,7 +255,7 @@ impl Builder { } /// Finalize building multisig - pub fn finalize(&self, secp: &Secp256k1, blind: &SecretKey) -> Result { + pub fn finalize(&self, secp: &Secp256k1, blind: &SecretKey) -> Result { let mut t_1 = self.sum_t_1(secp)?; let mut t_2 = self.sum_t_2(secp)?; let mut tau_x = self.sum_tau_x(secp)?; @@ -274,13 +274,13 @@ impl Builder { Some(&self.nonce), 0, ) - .ok_or(ErrorKind::MultiSigIncomplete)?; + .ok_or(Error::MultiSigIncomplete)?; secp.verify_bullet_proof(commit, proof, None)?; Ok(proof) } /// Multisig as commit - pub fn as_input(&self, secp: &Secp256k1) -> Result { + pub fn as_input(&self, secp: &Secp256k1) -> Result { Ok(TxInput { features: OutputFeatures::Plain, commit: self.commit(secp)?, @@ -288,7 +288,7 @@ impl Builder { } /// Multisig as output - pub fn as_output(&self, secp: &Secp256k1, blind: &SecretKey) -> Result { + pub fn as_output(&self, secp: &Secp256k1, blind: &SecretKey) -> Result { Ok(TxOutput { identifier: OutputIdentifier { features: OutputFeatures::Plain, @@ -299,7 +299,7 @@ impl Builder { } /// Build a commitment with initialized multisig - pub fn commit(&self, secp: &Secp256k1) -> Result { + pub fn commit(&self, secp: &Secp256k1) -> Result { let mut partial_commitments: Vec = self .participants .iter() @@ -307,7 +307,7 @@ impl Builder { .collect(); if partial_commitments.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } let commitment_value = secp.commit_value(self.amount)?; @@ -316,13 +316,11 @@ impl Builder { Ok(commitment) } - fn common_nonce(&self) -> Result { - self.common_nonce - .clone() - .ok_or(ErrorKind::CommonNonceMissing) + fn common_nonce(&self) -> Result { + self.common_nonce.clone().ok_or(Error::CommonNonceMissing) } - fn sum_t_1(&self, secp: &Secp256k1) -> Result { + fn sum_t_1(&self, secp: &Secp256k1) -> Result { let t_1s: Vec<&PublicKey> = self .participants .iter() @@ -330,14 +328,14 @@ impl Builder { .collect(); if t_1s.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } let t_1 = PublicKey::from_combination(secp, t_1s)?; Ok(t_1) } - fn sum_t_2(&self, secp: &Secp256k1) -> Result { + fn sum_t_2(&self, secp: &Secp256k1) -> Result { let t_2s: Vec<&PublicKey> = self .participants .iter() @@ -345,14 +343,14 @@ impl Builder { .collect(); if t_2s.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } let t_2 = PublicKey::from_combination(secp, t_2s)?; Ok(t_2) } - fn sum_tau_x(&self, secp: &Secp256k1) -> Result { + fn sum_tau_x(&self, secp: &Secp256k1) -> Result { let mut sum_tau_x = SecretKey([0; SECRET_KEY_SIZE]); let tau_xs: Vec<&SecretKey> = self .participants @@ -361,7 +359,7 @@ impl Builder { .collect(); if tau_xs.len() != self.num_participants { - return Err(ErrorKind::MultiSigIncomplete); + return Err(Error::MultiSigIncomplete); } tau_xs @@ -435,11 +433,11 @@ impl ParticipantData { } /// Convert this to not revealed - pub fn new_foreign_commit(&self) -> Result { + pub fn new_foreign_commit(&self) -> Result { let hash = self .partial_commitment_hash .clone() - .ok_or(ErrorKind::ParticipantInvalid)?; + .ok_or(Error::ParticipantInvalid)?; Ok(ParticipantData { partial_commitment_hash: Some(hash), partial_commitment: None, @@ -450,11 +448,11 @@ impl ParticipantData { } /// Convert this to revealed - pub fn new_foreign_reveal(&self) -> Result { + pub fn new_foreign_reveal(&self) -> Result { let commit = self .partial_commitment .clone() - .ok_or(ErrorKind::ParticipantInvalid)?; + .ok_or(Error::ParticipantInvalid)?; Ok(ParticipantData { partial_commitment_hash: None, partial_commitment: Some(commit), @@ -465,15 +463,12 @@ impl ParticipantData { } /// Check if partial_commitment match the hash - fn reveal(&mut self, partial_commitment: &Commitment) -> Result<(), ErrorKind> { - let hash = self - .partial_commitment_hash - .as_ref() - .ok_or(ErrorKind::Reveal)?; + fn reveal(&mut self, partial_commitment: &Commitment) -> Result<(), Error> { + let hash = self.partial_commitment_hash.as_ref().ok_or(Error::Reveal)?; if &partial_commitment.hash()? == hash { Ok(()) } else { - Err(ErrorKind::Reveal) + Err(Error::Reveal) } } } @@ -486,16 +481,16 @@ pub struct Hash { impl Hash { /// Create a new hash instance - pub fn new(inner: Vec) -> Result { + pub fn new(inner: Vec) -> Result { if inner.len() != 32 { - return Err(ErrorKind::HashLength); + return Err(Error::HashLength); } Ok(Self { inner }) } /// Init secret from the hash - pub fn to_secret_key(&self, secp: &Secp256k1) -> Result { + pub fn to_secret_key(&self, secp: &Secp256k1) -> Result { let key = SecretKey::from_slice(secp, &self.inner)?; Ok(key) } @@ -527,18 +522,18 @@ impl<'de> Deserialize<'de> for Hash { /// Trait that make Hashable pub trait Hashed { /// Calculate hash value - fn hash(&self) -> Result; + fn hash(&self) -> Result; } /// Define Hash for Pedersen Commitment impl Hashed for Commitment { - fn hash(&self) -> Result { + fn hash(&self) -> Result { Hash::new(blake2b(32, &[], &self.0).as_bytes().to_vec()) } } /// Define hash for vector impl Hashed for Vec { - fn hash(&self) -> Result { + fn hash(&self) -> Result { Hash::new(blake2b(32, &[], &self).as_bytes().to_vec()) } } diff --git a/libwallet/src/swap/seller.rs b/libwallet/src/swap/seller.rs index 0352a097a..123d91f2e 100644 --- a/libwallet/src/swap/seller.rs +++ b/libwallet/src/swap/seller.rs @@ -19,7 +19,7 @@ use super::multisig::{Builder as MultisigBuilder, ParticipantData as MultisigPar use super::swap; use super::swap::{signature_as_secret, tx_add_input, tx_add_output, Swap}; use super::types::*; -use super::{ErrorKind, Keychain, CURRENT_VERSION}; +use super::{Error, Keychain, CURRENT_VERSION}; use crate::grin_core::libtx::{build, proof, tx_fee}; use crate::grin_keychain::{BlindSum, BlindingFactor}; use crate::grin_util::secp::aggsig; @@ -66,7 +66,7 @@ impl SellApi { eth_redirect_to_private_wallet: Option, dry_run: bool, tag: Option, - ) -> Result { + ) -> Result { #[cfg(test)] let test_mode = is_test_mode(); let scontext = context.unwrap_seller()?; @@ -172,10 +172,9 @@ impl SellApi { refund_slate.fee = tx_fee(1, 1, 1); if !(dry_run && primary_amount == 0) { if primary_amount <= refund_slate.fee { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "MWC amount to trade is too low, it doesn't cover the fees".to_string(), - ) - .into()); + )); } } @@ -188,7 +187,7 @@ impl SellApi { let max_lock_time = 1440 * 30; if refund_slate.get_lock_height_check()? - refund_slate.height > max_lock_time { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "MWC locking time interval exceed 4 weeks. Is it a scam or mistake?".to_string(), )); } @@ -212,7 +211,7 @@ impl SellApi { // TODO: no change output if amounts match up exactly let change = if !(dry_run && primary_amount == 0) { if sum_in <= primary_amount + lock_slate.fee { - return Err(ErrorKind::InsufficientFunds( + return Err(Error::InsufficientFunds( primary_amount + lock_slate.fee + 1, sum_in, )); @@ -245,7 +244,7 @@ impl SellApi { context: &Context, accept_offer: AcceptOfferUpdate, height: u64, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(swap.is_seller()); // Finalize multisig proof @@ -287,15 +286,14 @@ impl SellApi { context: &Context, init_redeem: InitRedeemUpdate, height: u64, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { assert!(swap.is_seller()); // This function should only be called once if swap.adaptor_signature.is_some() { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Seller Fn init_redeem() multisig is empty".to_string(), - ) - .into()); + )); } let mut redeem_slate: Slate = init_redeem.redeem_slate.into_slate_plain(true)?; @@ -313,12 +311,12 @@ impl SellApi { Some(&pub_nonce_sum), &redeem_slate.participant_data[swap.other_participant_id()].public_blind_excess, Some(&pub_blind_sum), - Some(&swap.redeem_public.ok_or(ErrorKind::UnexpectedAction( + Some(&swap.redeem_public.ok_or(Error::UnexpectedAction( "Seller Fn init_redeem() redeem pub key is empty".to_string(), ))?), true, ) { - return Err(ErrorKind::InvalidAdaptorSignature); + return Err(Error::InvalidAdaptorSignature); } swap.redeem_slate = redeem_slate; @@ -334,10 +332,10 @@ impl SellApi { pub fn calculate_redeem_secret( keychain: &K, swap: &Swap, - ) -> Result { + ) -> Result { let adaptor_signature = signature_as_secret( keychain.secp(), - &swap.adaptor_signature.ok_or(ErrorKind::UnexpectedAction( + &swap.adaptor_signature.ok_or(Error::UnexpectedAction( "Seller Fn calculate_redeem_secret() multisig is empty".to_string(), ))?, )?; @@ -347,7 +345,7 @@ impl SellApi { .tx_or_err()? .kernels() .get(0) - .ok_or(ErrorKind::UnexpectedAction("Seller Fn calculate_redeem_secret() redeem slate is not initialized, no kernels found".to_string()))? + .ok_or(Error::UnexpectedAction("Seller Fn calculate_redeem_secret() redeem slate is not initialized, no kernels found".to_string()))? .excess_sig, )?; let seller_signature = signature_as_secret( keychain.secp(), @@ -355,9 +353,9 @@ impl SellApi { .redeem_slate .participant_data .get(swap.participant_id) - .ok_or(ErrorKind::UnexpectedAction("Seller Fn calculate_redeem_secret() redeem slate is not initialized, participant not found".to_string()))? + .ok_or(Error::UnexpectedAction("Seller Fn calculate_redeem_secret() redeem slate is not initialized, participant not found".to_string()))? .part_sig - .ok_or(ErrorKind::UnexpectedAction("Seller Fn calculate_redeem_secret() redeem slate is not initialized, participant signature not found".to_string()))?, + .ok_or(Error::UnexpectedAction("Seller Fn calculate_redeem_secret() redeem slate is not initialized, participant signature not found".to_string()))?, )?; let redeem = keychain @@ -366,7 +364,7 @@ impl SellApi { let redeem_pub = PublicKey::from_secret_key(keychain.secp(), &redeem)?; if swap.redeem_public != Some(redeem_pub) { // If this happens - mean that swap is broken, somewhere there is a security flaw. Probably didn't check something. - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Redeem secret doesn't match - this should never happen".into(), )); } @@ -376,10 +374,7 @@ impl SellApi { /// Generate Offer message. /// Note: from_address need to be update by the caller because only caller knows about communication layer. - pub fn offer_message( - swap: &Swap, - secondary_update: SecondaryUpdate, - ) -> Result { + pub fn offer_message(swap: &Swap, secondary_update: SecondaryUpdate) -> Result { assert!(swap.is_seller()); swap.message( Update::Offer(OfferUpdate { @@ -412,7 +407,7 @@ impl SellApi { } /// Generate redeem message - pub fn redeem_message(swap: &Swap) -> Result { + pub fn redeem_message(swap: &Swap) -> Result { assert!(swap.is_seller()); swap.message( Update::Redeem(RedeemUpdate { @@ -430,7 +425,7 @@ impl SellApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let multisig_secret = swap.multisig_secret(keychain, context)?; let multisig = &mut swap.multisig; @@ -446,7 +441,7 @@ impl SellApi { swap: &mut Swap, context: &Context, part: MultisigParticipant, - ) -> Result { + ) -> Result { let sec_key = swap.multisig_secret(keychain, context)?; let secp = keychain.secp(); @@ -471,7 +466,7 @@ impl SellApi { keychain: &K, swap: &Swap, context: &Context, - ) -> Result { + ) -> Result { let scontext = context.unwrap_seller()?; let (_, change) = swap.unwrap_seller()?; let mut sum = BlindSum::new(); @@ -497,17 +492,16 @@ impl SellApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let (_, change) = swap.unwrap_seller()?; let scontext = context.unwrap_seller()?; // This function should only be called once let slate = &mut swap.lock_slate; if slate.participant_data.len() > 0 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Seller Fn build_lock_slate() lock slate is already initialized".to_string(), - ) - .into()); + )); } // Build lock slate @@ -553,16 +547,15 @@ impl SellApi { proof: RangeProof, part: TxParticipant, height: u64, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let sec_key = Self::lock_tx_secret(keychain, swap, context)?; // This function should only be called once let slate = &mut swap.lock_slate; if slate.participant_data.len() > 1 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Seller Fn finalize_lock_slate() lock slate is already initialized".to_string(), - ) - .into()); + )); } // Add participant to slate @@ -588,7 +581,7 @@ impl SellApi { keychain: &K, swap: &Swap, context: &Context, - ) -> Result { + ) -> Result { let scontext = context.unwrap_seller()?; // Partial multisig input, refund output, offset @@ -607,14 +600,14 @@ impl SellApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let scontext = context.unwrap_seller()?; let refund_amount = swap.refund_amount(); // This function should only be called once let slate = &mut swap.refund_slate; if slate.participant_data.len() > 0 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Seller Fn build_refund_slate() refund slate is already initialized".to_string(), )); } @@ -658,16 +651,15 @@ impl SellApi { commit: Commitment, part: TxParticipant, height: u64, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let sec_key = Self::refund_tx_secret(keychain, swap, context)?; // This function should only be called once let slate = &mut swap.refund_slate; if slate.participant_data.len() > 1 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Seller Fn finalize_refund_slate() refund slate is already initialized".to_string(), - ) - .into()); + )); } // Add participant to slate @@ -693,7 +685,7 @@ impl SellApi { keychain: &K, swap: &Swap, context: &Context, - ) -> Result { + ) -> Result { // Partial multisig input let sum = BlindSum::new().sub_blinding_factor(BlindingFactor::from_secret_key( swap.multisig_secret(keychain, context)?, @@ -707,13 +699,13 @@ impl SellApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let sec_key = Self::redeem_tx_secret(keychain, swap, context)?; // This function should only be called once let slate = &mut swap.redeem_slate; if slate.participant_data.len() > 0 { - return Err(ErrorKind::OneShot( + return Err(Error::OneShot( "Seller Fn build_redeem_participant() redeem slate is already initialized" .to_string(), )); @@ -737,7 +729,7 @@ impl SellApi { keychain: &K, redeem_slate: &mut Slate, height: u64, - ) -> Result { + ) -> Result { let excess = redeem_slate.calc_excess(keychain.secp(), Some(keychain), height)?; redeem_slate.tx_or_err_mut()?.body.kernels[0].excess = excess.clone(); Ok(excess) @@ -747,14 +739,14 @@ impl SellApi { keychain: &K, swap: &mut Swap, context: &Context, - ) -> Result<(), ErrorKind> { + ) -> Result<(), Error> { let id = swap.participant_id; let sec_key = Self::redeem_tx_secret(keychain, swap, context)?; // This function should only be called once let slate = &mut swap.redeem_slate; if slate.participant_data[id].is_complete() { - return Err(ErrorKind::OneShot("Seller Fn sign_redeem_slate() redeem slate participant data is already initilaized".to_string())); + return Err(Error::OneShot("Seller Fn sign_redeem_slate() redeem slate participant data is already initilaized".to_string())); } // Sign slate diff --git a/libwallet/src/swap/ser.rs b/libwallet/src/swap/ser.rs index 2554c006e..5e0f915c9 100644 --- a/libwallet/src/swap/ser.rs +++ b/libwallet/src/swap/ser.rs @@ -15,8 +15,8 @@ use crate::grin_util::secp::key::{PublicKey, SecretKey}; use crate::grin_util::secp::pedersen::Commitment; use crate::grin_util::secp::Signature; +use crate::swap::Error; use crate::{Slate, VersionedSlate}; -use failure::Error; use grin_wallet_util::grin_util::secp::{ContextFlag, Secp256k1}; use grin_wallet_util::grin_util::ToHex; use hex::{self, FromHex}; @@ -62,7 +62,8 @@ where /// Deserialize Commitment from HEX string fn commit_from_hex_string(s: String) -> Result { - let v = Vec::from_hex(&s)?; + let v = Vec::from_hex(&s) + .map_err(|e| Error::Generic(format!("Unable to parse commit {} from HEX, {}", s, e)))?; Ok(Commitment::from_vec(v)) } @@ -102,7 +103,8 @@ where } fn pubkey_from_hex_string(s: String) -> Result { - let v = Vec::from_hex(&s)?; + let v = Vec::from_hex(&s) + .map_err(|e| Error::Generic(format!("Unable to parse public key {} from HEX, {}", s, e)))?; let secp = Secp256k1::with_caps(ContextFlag::None); let p = PublicKey::from_slice(&secp, &v[..])?; Ok(p) @@ -153,7 +155,8 @@ where } fn seckey_from_hex_string(s: String) -> Result { - let v = Vec::from_hex(&s)?; + let v = Vec::from_hex(&s) + .map_err(|e| Error::Generic(format!("Unable to parse sec key {} from HEX, {}", s, e)))?; let secp = Secp256k1::with_caps(ContextFlag::None); let sk = SecretKey::from_slice(&secp, &v[..])?; Ok(sk) @@ -205,7 +208,8 @@ where } fn sig_from_hex_string(secp: &Secp256k1, s: String) -> Result { - let v = Vec::from_hex(&s)?; + let v = Vec::from_hex(&s) + .map_err(|e| Error::Generic(format!("Unable to parse signature {} from HEX, {}", s, e)))?; let sig = Signature::from_compact(secp, &v[..])?; Ok(sig) } diff --git a/libwallet/src/swap/swap.rs b/libwallet/src/swap/swap.rs index 353eedd34..c7b4dc880 100644 --- a/libwallet/src/swap/swap.rs +++ b/libwallet/src/swap/swap.rs @@ -16,7 +16,7 @@ use super::message::*; use super::multisig::{Builder as MultisigBuilder, Hashed}; use super::ser::*; use super::types::*; -use super::{ErrorKind, Keychain}; +use super::{Error, Keychain}; use crate::grin_core::core::{ transaction as tx, CommitWrapper, Inputs, KernelFeatures, OutputIdentifier, TxKernel, Weighting, }; @@ -190,7 +190,7 @@ impl Swap { &self, keychain: &K, context: &Context, - ) -> Result<(Identifier, u64, Commitment), ErrorKind> { + ) -> Result<(Identifier, u64, Commitment), Error> { assert!(self.is_seller()); let scontext = context.unwrap_seller()?; @@ -206,7 +206,7 @@ impl Swap { } /// Return Seller specific data - pub fn unwrap_seller(&self) -> Result<(String, u64), ErrorKind> { + pub fn unwrap_seller(&self) -> Result<(String, u64), Error> { match &self.role { Role::Seller(address, change) => { match address == "0x0000000000000000000000000000000000000000" { @@ -214,14 +214,12 @@ impl Swap { _ => Ok((address.clone(), *change)), } } - _ => Err(ErrorKind::UnexpectedRole( - "Swap call unwrap_seller".to_string(), - )), + _ => Err(Error::UnexpectedRole("Swap call unwrap_seller".to_string())), } } /// Return buyer specific data - pub fn unwrap_buyer(&self) -> Result, ErrorKind> { + pub fn unwrap_buyer(&self) -> Result, Error> { match &self.role { Role::Buyer(address) => match address { Some(address) => match address == "0x0000000000000000000000000000000000000000" { @@ -230,9 +228,7 @@ impl Swap { }, _ => Ok(address.clone()), }, - _ => Err(ErrorKind::UnexpectedRole( - "Swap call unwrap_buyer".to_string(), - )), + _ => Err(Error::UnexpectedRole("Swap call unwrap_buyer".to_string())), } } @@ -267,7 +263,7 @@ impl Swap { &self, inner: Update, inner_secondary: SecondaryUpdate, - ) -> Result { + ) -> Result { Ok(Message::new(self.id.clone(), inner, inner_secondary)) } @@ -275,7 +271,7 @@ impl Swap { &self, keychain: &K, context: &Context, - ) -> Result { + ) -> Result { let sec_key = keychain.derive_key( self.primary_amount, &context.multisig_key, @@ -293,7 +289,7 @@ impl Swap { &self, redeem_slate: &Slate, secp: &Secp256k1, - ) -> Result<(PublicKey, PublicKey, SecpMessage), ErrorKind> { + ) -> Result<(PublicKey, PublicKey, SecpMessage), Error> { let pub_nonces = redeem_slate .participant_data .iter() @@ -311,11 +307,11 @@ impl Swap { fee: redeem_slate .fee .try_into() - .map_err(|e| ErrorKind::Generic(format!("Invalid fee, {}", e)))?, + .map_err(|e| Error::Generic(format!("Invalid fee, {}", e)))?, }; let message = features .kernel_sig_msg() - .map_err(|e| ErrorKind::Generic(format!("Unable to generate message, {}", e)))?; + .map_err(|e| Error::Generic(format!("Unable to generate message, {}", e)))?; Ok((pub_nonce_sum, pub_blind_sum, message)) } @@ -323,13 +319,13 @@ impl Swap { pub(super) fn find_redeem_kernel( &self, node_client: &C, - ) -> Result, ErrorKind> { + ) -> Result, Error> { let excess = &self .redeem_slate .tx_or_err()? .kernels() .get(0) - .ok_or(ErrorKind::UnexpectedAction( + .ok_or(Error::UnexpectedAction( "Swap Fn find_redeem_kernel() redeem slate is not initialized, not found kernel" .to_string(), ))? @@ -347,7 +343,7 @@ impl Swap { } /// Common nonce for the BulletProof is sum_i H(C_i) where C_i is the commitment of participant i - pub(super) fn common_nonce(&self, secp: &Secp256k1) -> Result { + pub(super) fn common_nonce(&self, secp: &Secp256k1) -> Result { let hashed_nonces: Vec = self .multisig .participants @@ -357,7 +353,7 @@ impl Swap { .filter_map(|s| s.ok()) .collect(); if hashed_nonces.len() != 2 { - return Err(super::multisig::ErrorKind::MultiSigIncomplete.into()); + return Err(super::multisig::Error::MultiSigIncomplete.into()); } let sec_key = secp.blind_sum(hashed_nonces, Vec::new())?; @@ -530,7 +526,7 @@ impl ser::Readable for Swap { }*/ /// Add an input to a tx at the appropriate position -pub fn tx_add_input(slate: &mut Slate, commit: Commitment) -> Result<(), ErrorKind> { +pub fn tx_add_input(slate: &mut Slate, commit: Commitment) -> Result<(), Error> { match &mut slate.tx_or_err_mut()?.body.inputs { Inputs::FeaturesAndCommit(inputs) => { let input = tx::Input { @@ -558,7 +554,7 @@ pub fn tx_add_output( slate: &mut Slate, commit: Commitment, proof: RangeProof, -) -> Result<(), ErrorKind> { +) -> Result<(), Error> { let output = tx::Output { identifier: OutputIdentifier { features: tx::OutputFeatures::Plain, @@ -575,10 +571,7 @@ pub fn tx_add_output( } /// Interpret the final 32 bytes of the signature as a secret key -pub fn signature_as_secret( - secp: &Secp256k1, - signature: &Signature, -) -> Result { +pub fn signature_as_secret(secp: &Secp256k1, signature: &Signature) -> Result { let ser = signature.to_raw_data(); let key = SecretKey::from_slice(secp, &ser[32..])?; Ok(key) @@ -589,10 +582,10 @@ pub fn publish_transaction( node_client: &C, tx: &tx::Transaction, fluff: bool, -) -> Result<(), ErrorKind> { +) -> Result<(), Error> { let (height, _, _) = node_client.get_chain_tip()?; tx.validate(Weighting::AsTransaction, height) - .map_err(|e| ErrorKind::UnexpectedAction(format!("slate is not valid, {}", e)))?; + .map_err(|e| Error::UnexpectedAction(format!("slate is not valid, {}", e)))?; node_client.post_tx(tx, fluff)?; Ok(()) diff --git a/libwallet/src/swap/trades.rs b/libwallet/src/swap/trades.rs index 3fbe46fc5..b1f7c5418 100644 --- a/libwallet/src/swap/trades.rs +++ b/libwallet/src/swap/trades.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::ErrorKind; +use super::Error; use crate::grin_core::global; use crate::grin_util::secp::key::SecretKey; use crate::grin_util::{from_hex, to_hex}; @@ -96,7 +96,7 @@ pub fn get_electrumx_uri( currency: &Currency, swap_electrum_node_uri1: &Option, swap_electrum_node_uri2: &Option, -) -> Result<(String, String), ErrorKind> { +) -> Result<(String, String), Error> { let network = if global::is_mainnet() { "main" } else { "test" }; let map = ELECTRUM_X_URI.read(); @@ -109,7 +109,7 @@ pub fn get_electrumx_uri( .as_ref() .unwrap() .get(&format!("{}_{}_1", sec_coin, network)) - .ok_or(ErrorKind::UndefinedElectrumXURI("primary".to_string()))? + .ok_or(Error::UndefinedElectrumXURI("primary".to_string()))? .clone(), }; let uri2 = match swap_electrum_node_uri2.clone() { @@ -118,7 +118,7 @@ pub fn get_electrumx_uri( .as_ref() .unwrap() .get(&format!("{}_{}_2", sec_coin, network)) - .ok_or(ErrorKind::UndefinedElectrumXURI("secondary".to_string()))? + .ok_or(Error::UndefinedElectrumXURI("secondary".to_string()))? .clone(), }; @@ -129,14 +129,14 @@ pub fn get_electrumx_uri( pub fn get_eth_swap_contract_address( _currency: &Currency, eth_swap_contract_addr: &Option, -) -> Result { +) -> Result { let swap_contract_addresss = ETH_SWAP_CONTRACT_ADDR.read().clone(); match eth_swap_contract_addr.clone() { Some(s) => Ok(s), None => match swap_contract_addresss { Some(s) => Ok(s), - None => swap_contract_addresss.ok_or(ErrorKind::UndefinedEthSwapContractAddress), + None => swap_contract_addresss.ok_or(Error::UndefinedEthSwapContractAddress), }, } } @@ -145,14 +145,14 @@ pub fn get_eth_swap_contract_address( pub fn get_erc20_swap_contract_address( _currency: &Currency, erc20_swap_contract_addr: &Option, -) -> Result { +) -> Result { let swap_contract_addresss = ERC20_SWAP_CONTRACT_ADDR.read().clone(); match erc20_swap_contract_addr.clone() { Some(s) => Ok(s), None => match swap_contract_addresss { Some(s) => Ok(s), - None => swap_contract_addresss.ok_or(ErrorKind::UndefinedEthSwapContractAddress), + None => swap_contract_addresss.ok_or(Error::UndefinedEthSwapContractAddress), }, } } @@ -161,20 +161,20 @@ pub fn get_erc20_swap_contract_address( pub fn get_eth_infura_projectid( _currency: &Currency, eth_infura_projectid: &Option, -) -> Result { +) -> Result { let infura_project_id = ETH_INFURA_PROJECTID.read().clone(); match eth_infura_projectid.clone() { Some(s) => Ok(s), None => match infura_project_id { Some(s) => Ok(s), - None => infura_project_id.ok_or(ErrorKind::UndefinedInfuraProjectId), + None => infura_project_id.ok_or(Error::UndefinedInfuraProjectId), }, } } /// List available swap trades. -pub fn list_swap_trades() -> Result, ErrorKind> { +pub fn list_swap_trades() -> Result, Error> { let mut result: Vec = Vec::new(); for entry in fs::read_dir(TRADE_DEALS_PATH.read().clone().unwrap())? { @@ -208,9 +208,9 @@ pub fn delete_swap_trade( swap_id: &str, dec_key: &SecretKey, lock: &Mutex<()>, -) -> Result<(), ErrorKind> { +) -> Result<(), Error> { if lock.try_lock().is_some() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "delete_swap_trade processing unlocked instance {}", swap_id ))); @@ -218,7 +218,7 @@ pub fn delete_swap_trade( let (_context, swap) = get_swap_trade(swap_id, dec_key, lock)?; if !swap.state.is_final_state() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Swap {} is still in the progress. Please finish or cancel this trade", swap_id ))); @@ -246,7 +246,7 @@ pub fn delete_swap_trade( .join(format!("{}.swap.del", swap_id)); fs::rename(target_path, deleted_path).map_err(|e| { - ErrorKind::TradeIoError(swap_id.to_string(), format!("Unable to delete, {}", e)) + Error::TradeIoError(swap_id.to_string(), format!("Unable to delete, {}", e)) })?; Ok(()) } @@ -257,9 +257,9 @@ pub fn get_swap_trade( swap_id: &str, dec_key: &SecretKey, lock: &Mutex<()>, -) -> Result<(Context, Swap), ErrorKind> { +) -> Result<(Context, Swap), Error> { if lock.try_lock().is_some() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "get_swap_trade processing unlocked instance {}", swap_id ))); @@ -271,15 +271,15 @@ pub fn get_swap_trade( .unwrap() .join(format!("{}.swap", swap_id)); if !path.exists() { - return Err(ErrorKind::TradeNotFound(swap_id.to_string())); + return Err(Error::TradeNotFound(swap_id.to_string())); } read_swap_data_from_file(path.as_path(), dec_key) } -fn read_swap_content(path: &Path, dec_key: &SecretKey) -> Result { +fn read_swap_content(path: &Path, dec_key: &SecretKey) -> Result { let mut swap_deal_f = File::open(path).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to open file {}, {}", path.to_str().unwrap(), e @@ -287,7 +287,7 @@ fn read_swap_content(path: &Path, dec_key: &SecretKey) -> Result Result Result<(Context, Swap), ErrorKind> { +fn read_swap_data_from_file(path: &Path, dec_key: &SecretKey) -> Result<(Context, Swap), Error> { let dec_swap_content = read_swap_content(path, dec_key)?; let mut split = dec_swap_content.split("<#>"); @@ -311,21 +308,21 @@ fn read_swap_data_from_file( let swap_str = split.next(); if context_str.is_none() || swap_str.is_none() { - return Err(ErrorKind::IO(format!( + return Err(Error::IO(format!( "Not found all packages at the swap trade file {}", path.to_str().unwrap() ))); } let context: Context = serde_json::from_str(context_str.unwrap()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to parce Swap data from file {}, {}", path.to_str().unwrap(), e )) })?; let swap: Swap = serde_json::from_str(swap_str.unwrap()).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to parce Swap data from file {}, {}", path.to_str().unwrap(), e @@ -341,9 +338,9 @@ pub fn store_swap_trade( swap: &Swap, enc_key: &SecretKey, lock: &Mutex<()>, -) -> Result<(), ErrorKind> { +) -> Result<(), Error> { if lock.try_lock().is_some() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "store_swap_trade processing unlocked instance {}", swap.id ))); @@ -360,7 +357,7 @@ pub fn store_swap_trade( .join(format!("{}.swap_{}.bak", swap_id, r)); { let mut stored_swap = File::create(path.clone()).map_err(|e| { - ErrorKind::TradeIoError( + Error::TradeIoError( swap_id.clone(), format!( "Unable to create the file {} to store swap trade, {}", @@ -371,13 +368,13 @@ pub fn store_swap_trade( })?; let context_ser = serde_json::to_string(context).map_err(|e| { - ErrorKind::TradeIoError( + Error::TradeIoError( swap_id.clone(), format!("Unable to convert context to Json, {}", e), ) })?; let swap_ser = serde_json::to_string(swap).map_err(|e| { - ErrorKind::TradeIoError( + Error::TradeIoError( swap_id.clone(), format!("Unable to convert swap to Json, {}", e), ) @@ -385,13 +382,13 @@ pub fn store_swap_trade( let res_str = context_ser + "<#>" + swap_ser.as_str(); let encrypted_swap = EncryptedSwap::from_json(&res_str, enc_key)?; let enc_swap_ser = serde_json::to_string(&encrypted_swap).map_err(|e| { - ErrorKind::TradeEncDecError(format!("Unable to serialize encrypted swap, {}", e)) + Error::TradeEncDecError(format!("Unable to serialize encrypted swap, {}", e)) })?; stored_swap .write_all(&enc_swap_ser.as_bytes()) .map_err(|e| { - ErrorKind::TradeIoError( + Error::TradeIoError( swap_id.clone(), format!( "Unable to write swap deal to file {}, {}", @@ -401,7 +398,7 @@ pub fn store_swap_trade( ) })?; stored_swap.sync_all().map_err(|e| { - ErrorKind::TradeIoError( + Error::TradeIoError( swap_id.clone(), format!( "Unable to sync file {} all after writing swap deal, {}", @@ -418,7 +415,7 @@ pub fn store_swap_trade( .unwrap() .join(format!("{}.swap", swap.id.to_string())); fs::rename(path, path_target).map_err(|e| { - ErrorKind::TradeIoError( + Error::TradeIoError( swap_id.clone(), format!("Unable to finalize writing, rename failed with error {}", e), ) @@ -432,9 +429,9 @@ pub fn dump_swap_trade( swap_id: &str, dec_key: &SecretKey, lock: &Mutex<()>, -) -> Result { +) -> Result { if lock.try_lock().is_some() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "dump_swap_trade processing unlocked instance {}", swap_id ))); @@ -446,14 +443,14 @@ pub fn dump_swap_trade( .unwrap() .join(format!("{}.swap", swap_id)); if !path.exists() { - return Err(ErrorKind::TradeNotFound(swap_id.to_string())); + return Err(Error::TradeNotFound(swap_id.to_string())); } read_swap_content(path.as_path(), dec_key) } /// Export encrypted trade data into the file -pub fn export_trade(swap_id: &str, export_file_name: &str) -> Result<(), ErrorKind> { +pub fn export_trade(swap_id: &str, export_file_name: &str) -> Result<(), Error> { let path = TRADE_DEALS_PATH .read() .clone() @@ -461,11 +458,11 @@ pub fn export_trade(swap_id: &str, export_file_name: &str) -> Result<(), ErrorKi .join(format!("{}.swap", swap_id)); if !path.exists() { - return Err(ErrorKind::TradeNotFound(swap_id.to_string())); + return Err(Error::TradeNotFound(swap_id.to_string())); } fs::copy(path, export_file_name).map_err(|e| { - ErrorKind::IO(format!( + Error::IO(format!( "Unable to export trade data into the file {}, {}", export_file_name, e )) @@ -480,16 +477,16 @@ pub fn import_trade( trade_file_name: &str, dec_key: &SecretKey, lock: &Mutex<()>, -) -> Result { +) -> Result { if lock.try_lock().is_some() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "import_trade processing unlocked instance" ))); } let src_path = Path::new(trade_file_name); if !src_path.exists() { - return Err(ErrorKind::IO(format!("Not found file {}", trade_file_name))); + return Err(Error::IO(format!("Not found file {}", trade_file_name))); } let (context, swap) = read_swap_data_from_file(src_path, dec_key)?; @@ -510,20 +507,17 @@ pub struct EncryptedSwap { impl EncryptedSwap { /// Encrypts and encodes json as base 64 - pub fn from_json(json_in: &String, enc_key: &SecretKey) -> Result { + pub fn from_json(json_in: &String, enc_key: &SecretKey) -> Result { let mut to_encrypt = serde_json::to_string(&json_in) .map_err(|e| { - ErrorKind::TradeEncDecError(format!( - "EncryptSwap Enc: unable to encode Json, {}", - e - )) + Error::TradeEncDecError(format!("EncryptSwap Enc: unable to encode Json, {}", e)) })? .as_bytes() .to_vec(); let nonce: [u8; 12] = thread_rng().gen(); let unbound_key = aead::UnboundKey::new(&aead::AES_256_GCM, &enc_key.0) - .map_err(|e| ErrorKind::Generic(format!("Unable to build a key, {}", e)))?; + .map_err(|e| Error::Generic(format!("Unable to build a key, {}", e)))?; let sealing_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key); let aad = aead::Aad::from(&[]); let res = sealing_key.seal_in_place_append_tag( @@ -532,11 +526,10 @@ impl EncryptedSwap { &mut to_encrypt, ); if let Err(e) = res { - return Err(ErrorKind::TradeEncDecError(format!( + return Err(Error::TradeEncDecError(format!( "EncryptedSwap Enc: Encryption failed, {}", e - )) - .into()); + ))); } Ok(EncryptedSwap { @@ -546,50 +539,48 @@ impl EncryptedSwap { } /// Decrypts and returns the original swap+context - pub fn decrypt(&self, dec_key: &SecretKey) -> Result { + pub fn decrypt(&self, dec_key: &SecretKey) -> Result { let mut to_decrypt = base64::decode(&self.body_enc).map_err(|e| { - ErrorKind::TradeEncDecError(format!( + Error::TradeEncDecError(format!( "EncryptedSwap Dec: Encrypted swap contains invalid Base64, {}", e )) })?; let nonce = from_hex(&self.nonce).map_err(|e| { - ErrorKind::TradeEncDecError(format!( + Error::TradeEncDecError(format!( "EncryptedSwap Dec: Encrypted request contains invalid nonce, {}", e )) })?; if nonce.len() < 12 { - return Err(ErrorKind::TradeEncDecError( + return Err(Error::TradeEncDecError( "EncryptedSwap Dec: Invalid Nonce length".to_string(), - ) - .into()); + )); } let mut n = [0u8; 12]; n.copy_from_slice(&nonce[0..12]); let unbound_key = aead::UnboundKey::new(&aead::AES_256_GCM, &dec_key.0) - .map_err(|e| ErrorKind::Generic(format!("Unable to build a key, {}", e)))?; + .map_err(|e| Error::Generic(format!("Unable to build a key, {}", e)))?; let opening_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key); let aad = aead::Aad::from(&[]); opening_key .open_in_place(aead::Nonce::assume_unique_for_key(n), aad, &mut to_decrypt) .map_err(|e| { - ErrorKind::TradeEncDecError(format!("EncryptedSwap Dec: Decryption failed, {}", e)) + Error::TradeEncDecError(format!("EncryptedSwap Dec: Decryption failed, {}", e)) })?; for _ in 0..aead::AES_256_GCM.tag_len() { to_decrypt.pop(); } - let decrypted = String::from_utf8(to_decrypt).map_err(|_| { - ErrorKind::TradeEncDecError("EncryptedSwap Dec: Invalid UTF-8".to_string()) - })?; + let decrypted = String::from_utf8(to_decrypt) + .map_err(|_| Error::TradeEncDecError("EncryptedSwap Dec: Invalid UTF-8".to_string()))?; Ok(serde_json::from_str(&decrypted).map_err(|e| { - ErrorKind::TradeEncDecError(format!("EncryptedSwap Dec: Invalid JSON, {}", e)) + Error::TradeEncDecError(format!("EncryptedSwap Dec: Invalid JSON, {}", e)) })?) } } diff --git a/libwallet/src/swap/types.rs b/libwallet/src/swap/types.rs index a0ab9e7b8..ac51edb23 100644 --- a/libwallet/src/swap/types.rs +++ b/libwallet/src/swap/types.rs @@ -15,7 +15,7 @@ use super::bitcoin::{BtcBuyerContext, BtcData, BtcSellerContext}; use super::ethereum::{EthBuyerContext, EthData, EthSellerContext, EthereumAddress}; use super::ser::*; -use super::ErrorKind; +use super::Error; use crate::grin_core::global::ChainTypes; use crate::grin_core::{global, ser}; use crate::grin_keychain::Identifier; @@ -38,16 +38,16 @@ pub enum Network { impl Network { /// Construct from current chaintype - pub fn current_network() -> Result { + pub fn current_network() -> Result { Ok(Self::from_chain_type(global::get_chain_type())?) } /// Constructor from mwc-node ChainTypes - pub fn from_chain_type(chain_type: ChainTypes) -> Result { + pub fn from_chain_type(chain_type: ChainTypes) -> Result { match chain_type { ChainTypes::Floonet => Ok(Network::Floonet), ChainTypes::Mainnet => Ok(Network::Mainnet), - _ => Err(ErrorKind::UnexpectedNetwork(format!("{:?}", chain_type))), + _ => Err(Error::UnexpectedNetwork(format!("{:?}", chain_type))), } } /// To mwc-node ChainType @@ -190,9 +190,9 @@ impl Currency { } /// Convert string amount to Satoshi amount - pub fn amount_from_hr_string(&self, hr: &str) -> Result { + pub fn amount_from_hr_string(&self, hr: &str) -> Result { if hr.find(",").is_some() { - return Err(ErrorKind::InvalidAmountString(hr.to_string())); + return Err(Error::InvalidAmountString(hr.to_string())); } let exp = self.exponent(); @@ -207,7 +207,7 @@ impl Currency { let amount = characteristic * 10u64.pow(exp as u32) + mantissa; if amount == 0 { - return Err(ErrorKind::InvalidAmountString("zero amoount".to_string())); + return Err(Error::InvalidAmountString("zero amoount".to_string())); } Ok(amount) @@ -221,11 +221,11 @@ impl Currency { } } - fn validate_address_network(addr: &Address, coin_name: &str) -> Result<(), ErrorKind> { + fn validate_address_network(addr: &Address, coin_name: &str) -> Result<(), Error> { match addr.network { bitcoin::network::constants::Network::Bitcoin => { if !global::is_mainnet() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Address is from main {} network, expected test network", coin_name ))); @@ -233,14 +233,14 @@ impl Currency { } bitcoin::network::constants::Network::Testnet => { if global::is_mainnet() { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Address is from test {} network, expected main network", coin_name ))); } } _ => { - return Err(ErrorKind::Generic(format!( + return Err(Error::Generic(format!( "Address is from invalid {} network", coin_name ))) @@ -250,11 +250,11 @@ impl Currency { } /// Validate the secondary address - pub fn validate_address(&self, address: &String) -> Result<(), ErrorKind> { + pub fn validate_address(&self, address: &String) -> Result<(), Error> { match self { Currency::Btc => { let addr = Address::new_btc().from_str(address).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse BTC address {}, {}", address, e)) + Error::Generic(format!("Unable to parse BTC address {}, {}", address, e)) })?; Self::validate_address_network(&addr, "BTC")?; } @@ -266,7 +266,7 @@ impl Currency { // Intentionally return error from first call. Legacy address error is not interesting much let (hash, addr_type) = bch::address::legacyaddr_decode(&address, nw) .map_err(|_| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to parse BCH address {}, {}", address, e )) @@ -276,20 +276,20 @@ impl Currency { Ok((v, addr_type)) => (v, addr_type), }; if v.len() != 160 / 8 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Swap supports only Legacy of 160 bit BCH addresses".to_string(), )); } } Currency::Ltc => { let addr = Address::new_ltc().from_str(address).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse LTC address {}, {}", address, e)) + Error::Generic(format!("Unable to parse LTC address {}, {}", address, e)) })?; Self::validate_address_network(&addr, "LTC")?; } Currency::Dash => { let addr = Address::new_dash().from_str(address).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse Dash address {}, {}", address, e)) + Error::Generic(format!("Unable to parse Dash address {}, {}", address, e)) })?; Self::validate_address_network(&addr, "Dash")?; @@ -298,7 +298,7 @@ impl Currency { | bitcoin::util::address::Payload::ScriptHash(_) => (), _ => { // Dash doesn't have Segwit - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Address is not supported by Dash".to_string(), )); } @@ -306,7 +306,7 @@ impl Currency { } Currency::ZCash => { let addr = Address::new_zec().from_str(address).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to parse ZCash transparent address {}, {}", address, e )) @@ -318,7 +318,7 @@ impl Currency { | bitcoin::util::address::Payload::ScriptHash(_) => (), _ => { // Dash doesn't have Segwit - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Address is not supported by ZCash".to_string(), )); } @@ -326,7 +326,7 @@ impl Currency { } Currency::Doge => { let addr = Address::new_doge().from_str(address).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to parse Dogecoin address {}, {}", address, e )) @@ -338,7 +338,7 @@ impl Currency { | bitcoin::util::address::Payload::ScriptHash(_) => (), _ => { // Dash doesn't have Segwit - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Address is not supported by DOgecoin".to_string(), )); } @@ -357,7 +357,7 @@ impl Currency { | Currency::Trx | Currency::Tst => { EthereumAddress::from_str(address.as_str()).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to parse Ethereum address {}, {}", address, e )) @@ -368,7 +368,7 @@ impl Currency { } /// Generate a script for this address. Address MUST be Hash160 - pub fn address_2_script_pubkey(&self, address: &String) -> Result { + pub fn address_2_script_pubkey(&self, address: &String) -> Result { let addr_str = match self { Currency::Btc => address.clone(), Currency::Bch => { @@ -382,13 +382,13 @@ impl Currency { } Ok((v, addr_type)) => { if v.len() != 160 / 8 { - return Err(ErrorKind::Generic( + return Err(Error::Generic( "Swap supporting only Legacy of 160 bit BCH addresses".to_string(), )); } let ba: Box<[u8; 20]> = v.into_boxed_slice().try_into().map_err(|_| { - ErrorKind::Generic( + Error::Generic( "Internal error. Failed to convert address to hash".to_string(), ) })?; @@ -403,28 +403,28 @@ impl Currency { Currency::Ltc => { // Converting to BTC address let addr = Address::new_ltc().from_str(&address).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse LTC address {}, {}", address, e)) + Error::Generic(format!("Unable to parse LTC address {}, {}", address, e)) })?; addr.to_btc().to_string() } Currency::Dash => { // Converting to BTC address let addr = Address::new_dash().from_str(&address).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse Dash address {}, {}", address, e)) + Error::Generic(format!("Unable to parse Dash address {}, {}", address, e)) })?; addr.to_btc().to_string() } Currency::ZCash => { // Converting to BTC address let addr = Address::new_zec().from_str(&address).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse ZCash address {}, {}", address, e)) + Error::Generic(format!("Unable to parse ZCash address {}, {}", address, e)) })?; addr.to_btc().to_string() } Currency::Doge => { // Converting to BTC address let addr = Address::new_doge().from_str(&address).map_err(|e| { - ErrorKind::Generic(format!( + Error::Generic(format!( "Unable to parse Dogecoin address {}, {}", address, e )) @@ -449,7 +449,7 @@ impl Currency { }; let addr = Address::new_btc().from_str(&addr_str).map_err(|e| { - ErrorKind::Generic(format!("Unable to parse BTC address {}, {}", address, e)) + Error::Generic(format!("Unable to parse BTC address {}, {}", address, e)) })?; Ok(addr.script_pubkey()) } @@ -648,7 +648,7 @@ impl Currency { } /// get erc20 token contract address - pub fn erc20_token_address(&self) -> Result { + pub fn erc20_token_address(&self) -> Result { match self { Currency::Usdt => { Ok(H160::from_str("dac17f958d2ee523a2206206994597c13d831ec7").unwrap()) @@ -683,10 +683,7 @@ impl Currency { Currency::Tst => { Ok(H160::from_str("722dd3F80BAC40c951b51BdD28Dd19d435762180").unwrap()) } - _ => Err(ErrorKind::EthUnsupportedERC20TokenError(format!( - "{}", - self - ))), + _ => Err(Error::EthUnsupportedERC20TokenError(format!("{}", self))), } } @@ -733,7 +730,7 @@ impl fmt::Display for Currency { } impl TryFrom<&str> for Currency { - type Error = ErrorKind; + type Error = Error; fn try_from(value: &str) -> Result { match value.to_lowercase().as_str() { @@ -755,22 +752,22 @@ impl TryFrom<&str> for Currency { "usdc" => Ok(Currency::Usdc), "trx" => Ok(Currency::Trx), "tst" => Ok(Currency::Tst), - _ => Err(ErrorKind::InvalidCurrency(value.to_string())), + _ => Err(Error::InvalidCurrency(value.to_string())), } } } -fn parse_characteristic(characteristic: &str) -> Result { +fn parse_characteristic(characteristic: &str) -> Result { if characteristic.len() == 0 { return Ok(0); } characteristic .parse() - .map_err(|_| ErrorKind::InvalidAmountString(characteristic.to_string())) + .map_err(|_| Error::InvalidAmountString(characteristic.to_string())) } -fn parse_mantissa(mantissa: &str, exp: usize) -> Result { +fn parse_mantissa(mantissa: &str, exp: usize) -> Result { let mut m = format!("{:0 Result { return Ok(0); } m.parse() - .map_err(|_| ErrorKind::InvalidAmountString(m.to_string())) + .map_err(|_| Error::InvalidAmountString(m.to_string())) } /// Secondary currency related data @@ -795,31 +792,31 @@ pub enum SecondaryData { impl SecondaryData { /// To BTC data - pub fn unwrap_btc(&self) -> Result<&BtcData, ErrorKind> { + pub fn unwrap_btc(&self) -> Result<&BtcData, Error> { match self { SecondaryData::Btc(d) => Ok(d), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } /// To BTC data - pub fn unwrap_btc_mut(&mut self) -> Result<&mut BtcData, ErrorKind> { + pub fn unwrap_btc_mut(&mut self) -> Result<&mut BtcData, Error> { match self { SecondaryData::Btc(d) => Ok(d), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } /// To ETH data - pub fn unwrap_eth(&self) -> Result<&EthData, ErrorKind> { + pub fn unwrap_eth(&self) -> Result<&EthData, Error> { match self { SecondaryData::Eth(d) => Ok(d), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } /// To ETH data - pub fn unwrap_eth_mut(&mut self) -> Result<&mut EthData, ErrorKind> { + pub fn unwrap_eth_mut(&mut self) -> Result<&mut EthData, Error> { match self { SecondaryData::Eth(d) => Ok(d), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } } @@ -847,19 +844,19 @@ pub struct Context { impl Context { /// To Seller Context - pub fn unwrap_seller(&self) -> Result<&SellerContext, ErrorKind> { + pub fn unwrap_seller(&self) -> Result<&SellerContext, Error> { match &self.role_context { RoleContext::Seller(c) => Ok(c), - RoleContext::Buyer(_) => Err(ErrorKind::UnexpectedRole( + RoleContext::Buyer(_) => Err(Error::UnexpectedRole( "Context Fn unwrap_seller()".to_string(), )), } } /// To Buyer Context - pub fn unwrap_buyer(&self) -> Result<&BuyerContext, ErrorKind> { + pub fn unwrap_buyer(&self) -> Result<&BuyerContext, Error> { match &self.role_context { - RoleContext::Seller(_) => Err(ErrorKind::UnexpectedRole( + RoleContext::Seller(_) => Err(Error::UnexpectedRole( "Context Fn unwrap_seller()".to_string(), )), RoleContext::Buyer(c) => Ok(c), @@ -912,18 +909,18 @@ pub struct SellerContext { impl SellerContext { /// Retreive BTC data - pub fn unwrap_btc(&self) -> Result<&BtcSellerContext, ErrorKind> { + pub fn unwrap_btc(&self) -> Result<&BtcSellerContext, Error> { match &self.secondary_context { SecondarySellerContext::Btc(c) => Ok(c), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } /// Retreive ETH data - pub fn unwrap_eth(&self) -> Result<&EthSellerContext, ErrorKind> { + pub fn unwrap_eth(&self) -> Result<&EthSellerContext, Error> { match &self.secondary_context { SecondarySellerContext::Eth(c) => Ok(c), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } } @@ -943,18 +940,18 @@ pub struct BuyerContext { impl BuyerContext { /// To BTC context - pub fn unwrap_btc(&self) -> Result<&BtcBuyerContext, ErrorKind> { + pub fn unwrap_btc(&self) -> Result<&BtcBuyerContext, Error> { match &self.secondary_context { SecondaryBuyerContext::Btc(c) => Ok(c), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } /// To ETH context - pub fn unwrap_eth(&self) -> Result<&EthBuyerContext, ErrorKind> { + pub fn unwrap_eth(&self) -> Result<&EthBuyerContext, Error> { match &self.secondary_context { SecondaryBuyerContext::Eth(c) => Ok(c), - _ => Err(ErrorKind::UnexpectedCoinType), + _ => Err(Error::UnexpectedCoinType), } } } diff --git a/libwallet/src/types.rs b/libwallet/src/types.rs index ac90c02aa..425bdfdfe 100644 --- a/libwallet/src/types.rs +++ b/libwallet/src/types.rs @@ -17,7 +17,7 @@ use super::swap::ethereum::EthereumWallet; use crate::config::{MQSConfig, TorConfig, WalletConfig}; -use crate::error::{Error, ErrorKind}; +use crate::error::Error; use crate::grin_api::{Libp2pMessages, Libp2pPeers}; use crate::grin_core::core::hash::Hash; use crate::grin_core::core::Committed; @@ -876,7 +876,7 @@ impl BlockIdentifier { /// convert to hex string pub fn from_hex(hex: &str) -> Result { let hash = Hash::from_hex(hex).map_err(|e| { - ErrorKind::GenericError(format!("BlockIdentifier Invalid hex {}, {}", hex, e)) + Error::GenericError(format!("BlockIdentifier Invalid hex {}, {}", hex, e)) })?; Ok(BlockIdentifier(hash)) } diff --git a/src/cmd/wallet_args.rs b/src/cmd/wallet_args.rs index ddf0be8da..61cb8de80 100644 --- a/src/cmd/wallet_args.rs +++ b/src/cmd/wallet_args.rs @@ -23,12 +23,10 @@ use crate::util::{Mutex, ZeroingString}; /// Argument parsing and error handling for wallet commands use clap::ArgMatches; use ed25519_dalek::SecretKey as DalekSecretKey; -use failure::Fail; use grin_wallet_api::Owner; use grin_wallet_config::parse_node_address_string; use grin_wallet_config::{MQSConfig, TorConfig, WalletConfig}; -use grin_wallet_controller::command; -use grin_wallet_controller::{Error, ErrorKind}; +use grin_wallet_controller::{command, Error}; use grin_wallet_impls::tor::config::is_tor_address; use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl}; use grin_wallet_impls::{PathToSlateGetter, SlateGetter}; @@ -59,23 +57,23 @@ 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, } @@ -632,8 +630,7 @@ pub fn parse_send_args(args: &ArgMatches) -> Result { - return Err(ErrorKind::ArgumentError(format!( + return Err(Error::ArgumentError(format!( "Unknown wallet command '{}', use 'mwc help wallet' for details", cmd - )) - .into()); + ))); } } } diff --git a/tests/cmd_line_basic.rs b/tests/cmd_line_basic.rs index 646e4251b..189905566 100644 --- a/tests/cmd_line_basic.rs +++ b/tests/cmd_line_basic.rs @@ -458,7 +458,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller:: &file_name, ]; if let Err(err) = execute_command(&app, test_dir, "wallet2", &client2, arg_vec) { - assert_eq!( String::from("Impls Error, LibWallet Error, Slatepack decode error, Unable to decrypt, ring::error::Unspecified"), + assert_eq!( String::from("Impls Error, LibWallet Error, Unable to deserialize slatepack, Slatepack decode error, Unable to decrypt, ring::error::Unspecified"), err.to_string() ); } else { panic!("Expected to fail because of another recipient") @@ -670,7 +670,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller:: out_file_name.as_str(), ]; if let Err(err) = execute_command(&app, test_dir, "wallet1", &client1, arg_vec) { - assert_eq!( String::from("Impls Error, LibWallet Error, Slatepack decode error, Unable to decrypt, ring::error::Unspecified"), err.to_string() ); + assert_eq!( String::from("Impls Error, LibWallet Error, Unable to deserialize slatepack, Slatepack decode error, Unable to decrypt, ring::error::Unspecified"), err.to_string() ); } else { panic!("Expected to fail because of another recipient") } @@ -893,6 +893,6 @@ 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); } } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 81fbad1d5..757c29439 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -164,7 +164,7 @@ pub fn config_command_wallet( let mut config_file_name = current_dir.clone(); config_file_name.push("mwc-wallet.toml"); if config_file_name.exists() { - return Err(grin_wallet_controller::ErrorKind::ArgumentError( + return Err(grin_wallet_controller::Error::ArgumentError( "mwc-wallet.toml already exists in the target directory. Please remove it first" .to_owned(), ))?; @@ -487,11 +487,26 @@ pub fn derive_ecdh_key(sec_key_str: &str, other_pubkey: &PublicKey, secp: &Secp2 } // 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 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); diff --git a/util/Cargo.toml b/util/Cargo.toml index 543163ab4..183ed9eea 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -16,10 +16,9 @@ serde_derive = "1" ed25519-dalek = "1.0.0-pre.4" data-encoding = "2" sha3 = "0.8" -failure = "0.1" -failure_derive = "0.1" lazy_static = "1.4" tokio = { version = "0.2", features = ["full"] } +thiserror = "1" # For Release #grin_core = { git = "https://github.com/mwcproject/mwc-node", tag = "4.4.4" } diff --git a/util/src/ov3.rs b/util/src/ov3.rs index e72980473..7a360df13 100644 --- a/util/src/ov3.rs +++ b/util/src/ov3.rs @@ -16,20 +16,18 @@ use crate::grin_util::from_hex; use data_encoding::BASE32; use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::SecretKey as DalekSecretKey; -use failure::Fail; 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 -#[derive(Fail)] pub enum OnionV3Error { /// Error decoding an address from a string - #[fail(display = "Unable to decode Onion address from a string, {}", _0)] + #[error("Unable to decode Onion address from a string, {0}")] AddressDecoding(String), /// Error with given private key - #[fail(display = "Invalid private key, {}", _0)] + #[error("Invalid private key, {0}")] InvalidPrivateKey(String), }