aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
authortobtoht <tob@featherwallet.org>2025-10-27 18:51:14 +0000
committertobtoht <tob@featherwallet.org>2025-10-27 18:51:14 +0000
commit3cc9d65c9374b541e64320052c933184944375ea (patch)
treef7173ff0cdba53b4f6900df21d5033b78b07aec0 /src/wallet/wallet2.cpp
parent7c6e84466a90f6701ebe09ff8f61ea8af3883181 (diff)
parent9239d36691bfe94dda12cc925903fed5e761fbe3 (diff)
downloadmonzero-core-3cc9d65c9374b541e64320052c933184944375ea.tar.gz
monzero-core-3cc9d65c9374b541e64320052c933184944375ea.tar.xz
monzero-core-3cc9d65c9374b541e64320052c933184944375ea.zip
Merge pull request #10153
9239d36 wallet: identify spends in pool when scanning (j-berman)
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp60
1 files changed, 43 insertions, 17 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index aedcaba06..416f83be7 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -922,6 +922,11 @@ bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pend
return false;
}
+uint64_t get_outgoing_amount(const cryptonote::transaction &tx, const uint64_t amount_spent)
+{
+ return tx.version == 1 ? get_outs_money_amount(tx) : (amount_spent - tx.rct_signatures.txnFee);
+}
+
tools::wallet2::tx_construction_data get_construction_data_with_decrypted_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
{
tools::wallet2::tx_construction_data construction_data = ptx.construction_data;
@@ -2712,10 +2717,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
LOG_ERROR("spent funds are from different subaddress accounts; count of incoming/outgoing payments will be incorrect");
subaddr_account = td.m_subaddr_index.major;
subaddr_indices.insert(td.m_subaddr_index.minor);
+ LOG_PRINT_L0("Spent money: " << print_money(amount) << ", with tx: " << txid);
+ set_spent(it->second, height);
if (!pool)
{
- LOG_PRINT_L0("Spent money: " << print_money(amount) << ", with tx: " << txid);
- set_spent(it->second, height);
if (!ignore_callbacks && 0 != m_callback)
m_callback->on_money_spent(height, txid, tx, amount, tx, td.m_subaddr_index);
@@ -2804,21 +2809,33 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
uint64_t fee = miner_tx ? 0 : tx.version == 1 ? tx_money_spent_in_ins - get_outs_money_amount(tx) : tx.rct_signatures.txnFee;
- if (tx_money_spent_in_ins > 0 && !pool)
+ if (tx_money_spent_in_ins > 0)
{
uint64_t self_received = std::accumulate<decltype(tx_money_got_in_outs.begin()), uint64_t>(tx_money_got_in_outs.begin(), tx_money_got_in_outs.end(), 0,
[&subaddr_account] (uint64_t acc, const std::pair<cryptonote::subaddress_index, uint64_t>& p)
{
return acc + (p.first.major == *subaddr_account ? p.second : 0);
});
- process_outgoing(txid, tx, height, ts, tx_money_spent_in_ins, self_received, *subaddr_account, subaddr_indices);
- // if sending to yourself at the same subaddress account, set the outgoing payment amount to 0 so that it's less confusing
- if (tx_money_spent_in_ins == self_received + fee)
+ if (!pool)
+ {
+ process_outgoing(txid, tx, height, ts, tx_money_spent_in_ins, self_received, *subaddr_account, subaddr_indices);
+ // if sending to yourself at the same subaddress account, set the outgoing payment amount to 0 so that it's less confusing
+ if (tx_money_spent_in_ins == self_received + fee)
+ {
+ auto i = m_confirmed_txs.find(txid);
+ THROW_WALLET_EXCEPTION_IF(i == m_confirmed_txs.end(), error::wallet_internal_error,
+ "confirmed tx wasn't found: " + string_tools::pod_to_hex(txid));
+ i->second.m_change = self_received;
+ }
+ }
+ else if (!m_unconfirmed_txs.count(txid))
{
- auto i = m_confirmed_txs.find(txid);
- THROW_WALLET_EXCEPTION_IF(i == m_confirmed_txs.end(), error::wallet_internal_error,
- "confirmed tx wasn't found: " + string_tools::pod_to_hex(txid));
- i->second.m_change = self_received;
+ // Add to unconfirmed txs if not already there (e.g. restoring wallet, or running the wallet in parallel to the sending wallet w/same seed)
+ add_unconfirmed_tx(txid, tx, tx_money_spent_in_ins, {}/*don't know dests*/, crypto::null_hash/*don't know payment_id*/, self_received, *subaddr_account, subaddr_indices);
+ auto i = m_unconfirmed_txs.find(txid);
+ THROW_WALLET_EXCEPTION_IF(i == m_unconfirmed_txs.end(), error::wallet_internal_error,
+ "unconfirmed tx wasn't found: " + string_tools::pod_to_hex(txid));
+ i->second.m_amount_out = get_outgoing_amount(tx, tx_money_spent_in_ins);
}
}
@@ -2967,10 +2984,7 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans
// wallet (eg, we're a cold wallet and the hot wallet sent it). For RCT transactions,
// we only see 0 input amounts, so have to deduce amount out from other parameters.
entry.first->second.m_amount_in = spent;
- if (tx.version == 1)
- entry.first->second.m_amount_out = get_outs_money_amount(tx);
- else
- entry.first->second.m_amount_out = spent - tx.rct_signatures.txnFee;
+ entry.first->second.m_amount_out = get_outgoing_amount(tx, spent);
entry.first->second.m_change = received;
std::vector<tx_extra_field> tx_extra_fields;
@@ -4081,6 +4095,18 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
// Lighwallet refresh done
return;
}
+
+ if (!m_first_refresh_done)
+ {
+ // We want to process the whole pool again, in case we identify received outputs in the chain we might have spent in the pool
+ m_pool_info_query_time = 0;
+ m_scanned_pool_txs[0].clear();
+ m_scanned_pool_txs[1].clear();
+ // Clear unconfirmed (received) payments because the data is 100% recovered when scanning
+ m_unconfirmed_payments.clear();
+ // Don't clear unconfirmed (sent) txs because some data is not recover-able when scanning (dests)
+ }
+
received_money = false;
blocks_fetched = 0;
uint64_t added_blocks = 0;
@@ -7475,9 +7501,9 @@ uint64_t wallet2::select_transfers(uint64_t needed_money, std::vector<size_t> un
return found_money;
}
//----------------------------------------------------------------------------------------------------
-void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amount_in, const std::vector<cryptonote::tx_destination_entry> &dests, const crypto::hash &payment_id, uint64_t change_amount, uint32_t subaddr_account, const std::set<uint32_t>& subaddr_indices)
+void wallet2::add_unconfirmed_tx(const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount_in, const std::vector<cryptonote::tx_destination_entry> &dests, const crypto::hash &payment_id, uint64_t change_amount, uint32_t subaddr_account, const std::set<uint32_t>& subaddr_indices)
{
- unconfirmed_transfer_details& utd = m_unconfirmed_txs[cryptonote::get_transaction_hash(tx)];
+ unconfirmed_transfer_details& utd = m_unconfirmed_txs[txid];
utd.m_amount_in = amount_in;
utd.m_amount_out = 0;
for (const auto &d: dests)
@@ -7590,7 +7616,7 @@ void wallet2::commit_tx(pending_tx& ptx)
for(size_t idx: ptx.selected_transfers)
amount_in += m_transfers[idx].amount();
}
- add_unconfirmed_tx(ptx.tx, amount_in, dests, payment_id, ptx.change_dts.amount, ptx.construction_data.subaddr_account, ptx.construction_data.subaddr_indices);
+ add_unconfirmed_tx(txid, ptx.tx, amount_in, dests, payment_id, ptx.change_dts.amount, ptx.construction_data.subaddr_account, ptx.construction_data.subaddr_indices);
if (store_tx_info() && ptx.tx_key != crypto::null_skey)
{
m_tx_keys[txid] = ptx.tx_key;