X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=ad75892fb923e6d76021819cb72eab4a5f028f21;hb=d11488abd05cb39a9f481e7c4c35f780197a3d28;hp=2473662620a8cc5635d167f5063e84fa1f2ba25d;hpb=66116c3847eeb3f0619bc084d96f5add41a156c8;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index 2473662..ad75892 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "headers.h" #include "checkpoints.h" #include "db.h" @@ -304,6 +305,8 @@ bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const if (!Solver(prevScript, whichType, vSolutions)) return false; int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); + if (nArgsExpected < 0) + return false; // Transactions with extra stuff in their scriptSigs are // non-standard. Note that this EvalScript() call will @@ -325,10 +328,15 @@ bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const return false; if (whichType2 == TX_SCRIPTHASH) return false; - nArgsExpected += ScriptSigArgsExpected(whichType2, vSolutions2); + + int tmpExpected; + tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); + if (tmpExpected < 0) + return false; + nArgsExpected += tmpExpected; } - if (stack.size() != nArgsExpected) + if (stack.size() != (unsigned int)nArgsExpected) return false; } @@ -1489,7 +1497,9 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) { uint256 hash = GetHash(); - txdb.TxnBegin(); + if (!txdb.TxnBegin()) + return error("SetBestChain() : TxnBegin failed"); + if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) { txdb.WriteHashBestChain(hash); @@ -1538,7 +1548,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) printf("SetBestChain() : ReadFromDisk failed\n"); break; } - txdb.TxnBegin(); + if (!txdb.TxnBegin()) { + printf("SetBestChain() : TxnBegin 2 failed\n"); + break; + } // errors now are not fatal, we still did a reorganisation to a new chain in a valid way if (!block.SetBestChainInner(txdb, pindex)) break; @@ -1596,7 +1609,8 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork(); CTxDB txdb; - txdb.TxnBegin(); + if (!txdb.TxnBegin()) + return false; txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); if (!txdb.TxnCommit()) return false; @@ -1652,6 +1666,16 @@ bool CBlock::CheckBlock() const if (!tx.CheckTransaction()) return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed")); + // Check for duplicate txids. This is caught by ConnectInputs(), + // but catching it earlier avoids a potential DoS attack: + set uniqueTx; + BOOST_FOREACH(const CTransaction& tx, vtx) + { + uniqueTx.insert(tx.GetHash()); + } + if (uniqueTx.size() != vtx.size()) + return DoS(100, error("CheckBlock() : duplicate transaction")); + int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, vtx) { @@ -2374,6 +2398,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return error("message inv size() = %d", vInv.size()); } + // find last block in inv vector + unsigned int nLastBlock = (unsigned int)(-1); + for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { + if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) + nLastBlock = vInv.size() - 1 - nInv; + } CTxDB txdb("r"); for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { @@ -2390,9 +2420,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Always request the last block in an inv bundle (even if we already have it), as it is the // trigger for the other side to send further invs. If we are stuck on a (very long) side chain, // this is necessary to connect earlier received orphan blocks to the chain again. - if (!fAlreadyHave || (inv.type == MSG_BLOCK && nInv==vInv.size()-1)) + if (fAlreadyHave && nInv == nLastBlock) { + // bypass mapAskFor, and send request directly; it must go through. + std::vector vGetData(1,inv); + pfrom->PushMessage("getdata", vGetData); + } + + if (!fAlreadyHave) pfrom->AskFor(inv); - if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); // Track requests for our stuff @@ -3145,7 +3181,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) dPriority += (double)nValueIn * nConf; if (fDebug && GetBoolArg("-printpriority")) - printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority); + printf("priority nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority); } // Priority is sum(valuein * age) / txsize