aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2012-01-18 13:36:44 -0500
committerLuke Dashjr <luke-jr+git@utopios.org>2012-02-02 20:03:33 -0500
commitc11e2b8679e13f739a58faf2a3439d4aaed24364 (patch)
treef2c18d43be3388dd321cdd5ac9a2e4a0f3c2c811 /src/main.cpp
parentd841fc969a3a300ebeaa4279320235f2ff2b0533 (diff)
downloadbitcoin-c11e2b8679e13f739a58faf2a3439d4aaed24364.tar.xz
Only store transactions with missing inputs in the orphan pool.
All previous versions of bitcoin could store some types of invalid transactions in the orphan-transaction list.
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 1c94090190..dc8503d38f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -411,10 +411,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
// Check against previous transactions
map<uint256, CTxIndex> mapUnused;
int64 nFees = 0;
- if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false))
+ bool fInvalid = false;
+ if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
{
- if (pfMissingInputs)
- *pfMissingInputs = true;
+ if (fInvalid)
+ return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
}
@@ -833,8 +834,15 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb)
bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
- CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee)
+ CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
+ bool& fInvalid)
{
+ // FetchInputs can return false either because we just haven't seen some inputs
+ // (in which case the transaction should be stored as an orphan)
+ // or because the transaction is malformed (in which case the transaction should
+ // be dropped). If tx is definitely invalid, fInvalid will be set to true.
+ fInvalid = false;
+
// Take over previous transactions' spent pointers
if (!IsCoinBase())
{
@@ -881,7 +889,12 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo
}
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
+ {
+ // Revisit this if/when transaction replacement is implemented and allows
+ // adding inputs:
+ fInvalid = true;
return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str());
+ }
// If prev is coinbase, check that it's matured
if (txPrev.IsCoinBase())
@@ -1025,7 +1038,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
nTxPos += ::GetSerializeSize(tx, SER_DISK);
- if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false))
+ bool fInvalid;
+ if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false, 0, fInvalid))
return false;
}
// Write queued txindex changes
@@ -2806,7 +2820,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Connecting shouldn't fail due to dependency on other memory pool transactions
// because we're already processing them in order of dependency
map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
- if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee))
+ bool fInvalid;
+ if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid))
continue;
swap(mapTestPool, mapTestPoolTmp);