PPCoin: Synchronized checkpoint accepting descendant blocks only
[novacoin.git] / src / main.cpp
index a258284..b8d83b2 100644 (file)
@@ -1561,10 +1561,6 @@ bool CBlock::AcceptBlock()
     if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
         return DoS(100, error("AcceptBlock() : incorrect proof-of-work/proof-of-stake"));
 
-    // ppcoin: coinstake tx must meet target protocol
-    if (IsProofOfStake() && !vtx[1].CheckProofOfStake(nBits))
-        return error("AcceptBlock() : Block %s unable to meet hash target for coinstake", GetHash().ToString().c_str());
-
     // Check timestamp against prev
     if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || GetBlockTime() + nMaxClockDrift < pindexPrev->GetBlockTime())
         return error("AcceptBlock() : block's timestamp is too early");
@@ -1582,6 +1578,10 @@ bool CBlock::AcceptBlock()
     if (!Checkpoints::CheckAuto(pindexPrev))
         return DoS(100, error("AcceptBlock() : rejected by automatic checkpoint at %d", Checkpoints::nAutoCheckpoint));
 
+    // ppcoin: check that the block satisfies synchronized checkpoint
+    if (!Checkpoints::CheckSync(hash, pindexPrev))
+        return error("AcceptBlock() : rejected by synchronized checkpoint");
+
     // Write block to history file
     if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
         return error("AcceptBlock() : out of disk space");
@@ -1600,7 +1600,7 @@ bool CBlock::AcceptBlock()
                     pnode->PushInventory(CInv(MSG_BLOCK, hash));
 
     // ppcoin: check pending sync-checkpoint
-    Checkpoints::AcceptPendingSyncCheckpoint(hash);
+    Checkpoints::AcceptPendingSyncCheckpoint();
 
     return true;
 }
@@ -1624,6 +1624,10 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
     if (!pblock->CheckBlock())
         return error("ProcessBlock() : CheckBlock FAILED");
 
+    // ppcoin: verify hash target and signature of coinstake tx
+    if (pblock->IsProofOfStake() && !pblock->vtx[1].CheckProofOfStake(pblock->nBits))
+        return error("ProcessBlock() : check proof-of-stake failed for block %s", hash.ToString().c_str());
+
     CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
     if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
     {
@@ -1637,11 +1641,15 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
         CBigNum bnNewBlock;
         bnNewBlock.SetCompact(pblock->nBits);
         CBigNum bnRequired;
-        bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
-        if (pblock->IsProofOfWork() && bnNewBlock > bnRequired)
+        if (pblock->IsProofOfWork())
+            bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
+        else
+            bnRequired = bnNewBlock; // TODO: Computer Min Stake Target Allowed
+
+        if (bnNewBlock > bnRequired)
         {
             pfrom->Misbehaving(100);
-            return error("ProcessBlock() : block with too little proof-of-work");
+            return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work");
         }
     }