1
0
Fork 0
forked from lthn/blockchain

added more proper handling of exception in rpc handlers

This commit is contained in:
cryptozoidberg 2023-05-25 20:05:39 +02:00
parent 3fec14f95e
commit 84066c7203
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
3 changed files with 134 additions and 113 deletions

View file

@ -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;
}

View file

@ -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
{
//-----------------------------------------------------------------------------------

View file

@ -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;
}