aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp6
-rw-r--r--src/blockchain_utilities/CMakeLists.txt2
-rw-r--r--src/cryptonote_config.h2
-rw-r--r--src/cryptonote_core/blockchain.cpp35
-rwxr-xr-x[-rw-r--r--]src/rpc/core_rpc_server.cpp2
-rwxr-xr-x[-rw-r--r--]src/rpc/rpc_args.cpp18
-rwxr-xr-x[-rw-r--r--]src/rpc/rpc_args.h2
-rw-r--r--src/wallet/api/wallet.cpp3
-rw-r--r--src/wallet/api/wallet.h12
-rw-r--r--src/wallet/wallet2.cpp24
-rw-r--r--src/wallet/wallet2.h19
-rw-r--r--src/wallet/wallet2_api.h12
-rwxr-xr-x[-rw-r--r--]src/wallet/wallet_rpc_server.cpp189
-rw-r--r--src/wallet/wallet_rpc_server.h1
-rw-r--r--src/wallet/wallet_rpc_server_error_codes.h8
15 files changed, 201 insertions, 134 deletions
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 3979a5edf..5bd02bcf7 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -1123,6 +1123,12 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
m_folder = filename;
+#ifdef __OpenBSD__
+ if ((mdb_flags & MDB_WRITEMAP) == 0) {
+ MCLOG_RED(el::Level::Info, "global", "Running on OpenBSD: forcing WRITEMAP");
+ mdb_flags |= MDB_WRITEMAP;
+ }
+#endif
// set up lmdb environment
if ((result = mdb_env_create(&m_env)))
throw0(DB_ERROR(lmdb_error("Failed to create lmdb environment: ", result).c_str()));
diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt
index 0eaf71084..bd32e0c55 100644
--- a/src/blockchain_utilities/CMakeLists.txt
+++ b/src/blockchain_utilities/CMakeLists.txt
@@ -93,6 +93,7 @@ endif()
set_property(TARGET blockchain_import
PROPERTY
OUTPUT_NAME "monero-blockchain-import")
+install(TARGETS blockchain_import DESTINATION bin)
monero_add_executable(blockchain_export
${blockchain_export_sources}
@@ -114,4 +115,5 @@ target_link_libraries(blockchain_export
set_property(TARGET blockchain_export
PROPERTY
OUTPUT_NAME "monero-blockchain-export")
+install(TARGETS blockchain_export DESTINATION bin)
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 5a61fc78c..e38e15cb2 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -150,7 +150,7 @@ namespace config
uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 18;
uint64_t const CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 19;
- uint64_t const CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX = 26;
+ uint64_t const CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX = 42;
uint16_t const P2P_DEFAULT_PORT = 18080;
uint16_t const RPC_DEFAULT_PORT = 18081;
uint16_t const ZMQ_RPC_DEFAULT_PORT = 18082;
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 933914363..9d89c6280 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -139,14 +139,20 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) :
bool Blockchain::have_tx(const crypto::hash &id) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
return m_db->tx_exists(id);
}
//------------------------------------------------------------------
bool Blockchain::have_tx_keyimg_as_spent(const crypto::key_image &key_im) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
return m_db->has_key_image(key_im);
}
//------------------------------------------------------------------
@@ -287,7 +293,10 @@ bool Blockchain::scan_outputkeys_for_indexes(size_t tx_version, const txin_to_ke
uint64_t Blockchain::get_current_blockchain_height() const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
return m_db->height();
}
//------------------------------------------------------------------
@@ -571,7 +580,10 @@ crypto::hash Blockchain::get_tail_id(uint64_t& height) const
crypto::hash Blockchain::get_tail_id() const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
return m_db->top_block_hash();
}
//------------------------------------------------------------------
@@ -633,7 +645,10 @@ bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids) const
crypto::hash Blockchain::get_block_id_by_height(uint64_t height) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
try
{
return m_db->get_block_hash_from_height(height);
@@ -1928,7 +1943,10 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
uint64_t Blockchain::block_difficulty(uint64_t i) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
try
{
return m_db->get_block_difficulty(i);
@@ -2209,7 +2227,10 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, block_verification_
size_t Blockchain::get_total_transactions() const
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ // WARNING: this function does not take m_blockchain_lock, and thus should only call read only
+ // m_db functions which do not depend on one another (ie, no getheight + gethash(height-1), as
+ // well as not accessing class members, even read only (ie, m_invalid_blocks). The caller must
+ // lock if it is otherwise needed.
return m_db->get_tx_count();
}
//------------------------------------------------------------------
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 9095aacae..b3ce30d0c 100644..100755
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -101,7 +101,7 @@ namespace cryptonote
http_login.emplace(std::move(rpc_config->login->username), std::move(rpc_config->login->password).password());
return epee::http_server_impl_base<core_rpc_server, connection_context>::init(
- std::move(port), std::move(rpc_config->bind_ip), std::move(http_login)
+ std::move(port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login)
);
}
//------------------------------------------------------------------------------------------------------------------------------
diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp
index 4435f74d1..93309bf3c 100644..100755
--- a/src/rpc/rpc_args.cpp
+++ b/src/rpc/rpc_args.cpp
@@ -28,6 +28,7 @@
//
#include "rpc_args.h"
+#include <boost/algorithm/string.hpp>
#include <boost/asio/ip/address.hpp>
#include "common/command_line.h"
#include "common/i18n.h"
@@ -38,6 +39,7 @@ namespace cryptonote
: rpc_bind_ip({"rpc-bind-ip", rpc_args::tr("Specify ip to bind rpc server"), "127.0.0.1"})
, rpc_login({"rpc-login", rpc_args::tr("Specify username[:password] required for RPC server"), "", true})
, confirm_external_bind({"confirm-external-bind", rpc_args::tr("Confirm rpc-bind-ip value is NOT a loopback (local) IP")})
+ , rpc_access_control_origins({"rpc-access-control-origins", rpc_args::tr("Specify a comma separated list of origins to allow cross origin resource sharing"), ""})
{}
const char* rpc_args::tr(const char* str) { return i18n_translate(str, "cryptonote::rpc_args"); }
@@ -48,6 +50,7 @@ namespace cryptonote
command_line::add_arg(desc, arg.rpc_bind_ip);
command_line::add_arg(desc, arg.rpc_login);
command_line::add_arg(desc, arg.confirm_external_bind);
+ command_line::add_arg(desc, arg.rpc_access_control_origins);
}
boost::optional<rpc_args> rpc_args::process(const boost::program_options::variables_map& vm)
@@ -91,6 +94,21 @@ namespace cryptonote
}
}
+ auto access_control_origins_input = command_line::get_arg(vm, arg.rpc_access_control_origins);
+ if (!access_control_origins_input.empty())
+ {
+ if (!config.login)
+ {
+ LOG_ERROR(arg.rpc_access_control_origins.name << tr(" requires RFC server password --") << arg.rpc_login.name << tr(" cannot be empty"));
+ return boost::none;
+ }
+
+ std::vector<std::string> access_control_origins;
+ boost::split(access_control_origins, access_control_origins_input, boost::is_any_of(","));
+ std::for_each(access_control_origins.begin(), access_control_origins.end(), boost::bind(&boost::trim<std::string>, _1, std::locale::classic()));
+ config.access_control_origins = std::move(access_control_origins);
+ }
+
return {std::move(config)};
}
}
diff --git a/src/rpc/rpc_args.h b/src/rpc/rpc_args.h
index d6e7bab07..72b5aa706 100644..100755
--- a/src/rpc/rpc_args.h
+++ b/src/rpc/rpc_args.h
@@ -53,6 +53,7 @@ namespace cryptonote
const command_line::arg_descriptor<std::string> rpc_bind_ip;
const command_line::arg_descriptor<std::string> rpc_login;
const command_line::arg_descriptor<bool> confirm_external_bind;
+ const command_line::arg_descriptor<std::string> rpc_access_control_origins;
};
static const char* tr(const char* str);
@@ -62,6 +63,7 @@ namespace cryptonote
static boost::optional<rpc_args> process(const boost::program_options::variables_map& vm);
std::string bind_ip;
+ std::vector<std::string> access_control_origins;
boost::optional<tools::login> login; // currently `boost::none` if unspecified by user
};
}
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index db7e60cd7..8f7befc8c 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -1044,8 +1044,7 @@ void WalletImpl::setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex
// - confirmed_transfer_details)
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, optional<uint64_t> amount, uint32_t mixin_count,
- uint32_t subaddr_account, std::set<uint32_t> subaddr_indices,
- PendingTransaction::Priority priority)
+ PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
{
clearStatus();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index ecb218ea0..051eda3ba 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -73,7 +73,7 @@ public:
int status() const;
std::string errorString() const;
bool setPassword(const std::string &password);
- std::string address(uint32_t accountIndex, uint32_t addressIndex) const;
+ std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const;
std::string integratedAddress(const std::string &payment_id) const;
std::string secretViewKey() const;
std::string publicViewKey() const;
@@ -88,8 +88,8 @@ public:
ConnectionStatus connected() const;
void setTrustedDaemon(bool arg);
bool trustedDaemon() const;
- uint64_t balance(uint32_t accountIndex) const;
- uint64_t unlockedBalance(uint32_t accountIndex) const;
+ uint64_t balance(uint32_t accountIndex = 0) const;
+ uint64_t unlockedBalance(uint32_t accountIndex = 0) const;
uint64_t blockChainHeight() const;
uint64_t approximateBlockChainHeight() const;
uint64_t daemonBlockChainHeight() const;
@@ -117,9 +117,9 @@ public:
PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
optional<uint64_t> amount, uint32_t mixin_count,
- uint32_t subaddr_account,
- std::set<uint32_t> subaddr_indices,
- PendingTransaction::Priority priority = PendingTransaction::Priority_Low);
+ PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
+ uint32_t subaddr_account = 0,
+ std::set<uint32_t> subaddr_indices = {});
virtual PendingTransaction * createSweepUnmixableTransaction();
bool submitTransaction(const std::string &fileName);
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename);
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index cc0e9e7e2..22afac7b7 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -692,20 +692,20 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
//----------------------------------------------------------------------------------------------------
std::string wallet2::get_subaddress_label(const cryptonote::subaddress_index& index) const
{
- if (index.major >= m_subaddress_labels.size())
- throw std::runtime_error("index.major is out of bound");
- if (index.minor >= m_subaddress_labels[index.major].size())
- throw std::runtime_error("index.minor is out of bound");
+ if (index.major >= m_subaddress_labels.size() || index.minor >= m_subaddress_labels[index.major].size())
+ {
+ MERROR("Subaddress label doesn't exist");
+ return "";
+ }
return m_subaddress_labels[index.major][index.minor];
}
//----------------------------------------------------------------------------------------------------
void wallet2::set_subaddress_label(const cryptonote::subaddress_index& index, const std::string &label)
{
- if (index.major >= m_subaddress_labels.size())
- throw std::runtime_error("index.major is out of bound");
- if (index.minor >= m_subaddress_labels[index.major].size())
- throw std::runtime_error("index.minor is out of bound");
- m_subaddress_labels[index.major][index.minor] = label;
+ if (index.major >= m_subaddress_labels.size() || index.minor >= m_subaddress_labels[index.major].size())
+ MERROR("Subaddress index is out of bounds. Failed to set subaddress label.");
+ else
+ m_subaddress_labels[index.major][index.minor] = label;
}
//----------------------------------------------------------------------------------------------------
/*!
@@ -788,7 +788,7 @@ void wallet2::scan_output(const cryptonote::account_keys &keys, const cryptonote
{
tx_scan_info.money_transfered = tools::decodeRct(tx.rct_signatures, tx_scan_info.received->derivation, i, tx_scan_info.mask);
}
- tx_money_got_in_outs[tx_scan_info.received->index] = tx_scan_info.money_transfered;
+ tx_money_got_in_outs[tx_scan_info.received->index] += tx_scan_info.money_transfered;
tx_scan_info.amount = tx_scan_info.money_transfered;
++num_vouts_received;
}
@@ -1520,7 +1520,7 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei
void wallet2::remove_obsolete_pool_txs(const std::vector<crypto::hash> &tx_hashes)
{
// remove pool txes to us that aren't in the pool anymore
- std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin();
+ std::unordered_multimap<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin();
while (uit != m_unconfirmed_payments.end())
{
const crypto::hash &txid = uit->second.m_tx_hash;
@@ -4751,7 +4751,7 @@ static size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs)
size += (2*64*32+32+64*32) * n_outputs;
// MGs
- size += n_inputs * (32 * (mixin+1) + 32);
+ size += n_inputs * (64 * (mixin+1) + 32);
// mixRing - not serialized, can be reconstructed
/* size += 2 * 32 * (mixin+1) * n_inputs; */
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 26680c3da..746255fa9 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -467,8 +467,8 @@ namespace tools
size_t get_num_subaddresses(uint32_t index_major) const { return index_major < m_subaddress_labels.size() ? m_subaddress_labels[index_major].size() : 0; }
void add_subaddress(uint32_t index_major, const std::string& label); // throws when index is out of bound
void expand_subaddresses(const cryptonote::subaddress_index& index);
- std::string get_subaddress_label(const cryptonote::subaddress_index& index) const; // throws when index is out of bound
- void set_subaddress_label(const cryptonote::subaddress_index &index, const std::string &label); // throws when index is out of bound
+ std::string get_subaddress_label(const cryptonote::subaddress_index& index) const;
+ void set_subaddress_label(const cryptonote::subaddress_index &index, const std::string &label);
/*!
* \brief Tells if the wallet file is deprecated.
*/
@@ -1042,7 +1042,10 @@ namespace boost
x.m_amount_out += x.m_change;
}
if (ver < 7)
+ {
+ x.m_subaddr_account = 0;
return;
+ }
a & x.m_subaddr_account;
a & x.m_subaddr_indices;
}
@@ -1083,7 +1086,10 @@ namespace boost
}
a & x.m_unlock_time;
if (ver < 5)
+ {
+ x.m_subaddr_account = 0;
return;
+ }
a & x.m_subaddr_account;
a & x.m_subaddr_indices;
}
@@ -1099,7 +1105,10 @@ namespace boost
return;
a & x.m_timestamp;
if (ver < 2)
+ {
+ x.m_subaddr_index = {};
return;
+ }
a & x.m_subaddr_index;
}
@@ -1110,7 +1119,10 @@ namespace boost
a & x.m_payment_id;
a & x.m_description;
if (ver < 17)
+ {
+ x.m_is_subaddress = false;
return;
+ }
a & x.m_is_subaddress;
}
@@ -1140,7 +1152,10 @@ namespace boost
a & x.use_rct;
a & x.dests;
if (ver < 1)
+ {
+ x.subaddr_account = 0;
return;
+ }
a & x.subaddr_account;
a & x.subaddr_indices;
}
diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h
index 4d734ab94..a8c150ca7 100644
--- a/src/wallet/wallet2_api.h
+++ b/src/wallet/wallet2_api.h
@@ -360,7 +360,7 @@ struct Wallet
//! in case error status, returns error string
virtual std::string errorString() const = 0;
virtual bool setPassword(const std::string &password) = 0;
- virtual std::string address(uint32_t accountIndex, uint32_t addressIndex) const = 0;
+ virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
std::string mainAddress() const { return address(0, 0); }
virtual std::string path() const = 0;
virtual bool testnet() const = 0;
@@ -476,14 +476,14 @@ struct Wallet
virtual ConnectionStatus connected() const = 0;
virtual void setTrustedDaemon(bool arg) = 0;
virtual bool trustedDaemon() const = 0;
- virtual uint64_t balance(uint32_t accountIndex) const = 0;
+ virtual uint64_t balance(uint32_t accountIndex = 0) const = 0;
uint64_t balanceAll() const {
uint64_t result = 0;
for (uint32_t i = 0; i < numSubaddressAccounts(); ++i)
result += balance(i);
return result;
}
- virtual uint64_t unlockedBalance(uint32_t accountIndex) const = 0;
+ virtual uint64_t unlockedBalance(uint32_t accountIndex = 0) const = 0;
uint64_t unlockedBalanceAll() const {
uint64_t result = 0;
for (uint32_t i = 0; i < numSubaddressAccounts(); ++i)
@@ -623,9 +623,9 @@ struct Wallet
virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
optional<uint64_t> amount, uint32_t mixin_count,
- uint32_t subaddr_account,
- std::set<uint32_t> subaddr_indices,
- PendingTransaction::Priority = PendingTransaction::Priority_Low) = 0;
+ PendingTransaction::Priority = PendingTransaction::Priority_Low,
+ uint32_t subaddr_account = 0,
+ std::set<uint32_t> subaddr_indices = {}) = 0;
/*!
* \brief createSweepUnmixableTransaction creates transaction with unmixable outputs.
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index a048a53ae..acd5357ed 100644..100755
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -216,7 +216,7 @@ namespace tools
m_net_server.set_threads_prefix("RPC");
return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init(
- std::move(bind_port), std::move(rpc_config->bind_ip), std::move(http_login)
+ std::move(bind_port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login)
);
}
//------------------------------------------------------------------------------------------------------------------------------
@@ -341,8 +341,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -369,8 +368,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -406,8 +404,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -436,8 +433,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -454,8 +450,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -476,8 +471,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -492,8 +486,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -618,7 +611,7 @@ namespace tools
// reject proposed transactions if there are more than one. see on_transfer_split below.
if (ptx_vector.size() != 1)
{
- er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
+ er.code = WALLET_RPC_ERROR_CODE_TX_TOO_LARGE;
er.message = "Transaction would be too large. try /transfer_split.";
return false;
}
@@ -642,22 +635,9 @@ namespace tools
}
return true;
}
- catch (const tools::error::daemon_busy& e)
- {
- er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY;
- er.message = e.what();
- return false;
- }
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
- er.message = e.what();
- return false;
- }
- catch (...)
- {
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR";
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
return true;
@@ -725,22 +705,9 @@ namespace tools
return true;
}
- catch (const tools::error::daemon_busy& e)
- {
- er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY;
- er.message = e.what();
- return false;
- }
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
- er.message = e.what();
- return false;
- }
- catch (...)
- {
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR";
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
return true;
@@ -782,22 +749,9 @@ namespace tools
return true;
}
- catch (const tools::error::daemon_busy& e)
- {
- er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY;
- er.message = e.what();
- return false;
- }
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
- er.message = e.what();
- return false;
- }
- catch (...)
- {
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR";
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
return true;
@@ -852,22 +806,9 @@ namespace tools
return true;
}
- catch (const tools::error::daemon_busy& e)
- {
- er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY;
- er.message = e.what();
- return false;
- }
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
- er.message = e.what();
- return false;
- }
- catch (...)
- {
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR";
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
return true;
@@ -897,10 +838,9 @@ namespace tools
res.payment_id = epee::string_tools::pod_to_hex(payment_id);
return true;
}
- catch (const std::exception &e)
+ catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -929,10 +869,9 @@ namespace tools
res.payment_id = epee::string_tools::pod_to_hex(info.payment_id);
return true;
}
- catch (const std::exception &e)
+ catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -954,8 +893,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -1185,8 +1123,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -1258,8 +1195,7 @@ namespace tools
}
catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -1494,10 +1430,9 @@ namespace tools
}
}
- catch (...)
+ catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = "Failed";
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
@@ -1550,10 +1485,9 @@ namespace tools
res.height = height;
}
- catch (...)
+ catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = "Failed";
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
@@ -1730,10 +1664,9 @@ namespace tools
m_wallet->rescan_spent();
return true;
}
- catch (const std::exception &e)
+ catch (const std::exception& e)
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
- er.message = e.what();
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
return false;
}
return true;
@@ -1798,7 +1731,7 @@ namespace tools
{
if (m_wallet_dir.empty())
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
+ er.code = WALLET_RPC_ERROR_CODE_NO_WALLET_DIR;
er.message = "No wallet dir configured";
return false;
}
@@ -1866,6 +1799,11 @@ namespace tools
}
catch (const std::exception& e)
{
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
+ return false;
+ }
+ if (!wal)
+ {
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = "Failed to generate wallet";
return false;
@@ -1880,7 +1818,7 @@ namespace tools
{
if (m_wallet_dir.empty())
{
- er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
+ er.code = WALLET_RPC_ERROR_CODE_NO_WALLET_DIR;
er.message = "No wallet dir configured";
return false;
}
@@ -1914,13 +1852,13 @@ namespace tools
command_line::add_arg(desc, arg_password);
po::store(po::parse_command_line(argc, argv, desc), vm2);
}
- std::unique_ptr<tools::wallet2> wal;
+ std::unique_ptr<tools::wallet2> wal = nullptr;
try {
wal = tools::wallet2::make_from_file(vm2, wallet_file).first;
}
catch (const std::exception& e)
{
- wal = nullptr;
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
}
if (!wal)
{
@@ -1934,6 +1872,63 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ void wallet_rpc_server::handle_rpc_exception(const std::exception_ptr& e, epee::json_rpc::error& er, int default_error_code) {
+ try
+ {
+ std::rethrow_exception(e);
+ }
+ catch (const tools::error::daemon_busy& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY;
+ er.message = e.what();
+ }
+ catch (const tools::error::zero_destination& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_ZERO_DESTINATION;
+ er.message = e.what();
+ }
+ catch (const tools::error::not_enough_money& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY;
+ er.message = e.what();
+ }
+ catch (const tools::error::tx_not_possible& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
+ er.message = (boost::format(tr("Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)")) %
+ cryptonote::print_money(e.available()) %
+ cryptonote::print_money(e.tx_amount() + e.fee()) %
+ cryptonote::print_money(e.tx_amount()) %
+ cryptonote::print_money(e.fee())).str();
+ er.message = e.what();
+ }
+ catch (const tools::error::not_enough_outs_to_mix& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_NOT_ENOUGH_OUTS_TO_MIX;
+ er.message = e.what();
+ }
+ catch (const error::file_exists& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_WALLET_ALREADY_EXISTS;
+ er.message = "Cannot create wallet. Already exists.";
+ }
+ catch (const error::invalid_password& e)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_INVALID_PASSWORD;
+ er.message = "Invalid password.";
+ }
+ catch (const std::exception& e)
+ {
+ er.code = default_error_code;
+ er.message = e.what();
+ }
+ catch (...)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
+ er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR";
+ }
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
}
int main(int argc, char** argv) {
diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h
index 7f4c412e4..f2d98df6f 100644
--- a/src/wallet/wallet_rpc_server.h
+++ b/src/wallet/wallet_rpc_server.h
@@ -162,6 +162,7 @@ namespace tools
void fill_transfer_entry(tools::wallet_rpc::transfer_entry &entry, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd);
bool not_open(epee::json_rpc::error& er);
uint64_t adjust_mixin(uint64_t mixin);
+ void handle_rpc_exception(const std::exception_ptr& e, epee::json_rpc::error& er, int default_error_code);
wallet2 *m_wallet;
std::string m_wallet_dir;
diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h
index cc9fd3856..e74e9110b 100644
--- a/src/wallet/wallet_rpc_server_error_codes.h
+++ b/src/wallet/wallet_rpc_server_error_codes.h
@@ -46,3 +46,11 @@
#define WALLET_RPC_ERROR_CODE_NOT_OPEN -13
#define WALLET_RPC_ERROR_CODE_ACCOUNT_INDEX_OUTOFBOUND -14
#define WALLET_RPC_ERROR_CODE_ADDRESS_INDEX_OUTOFBOUND -15
+#define WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE -16
+#define WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY -17
+#define WALLET_RPC_ERROR_CODE_TX_TOO_LARGE -18
+#define WALLET_RPC_ERROR_CODE_NOT_ENOUGH_OUTS_TO_MIX -19
+#define WALLET_RPC_ERROR_CODE_ZERO_DESTINATION -20
+#define WALLET_RPC_ERROR_CODE_WALLET_ALREADY_EXISTS -21
+#define WALLET_RPC_ERROR_CODE_INVALID_PASSWORD -22
+#define WALLET_RPC_ERROR_CODE_NO_WALLET_DIR -23