diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index bb761c33e..e925e81b5 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -560,12 +560,6 @@ bool simple_wallet::set_refresh_type(const std::vector &args/* = st bool simple_wallet::set_confirm_missing_payment_id(const std::vector &args/* = std::vector()*/) { - if (m_wallet->watch_only()) - { - fail_msg_writer() << tr("wallet is watch-only and cannot transfer"); - return true; - } - const auto pwd_container = get_and_verify_password(); if (pwd_container) { @@ -2911,6 +2905,7 @@ bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, size_t min_mixin = ~0; std::unordered_map dests; const std::string wallet_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet()); + int first_known_non_zero_change_index = -1; for (size_t n = 0; n < get_num_txes(); ++n) { const tools::wallet2::tx_construction_data &cd = get_tx(n); @@ -2945,10 +2940,15 @@ bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, fail_msg_writer() << tr("Claimed change is larger than payment to the change address"); return false; } - if (memcmp(&cd.change_dts.addr, &get_tx(0).change_dts.addr, sizeof(cd.change_dts.addr))) + if (cd.change_dts.amount > 0) { - fail_msg_writer() << tr("Change does to more than one address"); - return false; + if (first_known_non_zero_change_index == -1) + first_known_non_zero_change_index = n; + if (memcmp(&cd.change_dts.addr, &get_tx(first_known_non_zero_change_index).change_dts.addr, sizeof(cd.change_dts.addr))) + { + fail_msg_writer() << tr("Change goes to more than one address"); + return false; + } } change += cd.change_dts.amount; it->second -= cd.change_dts.amount; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ed31f34a4..941ee8afb 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4102,6 +4102,14 @@ static size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs) return size; } +static size_t estimate_tx_size(bool use_rct, int n_inputs, int mixin, int n_outputs) +{ + if (use_rct) + return estimate_rct_tx_size(n_inputs, mixin, n_outputs + 1); + else + return n_inputs * (mixin+1) * APPROXIMATE_INPUT_BYTES; +} + std::vector wallet2::pick_preferred_rct_inputs(uint64_t needed_money) const { std::vector picks; @@ -4409,7 +4417,7 @@ std::vector wallet2::create_transactions_2(std::vector wallet2::create_transactions_2(std::vector 0 && !dsts.empty()) { + if (available_amount > 0 && !dsts.empty() && estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()) < TX_SIZE_TARGET(upper_transaction_size_limit)) { // we can partially fill that destination LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_testnet, dsts[0].addr) << " for " << print_money(available_amount) << "/" << print_money(dsts[0].amount)); @@ -4441,11 +4449,7 @@ std::vector wallet2::create_transactions_2(std::vector= TX_SIZE_TARGET(upper_transaction_size_limit)); } @@ -4633,11 +4637,7 @@ std::vector wallet2::create_transactions_from(const crypton // here, check if we need to sent tx and start a new one LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit " << upper_transaction_size_limit); - size_t estimated_rct_tx_size; - if (use_rct) - estimated_rct_tx_size = estimate_rct_tx_size(tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 1); - else - estimated_rct_tx_size = tx.selected_transfers.size() * (fake_outs_count+1) * APPROXIMATE_INPUT_BYTES; + const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 1); bool try_tx = (unused_dust_indices.empty() && unused_transfers_indices.empty()) || ( estimated_rct_tx_size >= TX_SIZE_TARGET(upper_transaction_size_limit)); if (try_tx) {