diff options
author | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-04-02 17:00:17 +0100 |
---|---|---|
committer | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-04-02 17:00:17 +0100 |
commit | 29c2859a3e8a935ef605534c6c36333894980d50 (patch) | |
tree | 1d31daa09741cc82ecc24c0c89f15b84e74cb12d /src/wallet/wallet_errors.h | |
parent | some fixes (diff) | |
download | monero-29c2859a3e8a935ef605534c6c36333894980d50.tar.xz |
json rpc for wallet and bugfix
Diffstat (limited to 'src/wallet/wallet_errors.h')
-rw-r--r-- | src/wallet/wallet_errors.h | 611 |
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__); \ + } |