From 4370732bca42bcd668c0cb3997b9268f88ca863e Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Mon, 7 Sep 2015 17:49:52 +0300 Subject: [PATCH] Calculation of ValueIn and nSigops, implementation of IEqualityComparer --- Novacoin/CBlockStore.cs | 4 +- Novacoin/COutPoint.cs | 23 +++++++++++++++- Novacoin/CTransaction.cs | 65 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/Novacoin/CBlockStore.cs b/Novacoin/CBlockStore.cs index 2299e15..6cd81df 100644 --- a/Novacoin/CBlockStore.cs +++ b/Novacoin/CBlockStore.cs @@ -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; diff --git a/Novacoin/COutPoint.cs b/Novacoin/COutPoint.cs index b236ccd..07c6552 100644 --- a/Novacoin/COutPoint.cs +++ b/Novacoin/COutPoint.cs @@ -25,7 +25,7 @@ using System.Text; namespace Novacoin { - public class COutPoint : IComparable, IEquatable + public class COutPoint : IComparable, IEquatable, IEqualityComparer { /// /// Hash of parent transaction. @@ -135,6 +135,27 @@ namespace Novacoin return (o.n == n) && (o.hash == hash); } + + /// + /// Equality comparer for outpoints. + /// + /// First outpoint. + /// Second outpoint. + /// Result of comparison. + 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(); + } } } diff --git a/Novacoin/CTransaction.cs b/Novacoin/CTransaction.cs index a061c70..b525dfc 100644 --- a/Novacoin/CTransaction.cs +++ b/Novacoin/CTransaction.cs @@ -272,7 +272,7 @@ namespace Novacoin } return true; } - + /// /// Parse byte sequence and initialize new instance of CTransaction /// @@ -481,14 +481,69 @@ namespace Novacoin public static bool MoneyRange(ulong nValue) { return (nValue <= nMaxMoney); } - internal uint GetP2SHSigOpCount(Dictionary inputs) + /// + /// Get total sigops. + /// + /// Inputs map. + /// Amount of sigops. + public uint GetP2SHSigOpCount(ref Dictionary 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; + } + + /// + /// Get sum of inputs spent by this transaction. + /// + /// Reference to innputs map. + /// Sum of inputs. + public ulong GetValueIn(ref Dictionary 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 inputs) + /// + /// Helper method to find output in the map. + /// + /// Transaction input. + /// eference to inuts map. + /// Parent output. + private CTxOut GetOutputFor(CTxIn input, ref Dictionary 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); } + } } -- 1.7.1