|
|
|
@ -698,6 +698,8 @@ bool CTxMemPool::accept(CTransaction &tx, bool fCheckInputs,
@@ -698,6 +698,8 @@ bool CTxMemPool::accept(CTransaction &tx, bool fCheckInputs,
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
// do all inputs exist?
|
|
|
|
|
// Note that this does not check for the presence of actual outputs (see the next check for that),
|
|
|
|
|
// only helps filling in pfMissingInputs (to determine missing vs spent).
|
|
|
|
|
BOOST_FOREACH(const CTxIn txin, tx.vin) { |
|
|
|
|
if (!view.HaveCoins(txin.prevout.hash)) { |
|
|
|
|
if (pfMissingInputs) |
|
|
|
@ -706,6 +708,7 @@ bool CTxMemPool::accept(CTransaction &tx, bool fCheckInputs,
@@ -706,6 +708,7 @@ bool CTxMemPool::accept(CTransaction &tx, bool fCheckInputs,
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// are the actual inputs available?
|
|
|
|
|
if (!tx.HaveInputs(view)) |
|
|
|
|
return error("CTxMemPool::accept() : inputs already spent"); |
|
|
|
|
|
|
|
|
@ -1956,9 +1959,13 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const
@@ -1956,9 +1959,13 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const
|
|
|
|
|
if (!tx.CheckTransaction()) |
|
|
|
|
return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed")); |
|
|
|
|
|
|
|
|
|
// Build the merkle tree already. We need it anyway later, and it makes the
|
|
|
|
|
// block cache the transaction hashes, which means they don't need to be
|
|
|
|
|
// recalculated many times during this block's validation.
|
|
|
|
|
BuildMerkleTree(); |
|
|
|
|
|
|
|
|
|
// Check for duplicate txids. This is caught by ConnectInputs(),
|
|
|
|
|
// but catching it earlier avoids a potential DoS attack:
|
|
|
|
|
BuildMerkleTree(); |
|
|
|
|
set<uint256> uniqueTx; |
|
|
|
|
for (unsigned int i=0; i<vtx.size(); i++) { |
|
|
|
|
uniqueTx.insert(GetTxHash(i)); |
|
|
|
|