Remove legacy stake reward calculation code.
[NovacoinLibrary.git] / Novacoin / CBlockStore.cs
index fde21c6..62a021f 100644 (file)
@@ -177,14 +177,14 @@ namespace Novacoin
                     ));
 
                     // Write block to file.
-                    var itemTemplate = new CBlockStoreItem()
+                    var rootCursor = new CBlockStoreItem()
                     {
                         nHeight = 0
                     };
 
-                    itemTemplate.FillHeader(genesisBlock.header);
+                    rootCursor.FillHeader(genesisBlock.header);
 
-                    if (!AddItemToIndex(ref itemTemplate, ref genesisBlock))
+                    if (!AddItemToIndex(ref rootCursor, ref genesisBlock))
                     {
                         throw new Exception("Unable to write genesis block");
                     }
@@ -331,9 +331,9 @@ namespace Novacoin
             return true;
         }
 
-        private bool AddItemToIndex(ref CBlockStoreItem itemTemplate, ref CBlock block)
+        private bool AddItemToIndex(ref CBlockStoreItem newCursor, ref CBlock block)
         {
-            uint256 blockHash = itemTemplate.Hash;
+            uint256 blockHash = newCursor.Hash;
 
             if (blockMap.ContainsKey(blockHash))
             {
@@ -345,9 +345,9 @@ namespace Novacoin
             dbConn.BeginTransaction();
 
             // Compute chain trust score
-            itemTemplate.nChainTrust = (itemTemplate.prev != null ? itemTemplate.prev.nChainTrust : 0) + itemTemplate.nBlockTrust;
+            newCursor.nChainTrust = (newCursor.prev != null ? newCursor.prev.nChainTrust : 0) + newCursor.nBlockTrust;
 
-            if (!itemTemplate.SetStakeEntropyBit(Entropy.GetStakeEntropyBit(itemTemplate.nHeight, blockHash)))
+            if (!newCursor.SetStakeEntropyBit(Entropy.GetStakeEntropyBit(newCursor.nHeight, blockHash)))
             {
                 return false; // SetStakeEntropyBit() failed
             }
@@ -355,15 +355,15 @@ namespace Novacoin
             // compute stake modifier
             long nStakeModifier = 0;
             bool fGeneratedStakeModifier = false;
-            if (!StakeModifier.ComputeNextStakeModifier(itemTemplate, ref nStakeModifier, ref fGeneratedStakeModifier))
+            if (!StakeModifier.ComputeNextStakeModifier(ref newCursor, ref nStakeModifier, ref fGeneratedStakeModifier))
             {
                 return false;  // ComputeNextStakeModifier() failed
             }
 
-            itemTemplate.SetStakeModifier(nStakeModifier, fGeneratedStakeModifier);
-            itemTemplate.nStakeModifierChecksum = StakeModifier.GetModifierChecksum(itemTemplate);
+            newCursor.SetStakeModifier(nStakeModifier, fGeneratedStakeModifier);
+            newCursor.nStakeModifierChecksum = StakeModifier.GetModifierChecksum(newCursor);
 
-            if (!ModifierCheckpoints.Verify(itemTemplate.nHeight, itemTemplate.nStakeModifierChecksum))
+            if (!ModifierCheckpoints.Verify(newCursor.nHeight, newCursor.nStakeModifierChecksum))
             {
                 return false; // Stake modifier checkpoints mismatch
             }
@@ -371,10 +371,10 @@ namespace Novacoin
             // Add to index
             if (block.IsProofOfStake)
             {
-                itemTemplate.SetProofOfStake();
+                newCursor.SetProofOfStake();
 
-                itemTemplate.prevoutStake = block.vtx[1].vin[0].prevout;
-                itemTemplate.nStakeTime = block.vtx[1].nTime;
+                newCursor.prevoutStake = block.vtx[1].vin[0].prevout;
+                newCursor.nStakeTime = block.vtx[1].nTime;
 
                 // Save proof-of-stake hash value
                 uint256 hashProofOfStake;
@@ -382,32 +382,32 @@ namespace Novacoin
                 {
                     return false;  // hashProofOfStake not found 
                 }
-                itemTemplate.hashProofOfStake = hashProofOfStake;
+                newCursor.hashProofOfStake = hashProofOfStake;
             }
 
-            if (!itemTemplate.WriteToFile(ref fStreamReadWrite, ref block))
+            if (!newCursor.WriteToFile(ref fStreamReadWrite, ref block))
             {
                 return false;
             }
 
-            if (dbConn.Insert(itemTemplate) == 0)
+            if (dbConn.Insert(newCursor) == 0)
             {
                 return false; // Insert failed
             }
 
             // Get last RowID.
-            itemTemplate.ItemID = dbPlatform.SQLiteApi.LastInsertRowid(dbConn.Handle);
+            newCursor.ItemID = dbPlatform.SQLiteApi.LastInsertRowid(dbConn.Handle);
 
-            if (!blockMap.TryAdd(blockHash, itemTemplate))
+            if (!blockMap.TryAdd(blockHash, newCursor))
             {
                 return false; // blockMap add failed
             }
 
-            if (itemTemplate.nChainTrust > ChainParams.nBestChainTrust)
+            if (newCursor.nChainTrust > ChainParams.nBestChainTrust)
             {
                 // New best chain
 
-                if (!SetBestChain(ref itemTemplate))
+                if (!SetBestChain(ref newCursor))
                 {
                     return false; // SetBestChain failed.
                 }
@@ -970,20 +970,22 @@ namespace Novacoin
 
                 if (tx.IsCoinStake)
                 {
-                    // Coin stake tx earns reward instead of paying fee
-                    long nCoinAge;
-                    if (!tx.GetCoinAge(ref inputs, out nCoinAge))
+                    if (HashCheckpoints.LastCheckpointTime < tx.nTime)
                     {
-                        return false; // unable to get coin age for coinstake
-                    }
-
-                    long nReward = tx.nValueOut - nValueIn;
+                        // Coin stake tx earns reward instead of paying fee
+                        long nCoinAge;
+                        if (!tx.GetCoinAge(ref inputs, out nCoinAge))
+                        {
+                            return false; // unable to get coin age for coinstake
+                        }
 
-                    long nCalculatedReward = CBlock.GetProofOfStakeReward(nCoinAge, cursorBlock.nBits, tx.nTime) - tx.GetMinFee(1, false, CTransaction.MinFeeMode.GMF_BLOCK) + CTransaction.nCent;
+                        long nReward = tx.nValueOut - nValueIn;
+                        long nCalculatedReward = CBlock.GetProofOfStakeReward(nCoinAge, cursorBlock.nBits, tx.nTime) - tx.GetMinFee(1, false, CTransaction.MinFeeMode.GMF_BLOCK) + CTransaction.nCent;
 
-                    if (nReward > nCalculatedReward)
-                    {
-                        return false; // coinstake pays too much
+                        if (nReward > nCalculatedReward)
+                        {
+                            return false; // coinstake pays too much
+                        }
                     }
                 }
                 else
@@ -1058,7 +1060,6 @@ namespace Novacoin
 
             var prevBlockHeader = prevBlockCursor.BlockHeader;
 
-            // TODO: proof-of-work/proof-of-stake verification
             uint nHeight = prevBlockCursor.nHeight + 1;
 
             // Check timestamp against prev
@@ -1083,17 +1084,27 @@ namespace Novacoin
                 return false;  // rejected by checkpoint lock-in
             }
 
-            // TODO: Enforce rule that the coinbase starts with serialized block height
+            // 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()
+            var newCursor = new CBlockStoreItem()
             {
                 nHeight = nHeight,
             };
 
-            itemTemplate.FillHeader(block.header);
+            newCursor.FillHeader(block.header);
 
-            if (!AddItemToIndex(ref itemTemplate, ref block))
+            if (!AddItemToIndex(ref newCursor, ref block))
             {
                 dbConn.Rollback();
 
@@ -1292,8 +1303,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))
                 {