wallet2: fix spurious output splitting when not merging destinations

This commit is contained in:
moneromooo-monero 2017-04-08 11:13:28 +01:00
parent c9063c0b8f
commit 89d707566a
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

View File

@ -4244,14 +4244,24 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
pending_tx ptx; pending_tx ptx;
size_t bytes; size_t bytes;
void add(const account_public_address &addr, uint64_t amount, bool merge_destinations) { void add(const account_public_address &addr, uint64_t amount, unsigned int original_output_index, bool merge_destinations) {
if (merge_destinations)
{
std::vector<cryptonote::tx_destination_entry>::iterator i; std::vector<cryptonote::tx_destination_entry>::iterator i;
i = std::find_if(dsts.begin(), dsts.end(), [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &addr, sizeof(addr)); }); i = std::find_if(dsts.begin(), dsts.end(), [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &addr, sizeof(addr)); });
if (!merge_destinations || i == dsts.end()) if (i == dsts.end())
dsts.push_back(tx_destination_entry(amount,addr)); dsts.push_back(tx_destination_entry(0,addr));
else
i->amount += amount; i->amount += amount;
} }
else
{
THROW_WALLET_EXCEPTION_IF(original_output_index > dsts.size(), error::wallet_internal_error, "original_output_index too large");
if (original_output_index == dsts.size())
dsts.push_back(tx_destination_entry(0,addr));
THROW_WALLET_EXCEPTION_IF(memcmp(&dsts[original_output_index].addr, &addr, sizeof(addr)), error::wallet_internal_error, "Mismatched destination address");
dsts[original_output_index].amount += amount;
}
}
}; };
std::vector<TX> txes; std::vector<TX> txes;
bool adding_fee; // true if new outputs go towards fee, rather than destinations bool adding_fee; // true if new outputs go towards fee, rather than destinations
@ -4339,6 +4349,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// - we have something to send // - we have something to send
// - or we need to gather more fee // - or we need to gather more fee
// - or we have just one input in that tx, which is rct (to try and make all/most rct txes 2/2) // - or we have just one input in that tx, which is rct (to try and make all/most rct txes 2/2)
unsigned int original_output_index = 0;
while ((!dsts.empty() && dsts[0].amount > 0) || adding_fee || should_pick_a_second_output(use_rct, txes.back().selected_transfers.size(), unused_transfers_indices, unused_dust_indices)) { while ((!dsts.empty() && dsts[0].amount > 0) || adding_fee || should_pick_a_second_output(use_rct, txes.back().selected_transfers.size(), unused_transfers_indices, unused_dust_indices)) {
TX &tx = txes.back(); TX &tx = txes.back();
@ -4414,17 +4425,18 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// 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) <<
" for " << print_money(dsts[0].amount)); " for " << print_money(dsts[0].amount));
tx.add(dsts[0].addr, dsts[0].amount, m_merge_destinations); tx.add(dsts[0].addr, dsts[0].amount, original_output_index, m_merge_destinations);
available_amount -= dsts[0].amount; available_amount -= dsts[0].amount;
dsts[0].amount = 0; dsts[0].amount = 0;
pop_index(dsts, 0); pop_index(dsts, 0);
++original_output_index;
} }
if (available_amount > 0 && !dsts.empty()) { if (available_amount > 0 && !dsts.empty()) {
// 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));
tx.add(dsts[0].addr, available_amount, m_merge_destinations); tx.add(dsts[0].addr, available_amount, original_output_index, m_merge_destinations);
dsts[0].amount -= available_amount; dsts[0].amount -= available_amount;
available_amount = 0; available_amount = 0;
} }