Merge pull request #1949

0ee018b4 wallet2: do not go over the target tx size if many destinations (moneromooo-monero)
9ae566d0 simplewallet: fix cold signing of split transactions (moneromooo-monero)
aae14a10 simplewallet: allow setting confirm-missing-payment-id in watch wallets (moneromooo-monero)
This commit is contained in:
Riccardo Spagni 2017-04-11 00:25:09 +02:00
commit 9c2bcabcdd
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
2 changed files with 21 additions and 21 deletions

View File

@ -560,12 +560,6 @@ bool simple_wallet::set_refresh_type(const std::vector<std::string> &args/* = st
bool simple_wallet::set_confirm_missing_payment_id(const std::vector<std::string> &args/* = std::vector<std::string>()*/) bool simple_wallet::set_confirm_missing_payment_id(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{ {
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(); const auto pwd_container = get_and_verify_password();
if (pwd_container) if (pwd_container)
{ {
@ -2911,6 +2905,7 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
size_t min_mixin = ~0; size_t min_mixin = ~0;
std::unordered_map<std::string, uint64_t> dests; std::unordered_map<std::string, uint64_t> dests;
const std::string wallet_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet()); 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) for (size_t n = 0; n < get_num_txes(); ++n)
{ {
const tools::wallet2::tx_construction_data &cd = get_tx(n); const tools::wallet2::tx_construction_data &cd = get_tx(n);
@ -2945,11 +2940,16 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
fail_msg_writer() << tr("Claimed change is larger than payment to the change address"); fail_msg_writer() << tr("Claimed change is larger than payment to the change address");
return false; 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"); 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; return false;
} }
}
change += cd.change_dts.amount; change += cd.change_dts.amount;
it->second -= cd.change_dts.amount; it->second -= cd.change_dts.amount;
if (it->second == 0) if (it->second == 0)

View File

@ -4102,6 +4102,14 @@ static size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs)
return size; 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<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money) const std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money) const
{ {
std::vector<size_t> picks; std::vector<size_t> picks;
@ -4409,7 +4417,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
} }
else else
{ {
while (!dsts.empty() && dsts[0].amount <= available_amount) while (!dsts.empty() && dsts[0].amount <= available_amount && estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()) < TX_SIZE_TARGET(upper_transaction_size_limit))
{ {
// we can fully pay that destination // we can fully pay that destination
LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_testnet, dsts[0].addr) << LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_testnet, dsts[0].addr) <<
@ -4420,7 +4428,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
pop_index(dsts, 0); pop_index(dsts, 0);
} }
if (available_amount > 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 // we can partially fill that destination
LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_testnet, dsts[0].addr) << 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)); " for " << print_money(available_amount) << "/" << print_money(dsts[0].amount));
@ -4441,11 +4449,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
} }
else else
{ {
size_t estimated_rct_tx_size; const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.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;
try_tx = dsts.empty() || (estimated_rct_tx_size >= TX_SIZE_TARGET(upper_transaction_size_limit)); try_tx = dsts.empty() || (estimated_rct_tx_size >= TX_SIZE_TARGET(upper_transaction_size_limit));
} }
@ -4633,11 +4637,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
// here, check if we need to sent tx and start a new one // 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 " LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit "
<< upper_transaction_size_limit); << upper_transaction_size_limit);
size_t estimated_rct_tx_size; const size_t estimated_rct_tx_size = estimate_tx_size(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 1);
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;
bool try_tx = (unused_dust_indices.empty() && unused_transfers_indices.empty()) || ( estimated_rct_tx_size >= TX_SIZE_TARGET(upper_transaction_size_limit)); 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) { if (try_tx) {