aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wallet/wallet2.cpp46
-rw-r--r--src/wallet/wallet2.h26
2 files changed, 61 insertions, 11 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 767315450..55106fa98 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -490,6 +490,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
LOG_PRINT_L0("Spent money: " << print_money(amount) << ", with tx: " << get_transaction_hash(tx));
tx_money_spent_in_ins += amount;
td.m_spent = true;
+ td.m_spent_height = height;
if (0 != m_callback)
m_callback->on_money_spent(height, td.m_tx, amount, tx);
}
@@ -1167,6 +1168,17 @@ void wallet2::detach_blockchain(uint64_t height)
LOG_PRINT_L0("Detaching blockchain on height " << height);
size_t transfers_detached = 0;
+ for (size_t i = 0; i < m_transfers.size(); ++i)
+ {
+ wallet2::transfer_details &td = m_transfers[i];
+ if (td.m_spent && td.m_spent_height >= height)
+ {
+ LOG_PRINT_L1("Resetting spent status for output " << i << ": " << td.m_key_image);
+ td.m_spent = false;
+ td.m_spent_height = 0;
+ }
+ }
+
auto it = std::find_if(m_transfers.begin(), m_transfers.end(), [&](const transfer_details& td){return td.m_block_height >= height;});
size_t i_start = it - m_transfers.begin();
@@ -1980,10 +1992,12 @@ void wallet2::rescan_spent()
if (td.m_spent)
{
LOG_PRINT_L0("Marking output " << i << "(" << td.m_key_image << ") as unspent, it was marked as spent");
+ td.m_spent_height = 0;
}
else
{
LOG_PRINT_L0("Marking output " << i << "(" << td.m_key_image << ") as spent, it was marked as unspent");
+ // unknown height, if this gets reorged, it might still be missed
}
td.m_spent = daemon_resp.spent_status[i] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT;
}
@@ -2293,7 +2307,10 @@ void wallet2::commit_tx(pending_tx& ptx)
LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]");
BOOST_FOREACH(transfer_container::iterator it, ptx.selected_transfers)
+ {
it->m_spent = true;
+ it->m_spent_height = 0;
+ }
//fee includes dust if dust policy specified it.
LOG_PRINT_L0("Transaction successfully sent. <" << txid << ">" << ENDL
@@ -2371,7 +2388,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
// mark transfers to be used as "spent"
BOOST_FOREACH(transfer_container::iterator it, ptx.selected_transfers)
+ {
it->m_spent = true;
+ it->m_spent_height = 0;
+ }
}
// if we made it this far, we've selected our transactions. committing them will mark them spent,
@@ -2381,7 +2401,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
{
// mark transfers to be used as not spent
BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+ {
it2->m_spent = false;
+ it2->m_spent_height = 0;
+ }
}
@@ -2398,8 +2421,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
{
// mark transfers to be used as not spent
BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+ {
it2->m_spent = false;
-
+ it2->m_spent_height = 0;
+ }
}
if (attempt_count >= MAX_SPLIT_ATTEMPTS)
@@ -2416,8 +2441,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
{
// mark transfers to be used as not spent
BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+ {
it2->m_spent = false;
-
+ it2->m_spent_height = 0;
+ }
}
throw;
@@ -3860,7 +3887,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
// mark transfers to be used as "spent"
BOOST_FOREACH(transfer_container::iterator it, ptx.selected_transfers)
+ {
it->m_spent = true;
+ it->m_spent_height = 0;
+ }
}
// if we made it this far, we've selected our transactions. committing them will mark them spent,
@@ -3870,8 +3900,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
{
// mark transfers to be used as not spent
BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+ {
it2->m_spent = false;
-
+ it2->m_spent_height = 0;
+ }
}
// if we made it this far, we're OK to actually send the transactions
@@ -3887,8 +3919,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
{
// mark transfers to be used as not spent
BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+ {
it2->m_spent = false;
-
+ it2->m_spent_height = 0;
+ }
}
if (attempt_count >= MAX_SPLIT_ATTEMPTS)
@@ -3905,8 +3939,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
{
// mark transfers to be used as not spent
BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+ {
it2->m_spent = false;
-
+ it2->m_spent_height = 0;
+ }
}
throw;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 125f8edb5..1c835429f 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -103,6 +103,7 @@ namespace tools
size_t m_internal_output_index;
uint64_t m_global_output_index;
bool m_spent;
+ uint64_t m_spent_height;
crypto::key_image m_key_image; //TODO: key_image stored twice :(
rct::key m_mask;
uint64_t m_amount;
@@ -490,7 +491,7 @@ namespace tools
};
}
BOOST_CLASS_VERSION(tools::wallet2, 13)
-BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 1)
+BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 2)
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 4)
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2)
@@ -500,14 +501,21 @@ namespace boost
namespace serialization
{
template <class Archive>
- inline void initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x)
+ inline void initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
}
template<>
- inline void initialize_transfer_details(boost::archive::binary_iarchive &a, tools::wallet2::transfer_details &x)
+ inline void initialize_transfer_details(boost::archive::binary_iarchive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
- x.m_mask = rct::identity();
- x.m_amount = x.m_tx.vout[x.m_internal_output_index].amount;
+ if (ver < 1)
+ {
+ x.m_mask = rct::identity();
+ x.m_amount = x.m_tx.vout[x.m_internal_output_index].amount;
+ }
+ if (ver < 2)
+ {
+ x.m_spent_height = 0;
+ }
}
template <class Archive>
@@ -522,11 +530,17 @@ namespace boost
if (ver < 1)
{
// ensure mask and amount are set
- initialize_transfer_details(a, x);
+ initialize_transfer_details(a, x, ver);
return;
}
a & x.m_mask;
a & x.m_amount;
+ if (ver < 2)
+ {
+ initialize_transfer_details(a, x, ver);
+ return;
+ }
+ a & x.m_spent_height;
}
template <class Archive>