PPCoin: Fix bug in CBlock::ReadFromDisk() since 94ced845
[novacoin.git] / src / main.h
index 59b88ce..bd07ceb 100644 (file)
@@ -667,6 +667,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;
 };
 
 
@@ -807,13 +808,12 @@ public:
     unsigned int nBits;
     unsigned int nNonce;
 
-    // ppcoin: block signature (not considered part of header)
-    //         signed by coin base txout[0]'s owner
-    std::vector<unsigned char> vchBlockSig;
-
     // network and disk
     std::vector<CTransaction> vtx;
 
+    // ppcoin: block signature - signed by coin base txout[0]'s owner
+    std::vector<unsigned char> vchBlockSig;
+
     // memory only
     mutable std::vector<uint256> vMerkleTree;
 
@@ -836,16 +836,16 @@ public:
         READWRITE(nBits);
         READWRITE(nNonce);
 
-        // ConnectBlock depends on vtx being last so it can calculate offset
+        // ConnectBlock depends on vtx following header to generate CDiskTxPos
         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
         {
-            READWRITE(vchBlockSig);
             READWRITE(vtx);
+            READWRITE(vchBlockSig);
         }
         else if (fRead)
         {
-            const_cast<CBlock*>(this)->vchBlockSig.clear();
             const_cast<CBlock*>(this)->vtx.clear();
+            const_cast<CBlock*>(this)->vchBlockSig.clear();
         }
     )
 
@@ -857,8 +857,8 @@ public:
         nTime = 0;
         nBits = 0;
         nNonce = 0;
-        vchBlockSig.clear();
         vtx.clear();
+        vchBlockSig.clear();
         vMerkleTree.clear();
         nDoS = 0;
     }
@@ -878,6 +878,17 @@ public:
         return (int64)nTime;
     }
 
+    // ppcoin: two types of block: proof-of-work or proof-of-stake
+    bool IsProofOfStake() const
+    {
+        return (vtx.size() > 1 && vtx[1].IsCoinStake());
+    }
+
+    bool IsProofOfWork() const
+    {
+        return !IsProofOfStake();
+    }
+
     // ppcoin: get max transaction timestamp
     int64 GetMaxTransactionTime() const
     {
@@ -993,7 +1004,7 @@ public:
         filein >> *this;
 
         // Check the header
-        if (!CheckProofOfWork(GetHash(), nBits))
+        if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits))
             return error("CBlock::ReadFromDisk() : errors in block header");
 
         return true;
@@ -1003,14 +1014,14 @@ public:
 
     void print() const
     {
-        printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vchBlockSig=%s, vtx=%d)\n",
+        printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d, vchBlockSig=%s)\n",
             GetHash().ToString().substr(0,20).c_str(),
             nVersion,
             hashPrevBlock.ToString().substr(0,20).c_str(),
             hashMerkleRoot.ToString().substr(0,10).c_str(),
             nTime, nBits, nNonce,
-            HexStr(vchBlockSig.begin(), vchBlockSig.end()).c_str(),
-            vtx.size());
+            vtx.size(),
+            HexStr(vchBlockSig.begin(), vchBlockSig.end()).c_str());
         for (int i = 0; i < vtx.size(); i++)
         {
             printf("  ");
@@ -1105,6 +1116,7 @@ public:
     uint64 nChainTrust;// ppcoin: trust score of chain, in the unit of coin-days
     int nHeight;
     int nCheckpoint;    // ppcoin: chain auto checkpoint height
+    bool fProofOfStake; // ppcoin: is the block of proof-of-stake type
 
     // block header
     int nVersion;
@@ -1124,6 +1136,7 @@ public:
         nHeight = 0;
         nChainTrust = 0;
         nCheckpoint = 0;
+        fProofOfStake = true;
 
         nVersion       = 0;
         hashMerkleRoot = 0;
@@ -1142,6 +1155,7 @@ public:
         nHeight = 0;
         nChainTrust = 0;
         nCheckpoint = 0;
+        fProofOfStake = block.IsProofOfStake();
 
         nVersion       = block.nVersion;
         hashMerkleRoot = block.hashMerkleRoot;
@@ -1185,7 +1199,7 @@ public:
 
     bool CheckIndex() const
     {
-        return CheckProofOfWork(GetBlockHash(), nBits);
+        return IsProofOfWork() ? CheckProofOfWork(GetBlockHash(), nBits) : true;
     }
 
     bool EraseBlockFromDisk()
@@ -1231,12 +1245,20 @@ public:
         return pindex->GetMedianTimePast();
     }
 
+    bool IsProofOfWork() const
+    {
+        return !fProofOfStake;
+    }
 
+    bool IsProofOfStake() const
+    {
+        return fProofOfStake;
+    }
 
     std::string ToString() const
     {
-        return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, nCheckpoint=%d, merkle=%s, hashBlock=%s)",
-            pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint,
+        return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, nCheckpoint=%d, fProofOfStake=%d merkle=%s, hashBlock=%s)",
+            pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint, fProofOfStake,
             hashMerkleRoot.ToString().substr(0,10).c_str(),
             GetBlockHash().ToString().substr(0,20).c_str());
     }
@@ -1281,6 +1303,7 @@ public:
         READWRITE(nChainTrust);
         READWRITE(nHeight);
         READWRITE(nCheckpoint);
+        READWRITE(fProofOfStake);
 
         // block header
         READWRITE(this->nVersion);
@@ -1644,7 +1667,7 @@ public:
     bool CheckSignature()
     {
         CKey key;
-        if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
+        if (!key.SetPubKey(ParseHex("0487ca85b6ae9d311f996c7616d20d0c88a5b4f07d25e78f419019f35cce6522acf978b2d99f0e7a58db1f120439e5c1889266927854aa57c93956c2569188a539")))
             return error("CAlert::CheckSignature() : SetPubKey failed");
         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
             return error("CAlert::CheckSignature() : verify signature failed");