PPCoin: Reduce stale proof-of-stake blocks generated in CreateNewBlock()
[novacoin.git] / src / main.cpp
index 4581fcf..08ceb20 100644 (file)
@@ -1540,7 +1540,16 @@ bool CBlock::AcceptBlock()
     CBlockIndex* pindexPrev = (*mi).second;
     int nHeight = pindexPrev->nHeight+1;
 
-    // Check proof of work
+    // ppcoin: check for coinstake duplicate
+    if (IsProofOfStake())
+    {   // check if coinstake is already connected; that would imply the owner
+        // of the coinstake sent multiple blocks with the same coinstake
+        CTxIndex txindex;
+        if (CTxDB("r").ReadTxIndex(vtx[1].GetHash(), txindex))
+            return error("AcceptBlock() : block %s has duplicate coinstake %s", hash.ToString().c_str(), vtx[1].GetHash().ToString().c_str());
+    }
+
+    // Check proof-of-work or proof-of-stake
     if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
         return DoS(100, error("AcceptBlock() : incorrect proof-of-work/proof-of-stake"));
 
@@ -1608,7 +1617,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
         bnNewBlock.SetCompact(pblock->nBits);
         CBigNum bnRequired;
         bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
-        if (bnNewBlock > bnRequired)
+        if (pblock->IsProofOfWork() && bnNewBlock > bnRequired)
         {
             pfrom->Misbehaving(100);
             return error("ProcessBlock() : block with too little proof-of-work");
@@ -1851,11 +1860,12 @@ void PrintBlockTree()
         // print item
         CBlock block;
         block.ReadFromDisk(pindex);
-        printf("%d (%u,%u) %s  %s  tx %d",
+        printf("%d (%u,%u) %s  %08lx  %s  tx %d",
             pindex->nHeight,
             pindex->nFile,
             pindex->nBlockPos,
             block.GetHash().ToString().substr(0,20).c_str(),
+            block.nBits,
             DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
             block.vtx.size());
 
@@ -2964,7 +2974,6 @@ public:
 
 CBlock* CreateNewBlock(CWallet* pwallet)
 {
-    CBlockIndex* pindexPrev = pindexBest;
     CReserveKey reservekey(pwallet);
 
     // Create new block
@@ -2984,9 +2993,11 @@ CBlock* CreateNewBlock(CWallet* pwallet)
 
     // ppcoin: if coinstake available add coinstake tx
     static unsigned int nLastCoinStakeCheckTime = GetAdjustedTime() - nMaxClockDrift;  // only initialized at startup
-    pblock->nBits = GetNextTargetRequired(pindexPrev, true);
+    CBlockIndex* pindexPrev = pindexBest;
     while (nLastCoinStakeCheckTime < GetAdjustedTime())
     {
+        pindexPrev = pindexBest;  // get best block again to avoid getting stale
+        pblock->nBits = GetNextTargetRequired(pindexPrev, true);
         static CCriticalSection cs;
         CTransaction txCoinStake;
         CRITICAL_BLOCK(cs)
@@ -3000,8 +3011,8 @@ CBlock* CreateNewBlock(CWallet* pwallet)
             break;
         }
     }
-    if (pblock->IsProofOfWork())
-        pblock->nBits = GetNextTargetRequired(pindexPrev, false);
+
+    pblock->nBits = GetNextTargetRequired(pindexPrev, pblock->IsProofOfStake());
 
     // Collect memory pool transactions into the block
     int64 nFees = 0;
@@ -3270,6 +3281,8 @@ void static BitcoinMiner(CWallet *pwallet)
         if (!pblock.get())
             return;
 
+        IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
+
         // ppcoin: if proof-of-stake block found then process block
         if (pblock->IsProofOfStake())
         {
@@ -3282,8 +3295,6 @@ void static BitcoinMiner(CWallet *pwallet)
             continue;
         }
 
-        IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
-
         printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());