message: Update for saving orphan blocks.
diff: #include "validationinterface.h"
  #include "checkpoints.h"
  #include "test/test_random.h"
  +#include "clientversion.h"
  #include <boost/thread.hpp>
  @@ -3379,6 +3380,47 @@ bool ProcessNetBlock(const CChainParams& chainparams, const std::shared_ptr<cons
  return error("ProcessNetBlock(): bad block signature encoding");
  }
  +
  + // If we don't already have its previous block, shunt it off to holding area until we get it
  + if (!mapBlockIndex.count(pblock->hashPrevBlock))
  + {
  + LogPrintf("ProcessNetBlock: 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) {
  + // ppcoin: check proof-of-stake
  + if (pblock->IsProofOfStake())
  + {
  + // Limited duplicity on stake: prevents block flood attack
  + // Duplicate stake allowed only when there is orphan child block
  + if (setStakeSeenOrphan.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash))
  + return error("ProcessNetBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock->GetProofOfStake().first.ToString(), pblock->GetProofOfStake().second, hash.ToString());
  + }
  + //PruneOrphanBlocks();
  + COrphanBlock* pblock2 = new COrphanBlock();
  + {
  + CDataStream ss(SER_DISK, CLIENT_VERSION);
  + ss << *pblock;
  + pblock2->vchBlock = std::vector<unsigned char>(ss.begin(), ss.end());
  + }
  + pblock2->hashBlock = hash;
  + pblock2->hashPrev = pblock->hashPrevBlock;
  + pblock2->stake = pblock->GetProofOfStake();
  + nOrphanBlocksSize += pblock2->vchBlock.size();
  + mapOrphanBlocks.insert(std::make_pair(hash, pblock2));
  + mapOrphanBlocksByPrev.insert(std::make_pair(pblock2->hashPrev, pblock2));
  + if (pblock->IsProofOfStake())
  + setStakeSeenOrphan.insert(pblock->GetProofOfStake());
  +
  + // Ask this guy to fill in what we're missing
  + PushGetBlocks(pfrom, pindexBestHeader, GetOrphanRoot(hash), connman);
  + // ppcoin: getblocks may not obtain the ancestor block rejected
  + // earlier by duplicate-stake check so we ask for it again directly
  + if (!IsInitialBlockDownload())
  + pfrom->AskFor(CInv(MSG_BLOCK, WantedByOrphan(pblock2)));
  + }
  + return true;
  + }
  }
  return ProcessNewBlock(chainparams, pblock, fForceProcessing, fNewBlock);
  