diff options
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r-- | src/wallet/wallet2.cpp | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 8a4cec017..72fd2d866 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1389,7 +1389,7 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei } } //---------------------------------------------------------------------------------------------------- -void wallet2::update_pool_state() +void wallet2::update_pool_state(bool refreshed) { MDEBUG("update_pool_state start"); @@ -1425,13 +1425,14 @@ void wallet2::update_pool_state() // a tx is removed from the pool due to being found in a new block, but // just before the block is visible by refresh. So we keep a boolean, so // that the first time we don't see the tx, we set that boolean, and only - // delete it the second time it is checked + // delete it the second time it is checked (but only when refreshed, so + // we're sure we've seen the blockchain state first) if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending) { LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as not in pool"); pit->second.m_state = wallet2::unconfirmed_transfer_details::pending_not_in_pool; } - else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool) + else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool && refreshed) { LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as failed"); pit->second.m_state = wallet2::unconfirmed_transfer_details::failed; @@ -1460,24 +1461,30 @@ void wallet2::update_pool_state() MDEBUG("update_pool_state done first loop"); // remove pool txes to us that aren't in the pool anymore - std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin(); - while (uit != m_unconfirmed_payments.end()) + // but only if we just refreshed, so that the tx can go in + // the in transfers list instead (or nowhere if it just + // disappeared without being mined) + if (refreshed) { - const crypto::hash &txid = uit->second.m_tx_hash; - bool found = false; - for (const auto &it2: res.tx_hashes) + std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin(); + while (uit != m_unconfirmed_payments.end()) { - if (it2 == txid) + const crypto::hash &txid = uit->second.m_tx_hash; + bool found = false; + for (const auto &it2: res.tx_hashes) { - found = true; - break; + if (it2 == txid) + { + found = true; + break; + } + } + auto pit = uit++; + if (!found) + { + MDEBUG("Removing " << txid << " from unconfirmed payments, not found in pool"); + m_unconfirmed_payments.erase(pit); } - } - auto pit = uit++; - if (!found) - { - MDEBUG("Removing " << txid << " from unconfirmed payments, not found in pool"); - m_unconfirmed_payments.erase(pit); } } MDEBUG("update_pool_state done second loop"); @@ -1491,7 +1498,16 @@ void wallet2::update_pool_state() LOG_PRINT_L2("Already seen " << txid << ", skipped"); continue; } - if (m_unconfirmed_payments.find(txid) == m_unconfirmed_payments.end()) + bool txid_found_in_up = false; + for (const auto &up: m_unconfirmed_payments) + { + if (up.second.m_tx_hash == txid) + { + txid_found_in_up = true; + break; + } + } + if (!txid_found_in_up) { LOG_PRINT_L1("Found new pool tx: " << txid); bool found = false; @@ -1686,6 +1702,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re uint64_t blocks_start_height; std::list<cryptonote::block_complete_entry> blocks; std::vector<COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> o_indices; + bool refreshed = false; // pull the first set of blocks get_short_chain_history(short_chain_history); @@ -1727,6 +1744,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re if(blocks_start_height == next_blocks_start_height) { m_node_rpc_proxy.set_height(m_blockchain.size()); + refreshed = true; break; } @@ -1765,7 +1783,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re { // If stop() is called we don't need to check pending transactions if(m_run.load(std::memory_order_relaxed)) - update_pool_state(); + update_pool_state(refreshed); } catch (...) { @@ -3253,7 +3271,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f for (size_t n = 0; n < exported_txs.txes.size(); ++n) { const tools::wallet2::tx_construction_data &sd = exported_txs.txes[n]; - LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, mixin " << (sd.sources[0].outputs.size()-1)); + LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size()); signed_txes.ptx.push_back(pending_tx()); tools::wallet2::pending_tx &ptx = signed_txes.ptx.back(); crypto::secret_key tx_key; @@ -4120,7 +4138,7 @@ static size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs) // txnFee size += 4; - LOG_PRINT_L2("estimated rct tx size for " << n_inputs << " at mixin " << mixin << " and " << n_outputs << ": " << size << " (" << ((32 * n_inputs/*+1*/) + 2 * 32 * (mixin+1) * n_inputs + 32 * n_outputs) << " saved)"); + LOG_PRINT_L2("estimated rct tx size for " << n_inputs << " with ring size " << (mixin+1) << " and " << n_outputs << ": " << size << " (" << ((32 * n_inputs/*+1*/) + 2 * 32 * (mixin+1) * n_inputs + 32 * n_outputs) << " saved)"); return size; } @@ -4360,7 +4378,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // try to pick outputs not from the same block. We will get two outputs, one for // the destination, and one for change. LOG_PRINT_L2("checking preferred"); - std::vector<size_t> prefered_inputs; + std::vector<size_t> preferred_inputs; uint64_t rct_outs_needed = 2 * (fake_outs_count + 1); rct_outs_needed += 100; // some fudge factor since we don't know how many are locked if (use_rct && get_num_rct_outputs() >= rct_outs_needed) @@ -4368,12 +4386,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // this is used to build a tx that's 1 or 2 inputs, and 2 outputs, which // will get us a known fee. uint64_t estimated_fee = calculate_fee(fee_per_kb, estimate_rct_tx_size(2, fake_outs_count + 1, 2), fee_multiplier); - prefered_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee); - if (!prefered_inputs.empty()) + preferred_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee); + if (!preferred_inputs.empty()) { string s; - for (auto i: prefered_inputs) s += boost::lexical_cast<std::string>(i) + "(" + print_money(m_transfers[i].amount()) + ") "; - LOG_PRINT_L1("Found prefered rct inputs for rct tx: " << s); + for (auto i: preferred_inputs) s += boost::lexical_cast<std::string>(i) + "(" + print_money(m_transfers[i].amount()) + ") "; + LOG_PRINT_L1("Found preferred rct inputs for rct tx: " << s); } } LOG_PRINT_L2("done checking preferred"); @@ -4428,8 +4446,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp } pop_if_present(unused_transfers_indices, idx); pop_if_present(unused_dust_indices, idx); - } else if (!prefered_inputs.empty()) { - idx = pop_back(prefered_inputs); + } else if (!preferred_inputs.empty()) { + idx = pop_back(preferred_inputs); pop_if_present(unused_transfers_indices, idx); pop_if_present(unused_dust_indices, idx); } else @@ -4522,7 +4540,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp { uint64_t new_paid_amount = i->amount /*+ test_ptx.fee*/ - needed_fee; LOG_PRINT_L2("Adjusting amount paid to " << get_account_address_as_str(m_testnet, i->addr) << " from " << - print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accomodate " << + print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accommodate " << print_money(needed_fee) << " fee"); dsts[0].amount += i->amount - new_paid_amount; i->amount = new_paid_amount; |