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

@@ -494,7 +494,9 @@ void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vect
BOOST_FOREACH(const COutPoint& outpoint, vOutpoints)
{
if (!wallet->mapWallet.count(outpoint.hash)) continue;
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain());
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
if (nDepth < 0) continue;
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth);
vOutputs.push_back(out);
}
}
@@ -513,7 +515,9 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins)
{
if (!wallet->mapWallet.count(outpoint.hash)) continue;
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain());
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
if (nDepth < 0) continue;
COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth);
vCoins.push_back(out);
}