PPCoin: Check stake target and signature for all accepted block
authorSunny King <sunnyking9999@gmail.com>
Thu, 31 May 2012 20:45:25 +0000 (21:45 +0100)
committerSunny King <sunnyking9999@gmail.com>
Thu, 31 May 2012 20:45:25 +0000 (21:45 +0100)
src/main.cpp
src/main.h

index dc2d7b2..803cd79 100644 (file)
@@ -1081,10 +1081,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
     if (!CheckBlock())
         return false;
 
-    // ppcoin: coin stake tx must meet target protocol
-    if (IsProofOfStake() && !vtx[1].CheckProofOfStake(txdb, nBits))
-        return error("ConnectBlock() : Block %s unable to meet hash target for coinstake", GetHash().ToString().c_str());
-
     //// issue here: it doesn't know the version
     unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - (2 * GetSizeOfCompactSize(0)) + GetSizeOfCompactSize(vtx.size());
 
@@ -1308,7 +1304,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
 //   quantities so as to generate blocks faster, degrading the system back into
 //   a proof-of-work situation.
 //
-bool CTransaction::CheckProofOfStake(CTxDB& txdb, unsigned int nBits) const
+bool CTransaction::CheckProofOfStake(unsigned int nBits) const
 {
     CBigNum bnTargetPerCoinDay;
     bnTargetPerCoinDay.SetCompact(nBits);
@@ -1320,13 +1316,19 @@ bool CTransaction::CheckProofOfStake(CTxDB& txdb, unsigned int nBits) const
     const CTxIn& txin = vin[0];
 
     // First try finding the previous transaction in database
+    CTxDB txdb("r");
     CTransaction txPrev;
     CTxIndex txindex;
     if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
         return false;  // previous transaction not in main chain
+    txdb.Close();
     if (nTime < txPrev.nTime)
         return false;  // Transaction timestamp violation
 
+    // Verify signature
+    if (!VerifySignature(txPrev, *this, 0))
+        return DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", GetHash().ToString().c_str()));
+
     // Read block header
     CBlock block;
     if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
@@ -1342,7 +1344,7 @@ bool CTransaction::CheckProofOfStake(CTxDB& txdb, unsigned int nBits) const
     if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
         return true;
     else
-        return false;
+        return DoS(100, error("CheckProofOfStake() : check target failed on coinstake %s", GetHash().ToString().c_str()));
 }
 
 // ppcoin: total coin age spent in transaction, in the unit of coin-days.
@@ -1555,6 +1557,10 @@ 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");
index 6d2ead4..f6db3b3 100644 (file)
@@ -675,7 +675,7 @@ protected:
 public:
     bool RemoveFromMemoryPool();
     bool GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const;  // ppcoin: get transaction coin age
-    bool CheckProofOfStake(CTxDB& txdb, unsigned int nBits) const;
+    bool CheckProofOfStake(unsigned int nBits) const;
 };