From aae14a107ac45e2773ecf87bddab277573c2ceff Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 2 Apr 2017 11:10:11 +0100 Subject: [PATCH 1/3] simplewallet: allow setting confirm-missing-payment-id in watch wallets These can create transactions, even though they cannot sign them. --- src/simplewallet/simplewallet.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index f5a469af4..67dacda91 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -559,12 +559,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) { From 9ae566d0ddeeefdfbd35726f7074d32166f5c047 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 2 Apr 2017 11:11:18 +0100 Subject: [PATCH 2/3] simplewallet: fix cold signing of split transactions They'd be rejected as suspicious as the change goes to more than one destination. However, split transactions will most likely include fake zero amount change to random addresses, so we only consider change with non zero amount for this. --- src/simplewallet/simplewallet.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 67dacda91..9215ec821 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3035,6 +3035,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); @@ -3069,10 +3070,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; From 0ee018b40724342afa16dcf448024fb2e974a0e9 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 2 Apr 2017 11:13:15 +0100 Subject: [PATCH 3/3] wallet2: do not go over the target tx size if many destinations If using a large input and many destinations, the code would generate as many outputs as it could using that input, even if it would bring the resulting tx above the max tx size. --- src/wallet/wallet2.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) 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) {