aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet_errors.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet_errors.h')
-rw-r--r--src/wallet/wallet_errors.h611
1 files changed, 611 insertions, 0 deletions
diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h
new file mode 100644
index 000000000..b517d64f9
--- /dev/null
+++ b/src/wallet/wallet_errors.h
@@ -0,0 +1,611 @@
+// Copyright (c) 2012-2013 The Cryptonote developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#pragma once
+
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "cryptonote_core/cryptonote_format_utils.h"
+#include "rpc/core_rpc_server_commands_defs.h"
+#include "include_base_utils.h"
+
+
+namespace tools
+{
+ namespace error
+ {
+ // std::exception
+ // std::runtime_error
+ // wallet_runtime_error *
+ // wallet_internal_error
+ // unexpected_txin_type
+ // std::logic_error
+ // wallet_logic_error *
+ // file_exists
+ // file_not_found
+ // file_read_error
+ // file_save_error
+ // invalid_password
+ // refresh_error *
+ // acc_outs_lookup_error
+ // block_parse_error
+ // get_blocks_error
+ // get_out_indexes_error
+ // tx_extra_parse_error
+ // tx_parse_error
+ // transfer_error *
+ // get_random_outs_general_error
+ // not_enough_money
+ // not_enough_outs_to_mix
+ // tx_not_constructed
+ // tx_rejected
+ // tx_sum_overflow
+ // tx_too_big
+ // zero_destination
+ // wallet_rpc_error *
+ // daemon_busy
+ // no_connection_to_daemon
+ // wallet_files_doesnt_correspond
+ //
+ // * - class with protected ctor
+
+ //----------------------------------------------------------------------------------------------------
+ template<typename Base>
+ struct wallet_error_base : public Base
+ {
+ const std::string& location() const { return m_loc; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << m_loc << ':' << typeid(*this).name() << ": " << Base::what();
+ return ss.str();
+ }
+
+ protected:
+ wallet_error_base(std::string&& loc, const std::string& message)
+ : Base(message)
+ , m_loc(loc)
+ {
+ }
+
+ private:
+ std::string m_loc;
+ };
+ //----------------------------------------------------------------------------------------------------
+ const char* const failed_rpc_request_messages[] = {
+ "failed to get blocks",
+ "failed to get out indices",
+ "failed to get random outs"
+ };
+ enum failed_rpc_request_message_indices
+ {
+ get_blocks_error_message_index,
+ get_out_indices_error_message_index,
+ get_random_outs_error_message_index
+ };
+
+ template<typename Base, int msg_index>
+ struct failed_rpc_request : public Base
+ {
+ explicit failed_rpc_request(std::string&& loc, const std::string& status)
+ : Base(std::move(loc), failed_rpc_request_messages[msg_index])
+ , m_status(status)
+ {
+ }
+
+ const std::string& status() const { return m_status; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << Base::to_string() << ", status = " << status();
+ return ss.str();
+ }
+
+ private:
+ std::string m_status;
+ };
+ //----------------------------------------------------------------------------------------------------
+ typedef wallet_error_base<std::logic_error> wallet_logic_error;
+ typedef wallet_error_base<std::runtime_error> wallet_runtime_error;
+ //----------------------------------------------------------------------------------------------------
+ struct wallet_internal_error : public wallet_runtime_error
+ {
+ explicit wallet_internal_error(std::string&& loc, const std::string& message)
+ : wallet_runtime_error(std::move(loc), message)
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct unexpected_txin_type : public wallet_internal_error
+ {
+ explicit unexpected_txin_type(std::string&& loc, const cryptonote::transaction& tx)
+ : wallet_internal_error(std::move(loc), "one of tx inputs has unexpected type")
+ , m_tx(tx)
+ {
+ }
+
+ const cryptonote::transaction& tx() const { return m_tx; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ cryptonote::transaction tx = m_tx;
+ ss << wallet_internal_error::to_string() << ", tx:\n" << cryptonote::obj_to_json_str(tx);
+ return ss.str();
+ }
+
+ private:
+ cryptonote::transaction m_tx;
+ };
+ //----------------------------------------------------------------------------------------------------
+ const char* const file_error_messages[] = {
+ "file already exists",
+ "file not found",
+ "failed to read file",
+ "failed to save file"
+ };
+ enum file_error_message_indices
+ {
+ file_exists_message_index,
+ file_not_found_message_index,
+ file_read_error_message_index,
+ file_save_error_message_index
+ };
+
+ template<int msg_index>
+ struct file_error_base : public wallet_logic_error
+ {
+ explicit file_error_base(std::string&& loc, const std::string& file)
+ : wallet_logic_error(std::move(loc), std::string(file_error_messages[msg_index]) + " \"" + file + '\"')
+ , m_file(file)
+ {
+ }
+
+ const std::string& file() const { return m_file; }
+
+ std::string to_string() const { return wallet_logic_error::to_string(); }
+
+ private:
+ std::string m_file;
+ };
+ //----------------------------------------------------------------------------------------------------
+ typedef file_error_base<file_exists_message_index> file_exists;
+ typedef file_error_base<file_not_found_message_index> file_not_found;
+ typedef file_error_base<file_not_found_message_index> file_not_found;
+ typedef file_error_base<file_read_error_message_index> file_read_error;
+ typedef file_error_base<file_save_error_message_index> file_save_error;
+ //----------------------------------------------------------------------------------------------------
+ struct invalid_password : public wallet_logic_error
+ {
+ explicit invalid_password(std::string&& loc)
+ : wallet_logic_error(std::move(loc), "invalid password")
+ {
+ }
+
+ std::string to_string() const { return wallet_logic_error::to_string(); }
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct refresh_error : public wallet_logic_error
+ {
+ protected:
+ refresh_error(std::string&& loc, const std::string& message)
+ : wallet_logic_error(std::move(loc), message)
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct acc_outs_lookup_error : public refresh_error
+ {
+ explicit acc_outs_lookup_error(std::string&& loc, const cryptonote::transaction& tx,
+ const crypto::public_key& tx_pub_key, const cryptonote::account_keys& acc_keys)
+ : refresh_error(std::move(loc), "account outs lookup error")
+ , m_tx(tx)
+ , m_tx_pub_key(tx_pub_key)
+ , m_acc_keys(acc_keys)
+ {
+ }
+
+ const cryptonote::transaction& tx() const { return m_tx; }
+ const crypto::public_key& tx_pub_key() const { return m_tx_pub_key; }
+ const cryptonote::account_keys& acc_keys() const { return m_acc_keys; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ cryptonote::transaction tx = m_tx;
+ ss << refresh_error::to_string() << ", tx: " << cryptonote::obj_to_json_str(tx);
+ return ss.str();
+ }
+
+ private:
+ const cryptonote::transaction m_tx;
+ const crypto::public_key m_tx_pub_key;
+ const cryptonote::account_keys m_acc_keys;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct block_parse_error : public refresh_error
+ {
+ explicit block_parse_error(std::string&& loc, const cryptonote::blobdata& block_data)
+ : refresh_error(std::move(loc), "block parse error")
+ , m_block_blob(block_data)
+ {
+ }
+
+ const cryptonote::blobdata& block_blob() const { return m_block_blob; }
+
+ std::string to_string() const { return refresh_error::to_string(); }
+
+ private:
+ cryptonote::blobdata m_block_blob;
+ };
+ //----------------------------------------------------------------------------------------------------
+ typedef failed_rpc_request<refresh_error, get_blocks_error_message_index> get_blocks_error;
+ //----------------------------------------------------------------------------------------------------
+ typedef failed_rpc_request<refresh_error, get_out_indices_error_message_index> get_out_indices_error;
+ //----------------------------------------------------------------------------------------------------
+ struct tx_extra_parse_error : public refresh_error
+ {
+ explicit tx_extra_parse_error(std::string&& loc, const cryptonote::transaction& tx)
+ : refresh_error(std::move(loc), "transaction extra parse error")
+ , m_tx(tx)
+ {
+ }
+
+ const cryptonote::transaction& tx() const { return m_tx; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ cryptonote::transaction tx = m_tx;
+ ss << refresh_error::to_string() << ", tx: " << cryptonote::obj_to_json_str(tx);
+ return ss.str();
+ }
+
+ private:
+ const cryptonote::transaction m_tx;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct tx_parse_error : public refresh_error
+ {
+ explicit tx_parse_error(std::string&& loc, const cryptonote::blobdata& tx_blob)
+ : refresh_error(std::move(loc), "transaction parse error")
+ , m_tx_blob(tx_blob)
+ {
+ }
+
+ const cryptonote::blobdata& tx_blob() const { return m_tx_blob; }
+
+ std::string to_string() const { return refresh_error::to_string(); }
+
+ private:
+ cryptonote::blobdata m_tx_blob;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct transfer_error : public wallet_logic_error
+ {
+ protected:
+ transfer_error(std::string&& loc, const std::string& message)
+ : wallet_logic_error(std::move(loc), message)
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
+ typedef failed_rpc_request<transfer_error, get_random_outs_error_message_index> get_random_outs_error;
+ //----------------------------------------------------------------------------------------------------
+ struct not_enough_money : public transfer_error
+ {
+ not_enough_money(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee)
+ : transfer_error(std::move(loc), "not enough money")
+ , m_available(availbable)
+ , m_tx_amount(tx_amount)
+ , m_fee(fee)
+ {
+ }
+
+ uint64_t available() const { return m_available; }
+ uint64_t tx_amount() const { return m_tx_amount; }
+ uint64_t fee() const { return m_fee; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << transfer_error::to_string() <<
+ ", available = " << cryptonote::print_money(m_available) <<
+ ", tx_amount = " << cryptonote::print_money(m_tx_amount) <<
+ ", fee = " << cryptonote::print_money(m_fee);
+ return ss.str();
+ }
+
+ private:
+ uint64_t m_available;
+ uint64_t m_tx_amount;
+ uint64_t m_fee;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct not_enough_outs_to_mix : public transfer_error
+ {
+ typedef std::vector<cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount> scanty_outs_t;
+
+ explicit not_enough_outs_to_mix(std::string&& loc, const scanty_outs_t& scanty_outs, size_t mixin_count)
+ : transfer_error(std::move(loc), "not enough outputs to mix")
+ , m_scanty_outs(scanty_outs)
+ , m_mixin_count(mixin_count)
+ {
+ }
+
+ const scanty_outs_t& scanty_outs() const { return m_scanty_outs; }
+ size_t mixin_count() const { return m_mixin_count; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << transfer_error::to_string() << ", mixin_count = " << m_mixin_count << ", scanty_outs:";
+ for (const auto& outs_for_amount : m_scanty_outs)
+ {
+ ss << '\n' << cryptonote::print_money(outs_for_amount.amount) << " - " << outs_for_amount.outs.size();
+ }
+ return ss.str();
+ }
+
+ private:
+ scanty_outs_t m_scanty_outs;
+ size_t m_mixin_count;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct tx_not_constructed : public transfer_error
+ {
+ typedef std::vector<cryptonote::tx_source_entry> sources_t;
+ typedef std::vector<cryptonote::tx_destination_entry> destinations_t;
+
+ explicit tx_not_constructed(std::string&& loc, const sources_t& sources, const destinations_t& destinations, uint64_t unlock_time)
+ : transfer_error(std::move(loc), "transaction was not constructed")
+ , m_sources(sources)
+ , m_destinations(destinations)
+ , m_unlock_time(unlock_time)
+ {
+ }
+
+ const sources_t& sources() const { return m_sources; }
+ const destinations_t& destinations() const { return m_destinations; }
+ uint64_t unlock_time() const { return m_unlock_time; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << transfer_error::to_string();
+ ss << "\nSources:";
+ for (size_t i = 0; i < m_sources.size(); ++i)
+ {
+ const cryptonote::tx_source_entry& src = m_sources[i];
+ ss << "\n source " << i << ":";
+ ss << "\n amount: " << cryptonote::print_money(src.amount);
+ // It's not good, if logs will contain such much data
+ //ss << "\n real_output: " << src.real_output;
+ //ss << "\n real_output_in_tx_index: " << src.real_output_in_tx_index;
+ //ss << "\n real_out_tx_key: " << epee::string_tools::pod_to_hex(src.real_out_tx_key);
+ //ss << "\n outputs:";
+ //for (size_t j = 0; j < src.outputs.size(); ++j)
+ //{
+ // const cryptonote::tx_source_entry::output_entry& out = src.outputs[j];
+ // ss << "\n " << j << ": " << out.first << ", " << epee::string_tools::pod_to_hex(out.second);
+ //}
+ }
+
+ ss << "\nDestinations:";
+ for (size_t i = 0; i < m_destinations.size(); ++i)
+ {
+ const cryptonote::tx_destination_entry& dst = m_destinations[i];
+ ss << "\n " << i << ": " << cryptonote::get_account_address_as_str(dst.addr) << " " <<
+ cryptonote::print_money(dst.amount);
+ }
+
+ ss << "\nunlock_time: " << m_unlock_time;
+
+ return ss.str();
+ }
+
+ private:
+ sources_t m_sources;
+ destinations_t m_destinations;
+ uint64_t m_unlock_time;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct tx_rejected : public transfer_error
+ {
+ explicit tx_rejected(std::string&& loc, const cryptonote::transaction& tx, const std::string& status)
+ : transfer_error(std::move(loc), "transaction was rejected by daemon")
+ , m_tx(tx)
+ , m_status(status)
+ {
+ }
+
+ const cryptonote::transaction& tx() const { return m_tx; }
+ const std::string& status() const { return m_status; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << transfer_error::to_string() << ", status = " << m_status << ", tx:\n";
+ cryptonote::transaction tx = m_tx;
+ ss << cryptonote::obj_to_json_str(tx);
+ return ss.str();
+ }
+
+ private:
+ cryptonote::transaction m_tx;
+ std::string m_status;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct tx_sum_overflow : public transfer_error
+ {
+ tx_sum_overflow(std::string&& loc, const std::vector<cryptonote::tx_destination_entry>& destinations, uint64_t fee)
+ : transfer_error(std::move(loc), "transaction sum + fee exceeds " + cryptonote::print_money(std::numeric_limits<uint64_t>::max()))
+ , m_destinations(destinations)
+ , m_fee(fee)
+ {
+ }
+
+ const std::vector<cryptonote::tx_destination_entry>& destinations() const { return m_destinations; }
+ uint64_t fee() const { return m_fee; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << transfer_error::to_string() <<
+ ", fee = " << cryptonote::print_money(m_fee) <<
+ ", destinations:";
+ for (const auto& dst : m_destinations)
+ {
+ ss << '\n' << cryptonote::print_money(dst.amount) << " -> " << cryptonote::get_account_address_as_str(dst.addr);
+ }
+ return ss.str();
+ }
+
+ private:
+ std::vector<cryptonote::tx_destination_entry> m_destinations;
+ uint64_t m_fee;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct tx_too_big : public transfer_error
+ {
+ explicit tx_too_big(std::string&& loc, const cryptonote::transaction& tx, uint64_t tx_size_limit)
+ : transfer_error(std::move(loc), "transaction is too big")
+ , m_tx(tx)
+ , m_tx_size_limit(tx_size_limit)
+ {
+ }
+
+ const cryptonote::transaction& tx() const { return m_tx; }
+ uint64_t tx_size_limit() const { return m_tx_size_limit; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ cryptonote::transaction tx = m_tx;
+ ss << transfer_error::to_string() <<
+ ", tx_size_limit = " << m_tx_size_limit <<
+ ", tx size = " << get_object_blobsize(m_tx) <<
+ ", tx:\n" << cryptonote::obj_to_json_str(tx);
+ return ss.str();
+ }
+
+ private:
+ cryptonote::transaction m_tx;
+ uint64_t m_tx_size_limit;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct zero_destination : public transfer_error
+ {
+ explicit zero_destination(std::string&& loc)
+ : transfer_error(std::move(loc), "destination amount is zero")
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct wallet_rpc_error : public wallet_logic_error
+ {
+ const std::string& request() const { return m_request; }
+
+ std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << wallet_logic_error::to_string() << ", request = " << m_request;
+ return ss.str();
+ }
+
+ protected:
+ wallet_rpc_error(std::string&& loc, const std::string& message, const std::string& request)
+ : wallet_logic_error(std::move(loc), message)
+ , m_request(request)
+ {
+ }
+
+ private:
+ std::string m_request;
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct daemon_busy : public wallet_rpc_error
+ {
+ explicit daemon_busy(std::string&& loc, const std::string& request)
+ : wallet_rpc_error(std::move(loc), "daemon is busy", request)
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct no_connection_to_daemon : public wallet_rpc_error
+ {
+ explicit no_connection_to_daemon(std::string&& loc, const std::string& request)
+ : wallet_rpc_error(std::move(loc), "no connection to daemon", request)
+ {
+ }
+ };
+ //----------------------------------------------------------------------------------------------------
+ struct wallet_files_doesnt_correspond : public wallet_logic_error
+ {
+ explicit wallet_files_doesnt_correspond(std::string&& loc, const std::string& keys_file, const std::string& wallet_file)
+ : wallet_logic_error(std::move(loc), "file " + wallet_file + " does not correspond to " + keys_file)
+ {
+ }
+
+ const std::string& keys_file() const { return m_keys_file; }
+ const std::string& wallet_file() const { return m_wallet_file; }
+
+ std::string to_string() const { return wallet_logic_error::to_string(); }
+
+ private:
+ std::string m_keys_file;
+ std::string m_wallet_file;
+ };
+ //----------------------------------------------------------------------------------------------------
+
+#if !defined(_MSC_VER)
+
+ template<typename TException, typename... TArgs>
+ void throw_wallet_ex(std::string&& loc, const TArgs&... args)
+ {
+ TException e(std::move(loc), args...);
+ LOG_PRINT_L0(e.to_string());
+ throw e;
+ }
+
+#else
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+ template<typename TException>
+ void throw_wallet_ex(std::string&& loc)
+ {
+ TException e(std::move(loc));
+ LOG_PRINT_L0(e.to_string());
+ throw e;
+ }
+
+#define GEN_throw_wallet_ex(z, n, data) \
+ template<typename TException, BOOST_PP_ENUM_PARAMS(n, typename TArg)> \
+ void throw_wallet_ex(std::string&& loc, BOOST_PP_ENUM_BINARY_PARAMS(n, const TArg, &arg)) \
+ { \
+ TException e(std::move(loc), BOOST_PP_ENUM_PARAMS(n, arg)); \
+ LOG_PRINT_L0(e.to_string()); \
+ throw e; \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO(1, 6, GEN_throw_wallet_ex, ~)
+#endif
+ }
+}
+
+#define STRINGIZE_DETAIL(x) #x
+#define STRINGIZE(x) STRINGIZE_DETAIL(x)
+
+#define CHECK_AND_THROW_WALLET_EX(cond, err_type, ...) \
+ if (cond) \
+ { \
+ LOG_ERROR(#cond << ". THROW EXCEPTION: " << #err_type); \
+ tools::error::throw_wallet_ex<err_type>(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__); \
+ }