aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 416f83be7..af1f03d2c 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -3660,6 +3660,35 @@ bool wallet2::accept_pool_tx_for_processing(const crypto::hash &txid)
// Process an unconfirmed transfer after we know whether it's in the pool or not
void wallet2::process_unconfirmed_transfer(bool incremental, const crypto::hash &txid, wallet2::unconfirmed_transfer_details &tx_details, bool seen_in_pool, std::chrono::system_clock::time_point now, bool refreshed)
{
+ const auto set_tx_key_images_spent = [&](const bool spent)
+ {
+ for (size_t vini = 0; vini < tx_details.m_tx.vin.size(); ++vini)
+ {
+ if (tx_details.m_tx.vin[vini].type() != typeid(txin_to_key))
+ continue;
+
+ const crypto::key_image &key_image = boost::get<txin_to_key>(tx_details.m_tx.vin[vini]).k_image;
+ const auto it_ki = m_key_images.find(key_image);
+ if (it_ki == m_key_images.end())
+ continue;
+
+ const std::size_t i = it_ki->second;
+ if (i >= m_transfers.size())
+ continue;
+ const transfer_details &td = m_transfers.at(i);
+ if (td.m_key_image != key_image)
+ continue;
+ if (td.m_spent == spent)
+ continue;
+
+ LOG_PRINT_L1("Resetting spent status for output " << vini << ": " << key_image << " (spent=" << spent << ")");
+ if (spent)
+ set_spent(i, 0);
+ else
+ set_unspent(i);
+ }
+ };
+
// TODO: set tx_propagation_timeout to CRYPTONOTE_DANDELIONPP_EMBARGO_AVERAGE * 3 / 2 after v15 hardfork
constexpr const std::chrono::seconds tx_propagation_timeout{500};
if (seen_in_pool)
@@ -3669,6 +3698,10 @@ void wallet2::process_unconfirmed_transfer(bool incremental, const crypto::hash
tx_details.m_state = wallet2::unconfirmed_transfer_details::pending_in_pool;
MINFO("Pending txid " << txid << " seen in pool, marking as pending in pool");
}
+
+ // The inputs are spent, they're in the pool! It's possible the tx was previously marked as failed, so we
+ // make sure to re-mark the outputs as spent.
+ set_tx_key_images_spent(true/*spent*/);
}
else
{
@@ -3694,23 +3727,7 @@ void wallet2::process_unconfirmed_transfer(bool incremental, const crypto::hash
tx_details.m_state = wallet2::unconfirmed_transfer_details::failed;
// the inputs aren't spent anymore, since the tx failed
- for (size_t vini = 0; vini < tx_details.m_tx.vin.size(); ++vini)
- {
- if (tx_details.m_tx.vin[vini].type() == typeid(txin_to_key))
- {
- txin_to_key &tx_in_to_key = boost::get<txin_to_key>(tx_details.m_tx.vin[vini]);
- for (size_t i = 0; i < m_transfers.size(); ++i)
- {
- const transfer_details &td = m_transfers[i];
- if (td.m_key_image == tx_in_to_key.k_image)
- {
- LOG_PRINT_L1("Resetting spent status for output " << vini << ": " << td.m_key_image);
- set_unspent(i);
- break;
- }
- }
- }
- }
+ set_tx_key_images_spent(false/*spent*/);
}
}
}