mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
Distinguish "not enough money" and "not enough unlocked money"
Fix #1530
This commit is contained in:
parent
8d511f3c24
commit
b2d416f211
5 changed files with 96 additions and 14 deletions
|
@ -2821,13 +2821,20 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
||||||
}
|
}
|
||||||
catch (const tools::error::not_enough_money& e)
|
catch (const tools::error::not_enough_unlocked_money& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
||||||
print_money(e.available()) %
|
print_money(e.available()) %
|
||||||
print_money(e.tx_amount()));
|
print_money(e.tx_amount()));
|
||||||
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
||||||
}
|
}
|
||||||
|
catch (const tools::error::not_enough_money& e)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
|
||||||
|
print_money(e.available()) %
|
||||||
|
print_money(e.tx_amount()));
|
||||||
|
fail_msg_writer() << tr("Not enough money in overall balance");
|
||||||
|
}
|
||||||
catch (const tools::error::tx_not_possible& e)
|
catch (const tools::error::tx_not_possible& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
||||||
|
@ -2993,13 +3000,20 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
||||||
}
|
}
|
||||||
catch (const tools::error::not_enough_money& e)
|
catch (const tools::error::not_enough_unlocked_money& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
||||||
print_money(e.available()) %
|
print_money(e.available()) %
|
||||||
print_money(e.tx_amount()));
|
print_money(e.tx_amount()));
|
||||||
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
||||||
}
|
}
|
||||||
|
catch (const tools::error::not_enough_money& e)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
|
||||||
|
print_money(e.available()) %
|
||||||
|
print_money(e.tx_amount()));
|
||||||
|
fail_msg_writer() << tr("Not enough money in overall balance");
|
||||||
|
}
|
||||||
catch (const tools::error::tx_not_possible& e)
|
catch (const tools::error::tx_not_possible& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
||||||
|
@ -3273,13 +3287,20 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
||||||
}
|
}
|
||||||
catch (const tools::error::not_enough_money& e)
|
catch (const tools::error::not_enough_unlocked_money& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
||||||
print_money(e.available()) %
|
print_money(e.available()) %
|
||||||
print_money(e.tx_amount()));
|
print_money(e.tx_amount()));
|
||||||
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
||||||
}
|
}
|
||||||
|
catch (const tools::error::not_enough_money& e)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
|
||||||
|
print_money(e.available()) %
|
||||||
|
print_money(e.tx_amount()));
|
||||||
|
fail_msg_writer() << tr("Not enough money in overall balance");
|
||||||
|
}
|
||||||
catch (const tools::error::tx_not_possible& e)
|
catch (const tools::error::tx_not_possible& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
||||||
|
@ -3623,13 +3644,20 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what();
|
||||||
}
|
}
|
||||||
catch (const tools::error::not_enough_money& e)
|
catch (const tools::error::not_enough_unlocked_money& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, sent amount %s") %
|
||||||
print_money(e.available()) %
|
print_money(e.available()) %
|
||||||
print_money(e.tx_amount()));
|
print_money(e.tx_amount()));
|
||||||
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
fail_msg_writer() << tr("Not enough money in unlocked balance");
|
||||||
}
|
}
|
||||||
|
catch (const tools::error::not_enough_money& e)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0(boost::format("not enough money to transfer, overall balance only %s, sent amount %s") %
|
||||||
|
print_money(e.available()) %
|
||||||
|
print_money(e.tx_amount()));
|
||||||
|
fail_msg_writer() << tr("Not enough money in overall balance");
|
||||||
|
}
|
||||||
catch (const tools::error::tx_not_possible& e)
|
catch (const tools::error::tx_not_possible& e)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
LOG_PRINT_L0(boost::format("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)") %
|
||||||
|
|
|
@ -1147,7 +1147,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
||||||
m_errorString = (boost::format(tr("failed to get random outputs to mix: %s")) % e.what()).str();
|
m_errorString = (boost::format(tr("failed to get random outputs to mix: %s")) % e.what()).str();
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
|
|
||||||
} catch (const tools::error::not_enough_money& e) {
|
} catch (const tools::error::not_enough_unlocked_money& e) {
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
std::ostringstream writer;
|
std::ostringstream writer;
|
||||||
|
|
||||||
|
@ -1156,6 +1156,15 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
|
||||||
print_money(e.tx_amount());
|
print_money(e.tx_amount());
|
||||||
m_errorString = writer.str();
|
m_errorString = writer.str();
|
||||||
|
|
||||||
|
} catch (const tools::error::not_enough_money& e) {
|
||||||
|
m_status = Status_Error;
|
||||||
|
std::ostringstream writer;
|
||||||
|
|
||||||
|
writer << boost::format(tr("not enough money to transfer, overall balance only %s, sent amount %s")) %
|
||||||
|
print_money(e.available()) %
|
||||||
|
print_money(e.tx_amount());
|
||||||
|
m_errorString = writer.str();
|
||||||
|
|
||||||
} catch (const tools::error::tx_not_possible& e) {
|
} catch (const tools::error::tx_not_possible& e) {
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
std::ostringstream writer;
|
std::ostringstream writer;
|
||||||
|
@ -1241,7 +1250,7 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
|
||||||
m_errorString = tr("failed to get random outputs to mix");
|
m_errorString = tr("failed to get random outputs to mix");
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
|
|
||||||
} catch (const tools::error::not_enough_money& e) {
|
} catch (const tools::error::not_enough_unlocked_money& e) {
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
std::ostringstream writer;
|
std::ostringstream writer;
|
||||||
|
|
||||||
|
@ -1250,6 +1259,15 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
|
||||||
print_money(e.tx_amount());
|
print_money(e.tx_amount());
|
||||||
m_errorString = writer.str();
|
m_errorString = writer.str();
|
||||||
|
|
||||||
|
} catch (const tools::error::not_enough_money& e) {
|
||||||
|
m_status = Status_Error;
|
||||||
|
std::ostringstream writer;
|
||||||
|
|
||||||
|
writer << boost::format(tr("not enough money to transfer, overall balance only %s, sent amount %s")) %
|
||||||
|
print_money(e.available()) %
|
||||||
|
print_money(e.tx_amount());
|
||||||
|
m_errorString = writer.str();
|
||||||
|
|
||||||
} catch (const tools::error::tx_not_possible& e) {
|
} catch (const tools::error::tx_not_possible& e) {
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
std::ostringstream writer;
|
std::ostringstream writer;
|
||||||
|
|
|
@ -4441,7 +4441,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_PRINT_L2("wanted " << print_money(needed_money) << ", found " << print_money(found_money) << ", fee " << print_money(fee));
|
LOG_PRINT_L2("wanted " << print_money(needed_money) << ", found " << print_money(found_money) << ", fee " << print_money(fee));
|
||||||
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
|
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_unlocked_money, found_money, needed_money - fee, fee);
|
||||||
|
|
||||||
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
|
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
|
||||||
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
|
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
|
||||||
|
@ -4598,7 +4598,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_PRINT_L2("wanted " << print_money(needed_money) << ", found " << print_money(found_money) << ", fee " << print_money(fee));
|
LOG_PRINT_L2("wanted " << print_money(needed_money) << ", found " << print_money(found_money) << ", fee " << print_money(fee));
|
||||||
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
|
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_unlocked_money, found_money, needed_money - fee, fee);
|
||||||
|
|
||||||
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
|
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
|
||||||
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
|
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
|
||||||
|
@ -5475,6 +5475,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// early out if we know we can't make it anyway
|
||||||
|
// we could also check for being within FEE_PER_KB, but if the fee calculation
|
||||||
|
// ever changes, this might be missed, so let this go through
|
||||||
|
// first check overall balance is enough, then unlocked one, so we throw distinct exceptions
|
||||||
|
THROW_WALLET_EXCEPTION_IF(needed_money > balance(), error::not_enough_money,
|
||||||
|
unlocked_balance(), needed_money, 0);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(needed_money > unlocked_balance(), error::not_enough_unlocked_money,
|
||||||
|
unlocked_balance(), needed_money, 0);
|
||||||
|
|
||||||
// shuffle & sort output indices
|
// shuffle & sort output indices
|
||||||
{
|
{
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
|
|
|
@ -1249,10 +1249,10 @@ namespace tools
|
||||||
}
|
}
|
||||||
|
|
||||||
// randomly select inputs for transaction
|
// randomly select inputs for transaction
|
||||||
// throw if requested send amount is greater than amount available to send
|
// throw if requested send amount is greater than (unlocked) amount available to send
|
||||||
std::list<size_t> selected_transfers;
|
std::list<size_t> selected_transfers;
|
||||||
uint64_t found_money = select_transfers(needed_money, unused_transfers_indices, selected_transfers, trusted_daemon);
|
uint64_t found_money = select_transfers(needed_money, unused_transfers_indices, selected_transfers, trusted_daemon);
|
||||||
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_money, found_money, needed_money - fee, fee);
|
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_unlocked_money, found_money, needed_money - fee, fee);
|
||||||
|
|
||||||
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
|
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
|
||||||
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
|
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
|
||||||
|
|
|
@ -68,6 +68,7 @@ namespace tools
|
||||||
// get_tx_pool_error
|
// get_tx_pool_error
|
||||||
// transfer_error *
|
// transfer_error *
|
||||||
// get_random_outs_general_error
|
// get_random_outs_general_error
|
||||||
|
// not_enough_unlocked_money
|
||||||
// not_enough_money
|
// not_enough_money
|
||||||
// tx_not_possible
|
// tx_not_possible
|
||||||
// not_enough_outs_to_mix
|
// not_enough_outs_to_mix
|
||||||
|
@ -356,11 +357,37 @@ namespace tools
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
typedef failed_rpc_request<transfer_error, get_random_outs_error_message_index> get_random_outs_error;
|
typedef failed_rpc_request<transfer_error, get_random_outs_error_message_index> get_random_outs_error;
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
struct not_enough_unlocked_money : public transfer_error
|
||||||
|
{
|
||||||
|
explicit not_enough_unlocked_money(std::string&& loc, uint64_t available, uint64_t tx_amount, uint64_t fee)
|
||||||
|
: transfer_error(std::move(loc), "not enough unlocked money")
|
||||||
|
, m_available(available)
|
||||||
|
, m_tx_amount(tx_amount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t available() const { return m_available; }
|
||||||
|
uint64_t tx_amount() const { return m_tx_amount; }
|
||||||
|
|
||||||
|
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);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64_t m_available;
|
||||||
|
uint64_t m_tx_amount;
|
||||||
|
};
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
struct not_enough_money : public transfer_error
|
struct not_enough_money : public transfer_error
|
||||||
{
|
{
|
||||||
explicit not_enough_money(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee)
|
explicit not_enough_money(std::string&& loc, uint64_t available, uint64_t tx_amount, uint64_t fee)
|
||||||
: transfer_error(std::move(loc), "not enough money")
|
: transfer_error(std::move(loc), "not enough money")
|
||||||
, m_available(availbable)
|
, m_available(available)
|
||||||
, m_tx_amount(tx_amount)
|
, m_tx_amount(tx_amount)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -384,9 +411,9 @@ namespace tools
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
struct tx_not_possible : public transfer_error
|
struct tx_not_possible : public transfer_error
|
||||||
{
|
{
|
||||||
explicit tx_not_possible(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee)
|
explicit tx_not_possible(std::string&& loc, uint64_t available, uint64_t tx_amount, uint64_t fee)
|
||||||
: transfer_error(std::move(loc), "tx not possible")
|
: transfer_error(std::move(loc), "tx not possible")
|
||||||
, m_available(availbable)
|
, m_available(available)
|
||||||
, m_tx_amount(tx_amount)
|
, m_tx_amount(tx_amount)
|
||||||
, m_fee(fee)
|
, m_fee(fee)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue