Calculation of ValueIn and nSigops, implementation of IEqualityComparer<COutPoint>
authorCryptoManiac <balthazar.ad@gmail.com>
Mon, 7 Sep 2015 14:49:52 +0000 (17:49 +0300)
committerCryptoManiac <balthazar.ad@gmail.com>
Mon, 7 Sep 2015 14:50:28 +0000 (17:50 +0300)
Novacoin/CBlockStore.cs
Novacoin/COutPoint.cs
Novacoin/CTransaction.cs

index 2299e15..6cd81df 100644 (file)
@@ -677,13 +677,13 @@ namespace Novacoin
                     // Add in sigops done by pay-to-script-hash inputs;
                     // this is to prevent a "rogue miner" from creating
                     // an incredibly-expensive-to-validate block.
-                    nSigOps += tx.GetP2SHSigOpCount(inputs);
+                    nSigOps += tx.GetP2SHSigOpCount(ref inputs);
                     if (nSigOps > CBlock.nMaxSigOps)
                     {
                         return false; // too many sigops
                     }
 
-                    ulong nTxValueIn = tx.GetValueIn(inputs);
+                    ulong nTxValueIn = tx.GetValueIn(ref inputs);
                     ulong nTxValueOut = tx.nValueOut;
 
                     nValueIn += nTxValueIn;
index b236ccd..07c6552 100644 (file)
@@ -25,7 +25,7 @@ using System.Text;
 
 namespace Novacoin
 {
-    public class COutPoint : IComparable<COutPoint>, IEquatable<COutPoint>
+    public class COutPoint : IComparable<COutPoint>, IEquatable<COutPoint>, IEqualityComparer<COutPoint>
     {
         /// <summary>
         /// Hash of parent transaction.
@@ -135,6 +135,27 @@ namespace Novacoin
 
             return (o.n == n) && (o.hash == hash);
         }
+
+        /// <summary>
+        /// Equality comparer for outpoints.
+        /// </summary>
+        /// <param name="x">First outpoint.</param>
+        /// <param name="y">Second outpoint.</param>
+        /// <returns>Result of comparison.</returns>
+        public bool Equals(COutPoint x, COutPoint y)
+        {
+            return (x.n == y.n) && (x.hash == y.hash);
+        }
+
+        public override int GetHashCode()
+        {
+            return n.GetHashCode() ^ hash.GetHashCode();
+        }
+
+        public int GetHashCode(COutPoint obj)
+        {
+            return obj.GetHashCode();
+        }
     }
 
 }
index a061c70..b525dfc 100644 (file)
@@ -272,7 +272,7 @@ namespace Novacoin
             }
             return true;
         }
-        
+
         /// <summary>
         /// Parse byte sequence and initialize new instance of CTransaction
         /// </summary>
@@ -481,14 +481,69 @@ namespace Novacoin
 
         public static bool MoneyRange(ulong nValue) { return (nValue <= nMaxMoney); }
 
-        internal uint GetP2SHSigOpCount(Dictionary<COutPoint, TxOutItem> inputs)
+        /// <summary>
+        /// Get total sigops.
+        /// </summary>
+        /// <param name="inputs">Inputs map.</param>
+        /// <returns>Amount of sigops.</returns>
+        public uint GetP2SHSigOpCount(ref Dictionary<COutPoint, TxOutItem> inputs)
+        {
+            if (IsCoinBase)
+            {
+                return 0;
+            }
+
+            uint nSigOps = 0;
+            for (var i = 0; i < vin.Length; i++)
+            {
+                var prevout = GetOutputFor(vin[i], ref inputs);
+                if (prevout.scriptPubKey.IsPayToScriptHash)
+                {
+                    nSigOps += prevout.scriptPubKey.GetSigOpCount(vin[i].scriptSig);
+                }
+            }
+
+            return nSigOps;
+        }
+
+        /// <summary>
+        /// Get sum of inputs spent by this transaction.
+        /// </summary>
+        /// <param name="inputs">Reference to innputs map.</param>
+        /// <returns>Sum of inputs.</returns>
+        public ulong GetValueIn(ref Dictionary<COutPoint, TxOutItem> inputs)
         {
-            throw new NotImplementedException();
+            if (IsCoinBase)
+            {
+                return 0;
+            }
+
+            ulong nResult = 0;
+            for (int i = 0; i < vin.Length; i++)
+            {
+                nResult += GetOutputFor(vin[i], ref inputs).nValue;
+            }
+
+            return nResult;
         }
 
-        internal ulong GetValueIn(Dictionary<COutPoint, TxOutItem> inputs)
+        /// <summary>
+        /// Helper method to find output in the map.
+        /// </summary>
+        /// <param name="input">Transaction input.</param>
+        /// <param name="inputs">eference to inuts map.</param>
+        /// <returns>Parent output.</returns>
+        private CTxOut GetOutputFor(CTxIn input, ref Dictionary<COutPoint, TxOutItem> inputs)
         {
-            throw new NotImplementedException();
+            if (!inputs.ContainsKey(input.prevout))
+            {
+                throw new Exception("No such input");
+            }
+
+            var outItem = inputs[input.prevout];
+
+            return new CTxOut(outItem.nValue, outItem.scriptPubKey);
         }
+
     }
 }