Enforce rule that the coinbase starts with serialized block height.
[NovacoinLibrary.git] / Novacoin / CBlockStore.cs
index 25ea3bb..8235d51 100644 (file)
@@ -197,6 +197,8 @@ namespace Novacoin
                 // Init list of block items
                 foreach (var item in blockTreeItems)
                 {
+                    item.nStakeModifierChecksum = StakeModifier.GetModifierChecksum(item);
+
                     blockMap.TryAdd(item.Hash, item);
 
                     if (item.IsProofOfStake)
@@ -359,9 +361,12 @@ namespace Novacoin
             }
 
             itemTemplate.SetStakeModifier(nStakeModifier, fGeneratedStakeModifier);
-            itemTemplate.nStakeModifierChecksum = StakeModifier.GetStakeModifierChecksum(ref itemTemplate);
+            itemTemplate.nStakeModifierChecksum = StakeModifier.GetModifierChecksum(itemTemplate);
 
-            // TODO: verify stake modifier checkpoints
+            if (!ModifierCheckpoints.Verify(itemTemplate.nHeight, itemTemplate.nStakeModifierChecksum))
+            {
+                return false; // Stake modifier checkpoints mismatch
+            }
 
             // Add to index
             if (block.IsProofOfStake)
@@ -645,7 +650,7 @@ namespace Novacoin
                 return false; // Invalid block found.
             }
 
-            bool fScriptChecks = cursor.nHeight >= Checkpoints.TotalBlocksEstimate;
+            bool fScriptChecks = cursor.nHeight >= HashCheckpoints.TotalBlocksEstimate;
             var scriptFlags = scriptflag.SCRIPT_VERIFY_NOCACHE | scriptflag.SCRIPT_VERIFY_P2SH;
 
             long nFees = 0;
@@ -965,7 +970,7 @@ namespace Novacoin
 
                 if (tx.IsCoinStake)
                 {
-                    // ppcoin: coin stake tx earns reward instead of paying fee
+                    // Coin stake tx earns reward instead of paying fee
                     long nCoinAge;
                     if (!tx.GetCoinAge(ref inputs, out nCoinAge))
                     {
@@ -1053,7 +1058,6 @@ namespace Novacoin
 
             var prevBlockHeader = prevBlockCursor.BlockHeader;
 
-            // TODO: proof-of-work/proof-of-stake verification
             uint nHeight = prevBlockCursor.nHeight + 1;
 
             // Check timestamp against prev
@@ -1072,7 +1076,23 @@ namespace Novacoin
                 }
             }
 
-            // TODO: Enforce rule that the coinbase starts with serialized block height
+            // Check that the block chain matches the known block chain up to a checkpoint
+            if (!HashCheckpoints.Verify(nHeight, nHash))
+            {
+                return false;  // rejected by checkpoint lock-in
+            }
+
+            // Enforce rule that the coinbase starts with serialized block height
+            var expect = new CScript();
+            expect.AddNumber((int)nHeight);
+
+            byte[] expectBytes = expect;
+            byte[] scriptSig = block.vtx[0].vin[0].scriptSig;
+
+            if (!expectBytes.SequenceEqual(scriptSig.Take(expectBytes.Length)))
+            {
+                return false; // coinbase doesn't start with serialized height.
+            }
 
             // Write block to file.
             var itemTemplate = new CBlockStoreItem()
@@ -1093,7 +1113,7 @@ namespace Novacoin
         }
 
         /// <summary>
-        /// GEt block by hash.
+        /// Get block by hash.
         /// </summary>
         /// <param name="blockHash">Block hash</param>
         /// <param name="block">Block object reference</param>
@@ -1281,8 +1301,6 @@ namespace Novacoin
 
             if (block.IsProofOfStake)
             {
-                // TODO: proof-of-stake validation
-
                 uint256 hashProofOfStake = 0, targetProofOfStake = 0;
                 if (!StakeModifier.CheckProofOfStake(block.vtx[1], block.header.nBits, out hashProofOfStake, out targetProofOfStake))
                 {