diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/main.cpp b/src/main.cpp index 3c3f06604..e3b98b2e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -492,8 +492,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi { MapPrevTx mapInputs; map<uint256, CTxIndex> mapUnused; - if (!FetchInputs(txdb, mapUnused, false, false, mapInputs)) + bool fInvalid = false; + if (!FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) { + if (fInvalid) + return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str()); if (pfMissingInputs) *pfMissingInputs = true; return error("AcceptToMemoryPool() : FetchInputs failed %s", hash.ToString().substr(0,10).c_str()); @@ -546,8 +549,6 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false)) { - if (pfMissingInputs) - *pfMissingInputs = true; return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str()); } } @@ -923,8 +924,14 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb) bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTestPool, - bool fBlock, bool fMiner, MapPrevTx& inputsRet) + bool fBlock, bool fMiner, MapPrevTx& inputsRet, 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; + if (IsCoinBase()) return true; // Coinbase transactions have no inputs to fetch. @@ -980,7 +987,12 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes const CTxIndex& txindex = inputsRet[prevout.hash].first; const CTransaction& txPrev = inputsRet[prevout.hash].second; 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 DoS(100, error("FetchInputs() : %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())); + } } return true; @@ -1203,7 +1215,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) MapPrevTx mapInputs; if (!tx.IsCoinBase()) { - if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs)) + bool fInvalid; + if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid)) return false; int nTxOps = tx.GetSigOpCount(mapInputs); @@ -3063,7 +3076,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) // because we're already processing them in order of dependency map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool); MapPrevTx mapInputs; - if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs)) + bool fInvalid; + if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid)) continue; int64 nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); @@ -3130,12 +3144,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& hashPrevBlock = pblock->hashPrevBlock; } ++nExtraNonce; - pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce); - - // Put "/P2SH/" in the coinbase so everybody can tell when - // a majority of miners support it - const char* pszP2SH = "/P2SH/"; - pblock->vtx[0].vin[0].scriptSig += CScript() << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); + pblock->vtx[0].vin[0].scriptSig = (CScript() << pblock->nTime << CBigNum(nExtraNonce)) + COINBASE_FLAGS; assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); pblock->hashMerkleRoot = pblock->BuildMerkleTree(); |