Handle "conflicted" transactions properly

Extend CMerkleTx::GetDepthInMainChain with the concept of
a "conflicted" transaction-- a transaction generated by the wallet
that is not in the main chain or in the mempool, and, therefore,
will likely never be confirmed.

GetDepthInMainChain() now returns -1 for conflicted transactions
(0 for unconfirmed-but-in-the-mempool, and >1 for confirmed).

This makes getbalance, getbalance '*', and listunspent all agree when there are
mutated transactions in the wallet.

Before:
 listunspent: one 49BTC output
 getbalance: 96 BTC (change counted twice)
 getbalance '*': 46 BTC (spends counted twice)

After: all agree, 49 BTC available to spend.
This commit is contained in:
Gavin Andresen
2014-02-12 13:43:07 -05:00
parent f582eda4ed
commit 2b72d46f42
8 changed files with 194 additions and 11 deletions

View File

@@ -1021,11 +1021,15 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
continue;
int nDepth = pcoin->GetDepthInMainChain();
if (nDepth < 0)
continue;
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) &&
!IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 &&
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain()));
vCoins.push_back(COutput(pcoin, i, nDepth));
}
}
}