forked from lthn/blockchain
added more proper handling of exception in rpc handlers
This commit is contained in:
parent
3fec14f95e
commit
84066c7203
3 changed files with 134 additions and 113 deletions
|
|
@ -41,6 +41,86 @@ namespace ph = boost::placeholders;
|
|||
#define EXTENDED_LOGS_FILE "wallet_details.log"
|
||||
|
||||
|
||||
#define SIMPLE_WALLET_BEGIN_TRY_ENTRY() try {
|
||||
#define SIMPLE_WALLET_CATCH_TRY_ENTRY() } \
|
||||
catch (const tools::error::daemon_busy&) \
|
||||
{ \
|
||||
fail_msg_writer() << "daemon is busy. Please try later"; \
|
||||
} \
|
||||
catch (const tools::error::no_connection_to_daemon&) \
|
||||
{ \
|
||||
fail_msg_writer() << "no connection to daemon. Please, make sure daemon is running."; \
|
||||
} \
|
||||
catch (const tools::error::wallet_rpc_error& e) \
|
||||
{ \
|
||||
LOG_ERROR("Unknown RPC error: " << e.to_string()); \
|
||||
fail_msg_writer() << "RPC error \"" << e.what() << '"'; \
|
||||
} \
|
||||
catch (const tools::error::get_random_outs_error&) \
|
||||
{ \
|
||||
fail_msg_writer() << "failed to get random outputs to mix"; \
|
||||
} \
|
||||
catch (const tools::error::not_enough_money& e) \
|
||||
{ \
|
||||
fail_msg_writer() << "not enough money to transfer, available only " << print_money(e.available()) << \
|
||||
", transaction amount " << print_money(e.tx_amount() + e.fee()) << " = " << print_money(e.tx_amount()) << \
|
||||
" + " << print_money(e.fee()) << " (fee)"; \
|
||||
} \
|
||||
catch (const tools::error::not_enough_outs_to_mix& e) \
|
||||
{ \
|
||||
auto writer = fail_msg_writer(); \
|
||||
writer << "not enough outputs for specified mixin_count = " << e.mixin_count() << ":"; \
|
||||
for (const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& outs_for_amount : e.scanty_outs()) \
|
||||
{ \
|
||||
writer << "\noutput amount = " << print_money(outs_for_amount.amount) << ", fount outputs to mix = " << outs_for_amount.outs.size(); \
|
||||
} \
|
||||
} \
|
||||
catch (const tools::error::tx_not_constructed&) \
|
||||
{ \
|
||||
fail_msg_writer() << "transaction was not constructed"; \
|
||||
} \
|
||||
catch (const tools::error::tx_rejected& e) \
|
||||
{ \
|
||||
fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " was rejected by daemon with status \"" << e.status() << '"'; \
|
||||
} \
|
||||
catch (const tools::error::tx_sum_overflow& e) \
|
||||
{ \
|
||||
fail_msg_writer() << e.what(); \
|
||||
} \
|
||||
catch (const tools::error::tx_too_big& e) \
|
||||
{ \
|
||||
currency::transaction tx = e.tx(); \
|
||||
fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " is too big. Transaction size: " << \
|
||||
get_object_blobsize(e.tx()) << " bytes, transaction size limit: " << e.tx_size_limit() << " bytes. Try to separate this payment into few smaller transfers."; \
|
||||
} \
|
||||
catch (const tools::error::zero_destination&) \
|
||||
{ \
|
||||
fail_msg_writer() << "one of destinations is zero"; \
|
||||
} \
|
||||
catch (const tools::error::transfer_error& e) \
|
||||
{ \
|
||||
LOG_ERROR("unknown transfer error: " << e.to_string()); \
|
||||
fail_msg_writer() << "unknown transfer error: " << e.what(); \
|
||||
} \
|
||||
catch (const tools::error::wallet_internal_error& e) \
|
||||
{ \
|
||||
LOG_ERROR("internal error: " << e.to_string()); \
|
||||
fail_msg_writer() << "internal error: " << e.what(); \
|
||||
} \
|
||||
catch (const std::exception& e) \
|
||||
{ \
|
||||
LOG_ERROR("unexpected error: " << e.what()); \
|
||||
fail_msg_writer() << "unexpected error: " << e.what(); \
|
||||
} \
|
||||
catch (...) \
|
||||
{ \
|
||||
LOG_ERROR("Unknown error"); \
|
||||
fail_msg_writer() << "unknown error"; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_wallet_file ("wallet-file", "Use wallet <arg>", "");
|
||||
|
|
@ -1271,6 +1351,7 @@ bool preprocess_asset_id(std::string& address_arg, crypto::public_key& asset_id)
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
if (!try_connect_to_daemon())
|
||||
return true;
|
||||
|
||||
|
|
@ -1389,97 +1470,21 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
currency::transaction tx;
|
||||
m_wallet->transfer(dsts, fake_outs_count, 0, m_wallet->get_core_runtime_config().tx_default_fee, extra, attachments, tx);
|
||||
currency::transaction tx;
|
||||
m_wallet->transfer(dsts, fake_outs_count, 0, m_wallet->get_core_runtime_config().tx_default_fee, extra, attachments, tx);
|
||||
|
||||
if (!m_wallet->is_watch_only())
|
||||
{
|
||||
if(wrapped_transaction)
|
||||
success_msg_writer(true) << "Money successfully sent to wZano custody wallet, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
|
||||
else
|
||||
success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
|
||||
}
|
||||
if (!m_wallet->is_watch_only())
|
||||
{
|
||||
if(wrapped_transaction)
|
||||
success_msg_writer(true) << "Money successfully sent to wZano custody wallet, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
|
||||
else
|
||||
{
|
||||
success_msg_writer(true) << "Transaction prepared for signing and saved into \"zano_tx_unsigned\" file, use full wallet to sign transfer and then use \"submit_transfer\" on this wallet to broadcast the transaction to the network";
|
||||
}
|
||||
success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
|
||||
}
|
||||
catch (const tools::error::daemon_busy&)
|
||||
else
|
||||
{
|
||||
fail_msg_writer() << "daemon is busy. Please try later";
|
||||
}
|
||||
catch (const tools::error::no_connection_to_daemon&)
|
||||
{
|
||||
fail_msg_writer() << "no connection to daemon. Please, make sure daemon is running.";
|
||||
}
|
||||
catch (const tools::error::wallet_rpc_error& e)
|
||||
{
|
||||
LOG_ERROR("Unknown RPC error: " << e.to_string());
|
||||
fail_msg_writer() << "RPC error \"" << e.what() << '"';
|
||||
}
|
||||
catch (const tools::error::get_random_outs_error&)
|
||||
{
|
||||
fail_msg_writer() << "failed to get random outputs to mix";
|
||||
}
|
||||
catch (const tools::error::not_enough_money& e)
|
||||
{
|
||||
fail_msg_writer() << "not enough money to transfer, available only " << print_money(e.available()) <<
|
||||
", transaction amount " << print_money(e.tx_amount() + e.fee()) << " = " << print_money(e.tx_amount()) <<
|
||||
" + " << print_money(e.fee()) << " (fee)";
|
||||
}
|
||||
catch (const tools::error::not_enough_outs_to_mix& e)
|
||||
{
|
||||
auto writer = fail_msg_writer();
|
||||
writer << "not enough outputs for specified mixin_count = " << e.mixin_count() << ":";
|
||||
for (const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& outs_for_amount : e.scanty_outs())
|
||||
{
|
||||
writer << "\noutput amount = " << print_money(outs_for_amount.amount) << ", fount outputs to mix = " << outs_for_amount.outs.size();
|
||||
}
|
||||
}
|
||||
catch (const tools::error::tx_not_constructed&)
|
||||
{
|
||||
fail_msg_writer() << "transaction was not constructed";
|
||||
}
|
||||
catch (const tools::error::tx_rejected& e)
|
||||
{
|
||||
fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " was rejected by daemon with status \"" << e.status() << '"';
|
||||
}
|
||||
catch (const tools::error::tx_sum_overflow& e)
|
||||
{
|
||||
fail_msg_writer() << e.what();
|
||||
}
|
||||
catch (const tools::error::tx_too_big& e)
|
||||
{
|
||||
currency::transaction tx = e.tx();
|
||||
fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " is too big. Transaction size: " <<
|
||||
get_object_blobsize(e.tx()) << " bytes, transaction size limit: " << e.tx_size_limit() << " bytes. Try to separate this payment into few smaller transfers.";
|
||||
}
|
||||
catch (const tools::error::zero_destination&)
|
||||
{
|
||||
fail_msg_writer() << "one of destinations is zero";
|
||||
}
|
||||
catch (const tools::error::transfer_error& e)
|
||||
{
|
||||
LOG_ERROR("unknown transfer error: " << e.to_string());
|
||||
fail_msg_writer() << "unknown transfer error: " << e.what();
|
||||
}
|
||||
catch (const tools::error::wallet_internal_error& e)
|
||||
{
|
||||
LOG_ERROR("internal error: " << e.to_string());
|
||||
fail_msg_writer() << "internal error: " << e.what();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR("unexpected error: " << e.what());
|
||||
fail_msg_writer() << "unexpected error: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERROR("Unknown error");
|
||||
fail_msg_writer() << "unknown error";
|
||||
}
|
||||
success_msg_writer(true) << "Transaction prepared for signing and saved into \"zano_tx_unsigned\" file, use full wallet to sign transfer and then use \"submit_transfer\" on this wallet to broadcast the transaction to the network";
|
||||
}
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1806,6 +1811,7 @@ bool simple_wallet::tor_disable(const std::vector<std::string> &args)
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::deploy_new_asset(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
asset_descriptor_base adb = AUTO_VAL_INIT(adb);
|
||||
if (!args.size() || args.size() > 1)
|
||||
{
|
||||
|
|
@ -1826,19 +1832,21 @@ bool simple_wallet::deploy_new_asset(const std::vector<std::string> &args)
|
|||
crypto::public_key result_asset_id = currency::null_pkey;
|
||||
m_wallet->publish_new_asset(adb, destinations, result_tx, result_asset_id);
|
||||
|
||||
success_msg_writer(true) << "New asset deployed: " << ENDL
|
||||
<< "Asset ID: " << result_asset_id << ENDL
|
||||
success_msg_writer(true) << "New asset deployed: " << ENDL
|
||||
<< "Asset ID: " << result_asset_id << ENDL
|
||||
<< "Title: " << adb.full_name << ENDL
|
||||
<< "Ticker: " << adb.ticker << ENDL
|
||||
<< "Emitted: " << print_fixed_decimal_point(adb.current_supply, adb.decimal_point) << ENDL
|
||||
<< "Max emission: " << print_fixed_decimal_point(adb.total_max_supply, adb.decimal_point) << ENDL
|
||||
;
|
||||
|
||||
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::add_custom_asset_id(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
if (!args.size() || args.size() > 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
|
|
@ -1865,11 +1873,14 @@ bool simple_wallet::add_custom_asset_id(const std::vector<std::string> &args)
|
|||
<< " supply: " << print_fixed_decimal_point(asset_descriptor.current_supply, asset_descriptor.decimal_point) << ENDL
|
||||
;
|
||||
}
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::generate_ionic_swap_proposal(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
|
||||
if (args.size() != 2)
|
||||
{
|
||||
|
|
@ -1906,11 +1917,15 @@ bool simple_wallet::generate_ionic_swap_proposal(const std::vector<std::string>
|
|||
{
|
||||
success_msg_writer() << "Generated proposal: " << ENDL << epee::string_tools::buff_to_hex_nodelimer(t_serializable_object_to_blob(proposal));
|
||||
}
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::get_ionic_swap_proposal_info(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
|
||||
if (args.size() != 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
|
|
@ -1935,11 +1950,14 @@ bool simple_wallet::get_ionic_swap_proposal_info(const std::vector<std::string>
|
|||
|
||||
success_msg_writer() << "Proposal details: " << ENDL << json_proposal_info;
|
||||
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::accept_ionic_swap_proposal(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
|
||||
if (args.size() != 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
|
|
@ -1962,12 +1980,14 @@ bool simple_wallet::accept_ionic_swap_proposal(const std::vector<std::string> &a
|
|||
|
||||
success_msg_writer() << "Proposal accepted and executed, tx_id : " << currency::get_transaction_hash(result_tx);
|
||||
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::remove_custom_asset_id(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
if (!args.size() || args.size() > 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
|
|
@ -1989,11 +2009,14 @@ bool simple_wallet::remove_custom_asset_id(const std::vector<std::string> &args)
|
|||
{
|
||||
success_msg_writer() << "Asset id " << asset_id << " removed from wallet custom list" << ENDL;
|
||||
}
|
||||
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::sweep_below(const std::vector<std::string> &args)
|
||||
{
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
bool r = false;
|
||||
if (args.size() < 3 || args.size() > 4)
|
||||
{
|
||||
|
|
@ -2051,30 +2074,23 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args)
|
|||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint64_t fee = m_wallet->get_core_runtime_config().tx_default_fee;
|
||||
size_t outs_total = 0, outs_swept = 0;
|
||||
uint64_t amount_total = 0, amount_swept = 0;
|
||||
currency::transaction result_tx = AUTO_VAL_INIT(result_tx);
|
||||
std::string filename = "zano_tx_unsigned";
|
||||
m_wallet->sweep_below(fake_outs_count, addr, amount, payment_id, fee, outs_total, amount_total, outs_swept, amount_swept, &result_tx, &filename);
|
||||
|
||||
success_msg_writer(false) << outs_swept << " outputs (" << print_money_brief(amount_swept) << " coins) of " << outs_total << " total (" << print_money_brief(amount_total)
|
||||
<< ") below the specified limit of " << print_money_brief(amount) << " were successfully swept";
|
||||
uint64_t fee = m_wallet->get_core_runtime_config().tx_default_fee;
|
||||
size_t outs_total = 0, outs_swept = 0;
|
||||
uint64_t amount_total = 0, amount_swept = 0;
|
||||
currency::transaction result_tx = AUTO_VAL_INIT(result_tx);
|
||||
std::string filename = "zano_tx_unsigned";
|
||||
m_wallet->sweep_below(fake_outs_count, addr, amount, payment_id, fee, outs_total, amount_total, outs_swept, amount_swept, &result_tx, &filename);
|
||||
|
||||
if (m_wallet->is_watch_only())
|
||||
success_msg_writer(true) << "Transaction prepared for signing and saved into \"" << filename << "\" file, use full wallet to sign transfer and then use \"submit_transfer\" on this wallet to broadcast the transaction to the network";
|
||||
else
|
||||
success_msg_writer(true) << "tx: " << get_transaction_hash(result_tx) << " size: " << get_object_blobsize(result_tx) << " bytes";
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
fail_msg_writer() << e.what();
|
||||
return true;
|
||||
}
|
||||
success_msg_writer(false) << outs_swept << " outputs (" << print_money_brief(amount_swept) << " coins) of " << outs_total << " total (" << print_money_brief(amount_total)
|
||||
<< ") below the specified limit of " << print_money_brief(amount) << " were successfully swept";
|
||||
|
||||
if (m_wallet->is_watch_only())
|
||||
success_msg_writer(true) << "Transaction prepared for signing and saved into \"" << filename << "\" file, use full wallet to sign transfer and then use \"submit_transfer\" on this wallet to broadcast the transaction to the network";
|
||||
else
|
||||
success_msg_writer(true) << "tx: " << get_transaction_hash(result_tx) << " size: " << get_object_blobsize(result_tx) << " bytes";
|
||||
|
||||
SIMPLE_WALLET_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ using namespace epee;
|
|||
er.message = e.error_code(); \
|
||||
return false; \
|
||||
} \
|
||||
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; \
|
||||
|
|
@ -41,7 +47,6 @@ using namespace epee;
|
|||
return false; \
|
||||
}
|
||||
|
||||
|
||||
namespace tools
|
||||
{
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -2051,7 +2051,7 @@ bool wallets_manager::on_mw_select_wallet(uint64_t wallet_id)
|
|||
return false;
|
||||
|
||||
m_rpc_selected_wallet_id = wallet_id;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue