aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 4532b776c..f61b28286 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -442,6 +442,10 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
reason = "scriptsig-not-pushonly";
return false;
}
+ if (!txin.scriptSig.HasCanonicalPushes()) {
+ reason = "non-canonical-push";
+ return false;
+ }
}
unsigned int nDataOut = 0;
@@ -868,7 +872,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
-int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
+int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
{
if (hashBlock == 0 || nIndex == -1)
return 0;
@@ -893,6 +897,14 @@ int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
return chainActive.Height() - pindex->nHeight + 1;
}
+int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
+{
+ int nResult = GetDepthInMainChainINTERNAL(pindexRet);
+ if (nResult == 0 && !mempool.exists(GetHash()))
+ return -1; // Not in chain, not in mempool
+
+ return nResult;
+}
int CMerkleTx::GetBlocksToMaturity() const
{
@@ -1054,6 +1066,31 @@ uint256 static GetOrphanRoot(const uint256& hash)
} while(true);
}
+// Remove a random orphan block (which does not have any dependent orphans).
+void static PruneOrphanBlocks()
+{
+ if (mapOrphanBlocksByPrev.size() <= MAX_ORPHAN_BLOCKS)
+ return;
+
+ // Pick a random orphan block.
+ int pos = insecure_rand() % mapOrphanBlocksByPrev.size();
+ std::multimap<uint256, COrphanBlock*>::iterator it = mapOrphanBlocksByPrev.begin();
+ while (pos--) it++;
+
+ // As long as this block has other orphans depending on it, move to one of those successors.
+ do {
+ std::multimap<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocksByPrev.find(it->second->hashBlock);
+ if (it2 == mapOrphanBlocksByPrev.end())
+ break;
+ it = it2;
+ } while(1);
+
+ uint256 hash = it->second->hashBlock;
+ delete it->second;
+ mapOrphanBlocksByPrev.erase(it);
+ mapOrphanBlocks.erase(hash);
+}
+
int64_t GetBlockValue(int nHeight, int64_t nFees)
{
int64_t nSubsidy = 50 * COIN;
@@ -2373,10 +2410,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
// If we don't already have its previous block, shunt it off to holding area until we get it
if (pblock->hashPrevBlock != 0 && !mapBlockIndex.count(pblock->hashPrevBlock))
{
- LogPrintf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString());
+ LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString());
// Accept orphans as long as there is a node to request its parents from
if (pfrom) {
+ PruneOrphanBlocks();
COrphanBlock* pblock2 = new COrphanBlock();
{
CDataStream ss(SER_DISK, CLIENT_VERSION);