|
|
@ -590,8 +590,9 @@ void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid) |
|
|
|
|
|
|
|
|
|
|
|
void CWallet::AddToSpends(const uint256& wtxid) |
|
|
|
void CWallet::AddToSpends(const uint256& wtxid) |
|
|
|
{ |
|
|
|
{ |
|
|
|
assert(mapWallet.count(wtxid)); |
|
|
|
auto it = mapWallet.find(wtxid); |
|
|
|
CWalletTx& thisTx = mapWallet[wtxid]; |
|
|
|
assert(it != mapWallet.end()); |
|
|
|
|
|
|
|
CWalletTx& thisTx = it->second; |
|
|
|
if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
|
|
|
|
if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
|
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
@ -974,8 +975,9 @@ bool CWallet::LoadToWallet(const CWalletTx& wtxIn) |
|
|
|
wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); |
|
|
|
wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); |
|
|
|
AddToSpends(hash); |
|
|
|
AddToSpends(hash); |
|
|
|
for (const CTxIn& txin : wtx.tx->vin) { |
|
|
|
for (const CTxIn& txin : wtx.tx->vin) { |
|
|
|
if (mapWallet.count(txin.prevout.hash)) { |
|
|
|
auto it = mapWallet.find(txin.prevout.hash); |
|
|
|
CWalletTx& prevtx = mapWallet[txin.prevout.hash]; |
|
|
|
if (it != mapWallet.end()) { |
|
|
|
|
|
|
|
CWalletTx& prevtx = it->second; |
|
|
|
if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { |
|
|
|
if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { |
|
|
|
MarkConflicted(prevtx.hashBlock, wtx.GetHash()); |
|
|
|
MarkConflicted(prevtx.hashBlock, wtx.GetHash()); |
|
|
|
} |
|
|
|
} |
|
|
@ -1050,8 +1052,9 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) |
|
|
|
std::set<uint256> done; |
|
|
|
std::set<uint256> done; |
|
|
|
|
|
|
|
|
|
|
|
// Can't mark abandoned if confirmed or in mempool
|
|
|
|
// Can't mark abandoned if confirmed or in mempool
|
|
|
|
assert(mapWallet.count(hashTx)); |
|
|
|
auto it = mapWallet.find(hashTx); |
|
|
|
CWalletTx& origtx = mapWallet[hashTx]; |
|
|
|
assert(it != mapWallet.end()); |
|
|
|
|
|
|
|
CWalletTx& origtx = it->second; |
|
|
|
if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { |
|
|
|
if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -1062,8 +1065,9 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) |
|
|
|
uint256 now = *todo.begin(); |
|
|
|
uint256 now = *todo.begin(); |
|
|
|
todo.erase(now); |
|
|
|
todo.erase(now); |
|
|
|
done.insert(now); |
|
|
|
done.insert(now); |
|
|
|
assert(mapWallet.count(now)); |
|
|
|
auto it = mapWallet.find(now); |
|
|
|
CWalletTx& wtx = mapWallet[now]; |
|
|
|
assert(it != mapWallet.end()); |
|
|
|
|
|
|
|
CWalletTx& wtx = it->second; |
|
|
|
int currentconfirm = wtx.GetDepthInMainChain(); |
|
|
|
int currentconfirm = wtx.GetDepthInMainChain(); |
|
|
|
// If the orig tx was not in block, none of its spends can be
|
|
|
|
// If the orig tx was not in block, none of its spends can be
|
|
|
|
assert(currentconfirm <= 0); |
|
|
|
assert(currentconfirm <= 0); |
|
|
@ -1088,8 +1092,10 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) |
|
|
|
// available of the outputs it spends. So force those to be recomputed
|
|
|
|
// available of the outputs it spends. So force those to be recomputed
|
|
|
|
for (const CTxIn& txin : wtx.tx->vin) |
|
|
|
for (const CTxIn& txin : wtx.tx->vin) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (mapWallet.count(txin.prevout.hash)) |
|
|
|
auto it = mapWallet.find(txin.prevout.hash); |
|
|
|
mapWallet[txin.prevout.hash].MarkDirty(); |
|
|
|
if (it != mapWallet.end()) { |
|
|
|
|
|
|
|
it->second.MarkDirty(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1127,8 +1133,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) |
|
|
|
uint256 now = *todo.begin(); |
|
|
|
uint256 now = *todo.begin(); |
|
|
|
todo.erase(now); |
|
|
|
todo.erase(now); |
|
|
|
done.insert(now); |
|
|
|
done.insert(now); |
|
|
|
assert(mapWallet.count(now)); |
|
|
|
auto it = mapWallet.find(now); |
|
|
|
CWalletTx& wtx = mapWallet[now]; |
|
|
|
assert(it != mapWallet.end()); |
|
|
|
|
|
|
|
CWalletTx& wtx = it->second; |
|
|
|
int currentconfirm = wtx.GetDepthInMainChain(); |
|
|
|
int currentconfirm = wtx.GetDepthInMainChain(); |
|
|
|
if (conflictconfirms < currentconfirm) { |
|
|
|
if (conflictconfirms < currentconfirm) { |
|
|
|
// Block is 'more conflicted' than current confirm; update.
|
|
|
|
// Block is 'more conflicted' than current confirm; update.
|
|
|
@ -1147,10 +1154,11 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) |
|
|
|
} |
|
|
|
} |
|
|
|
// If a transaction changes 'conflicted' state, that changes the balance
|
|
|
|
// If a transaction changes 'conflicted' state, that changes the balance
|
|
|
|
// available of the outputs it spends. So force those to be recomputed
|
|
|
|
// available of the outputs it spends. So force those to be recomputed
|
|
|
|
for (const CTxIn& txin : wtx.tx->vin) |
|
|
|
for (const CTxIn& txin : wtx.tx->vin) { |
|
|
|
{ |
|
|
|
auto it = mapWallet.find(txin.prevout.hash); |
|
|
|
if (mapWallet.count(txin.prevout.hash)) |
|
|
|
if (it != mapWallet.end()) { |
|
|
|
mapWallet[txin.prevout.hash].MarkDirty(); |
|
|
|
it->second.MarkDirty(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1165,10 +1173,11 @@ void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pin |
|
|
|
// If a transaction changes 'conflicted' state, that changes the balance
|
|
|
|
// If a transaction changes 'conflicted' state, that changes the balance
|
|
|
|
// available of the outputs it spends. So force those to be
|
|
|
|
// available of the outputs it spends. So force those to be
|
|
|
|
// recomputed, also:
|
|
|
|
// recomputed, also:
|
|
|
|
for (const CTxIn& txin : tx.vin) |
|
|
|
for (const CTxIn& txin : tx.vin) { |
|
|
|
{ |
|
|
|
auto it = mapWallet.find(txin.prevout.hash); |
|
|
|
if (mapWallet.count(txin.prevout.hash)) |
|
|
|
if (it != mapWallet.end()) { |
|
|
|
mapWallet[txin.prevout.hash].MarkDirty(); |
|
|
|
it->second.MarkDirty(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|