From: CryptoManiac Date: Sun, 6 Sep 2015 22:24:14 +0000 (+0300) Subject: Checkpoints valudation, PoW reward calculation and continue working on block index. X-Git-Url: https://git.novaco.in/?p=NovacoinLibrary.git;a=commitdiff_plain;h=624ac1021490395614a0cbee619c79860c22061a Checkpoints valudation, PoW reward calculation and continue working on block index. --- diff --git a/Novacoin/CBlock.cs b/Novacoin/CBlock.cs index 9bf7e36..e8f2207 100644 --- a/Novacoin/CBlock.cs +++ b/Novacoin/CBlock.cs @@ -21,6 +21,7 @@ using System.Text; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.IO; +using System.Numerics; namespace Novacoin { @@ -199,13 +200,13 @@ namespace Novacoin } // Check timestamp - if (header.nTime > NetUtils.FutureDrift(NetUtils.GetAdjustedTime())) + if (header.nTime > NetInfo.FutureDrift(NetInfo.GetAdjustedTime())) { return false; } // Check coinbase timestamp - if (header.nTime < NetUtils.PastDrift(vtx[0].nTime)) + if (header.nTime < NetInfo.PastDrift(vtx[0].nTime)) { return false; } @@ -275,7 +276,7 @@ namespace Novacoin nTarget.Compact = nBits; // Check range - if (nTarget > NetUtils.nProofOfWorkLimit) + if (nTarget > NetInfo.nProofOfWorkLimit) { // nBits below minimum work return false; @@ -470,6 +471,51 @@ namespace Novacoin return sb.ToString(); } - } + + /// + /// Calculate proof-of-work reward. + /// + /// Packed difficulty representation. + /// Amount of fees. + /// Reward value. + public static ulong GetProofOfWorkReward(uint nBits, ulong nFees) + { + // NovaCoin: subsidy is cut in half every 64x multiply of PoW difficulty + // A reasonably continuous curve is used to avoid shock to market + // (nSubsidyLimit / nSubsidy) ** 6 == bnProofOfWorkLimit / bnTarget + // + // Human readable form: + // + // nSubsidy = 100 / (diff ^ 1/6) + // + // Please note that we're using bisection to find an approximate solutuion + + BigInteger bnSubsidyLimit = NetInfo.nMaxMintProofOfWork; + + uint256 nTarget = 0; + nTarget.Compact = nBits; + + BigInteger bnTarget = new BigInteger(nTarget); + BigInteger bnTargetLimit = new BigInteger(NetInfo.nProofOfWorkLimit); + + BigInteger bnLowerBound = CTransaction.nCent; + BigInteger bnUpperBound = bnSubsidyLimit; + + while (bnLowerBound + CTransaction.nCent <= bnUpperBound) + { + BigInteger bnMidValue = (bnLowerBound + bnUpperBound) / 2; + if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnTarget) + bnUpperBound = bnMidValue; + else + bnLowerBound = bnMidValue; + } + + ulong nSubsidy = (ulong)bnUpperBound; + nSubsidy = (nSubsidy / CTransaction.nCent) * CTransaction.nCent; + + + return Math.Min(nSubsidy, NetInfo.nMaxMintProofOfWork) + nFees; + } + } } diff --git a/Novacoin/CBlockStore.cs b/Novacoin/CBlockStore.cs index a4466ab..022459b 100644 --- a/Novacoin/CBlockStore.cs +++ b/Novacoin/CBlockStore.cs @@ -289,8 +289,9 @@ namespace Novacoin /// Previous block cursor /// [Ignore] - public CBlockStoreItem prev { - get { return CBlockStore.Instance.GetCursor(prevHash); } + public CBlockStoreItem prev + { + get { return CBlockStore.Instance.GetMapCursor(prevHash); } } /// @@ -306,14 +307,13 @@ namespace Novacoin return null; } - return CBlockStore.Instance.GetCursor(nextHash); + return CBlockStore.Instance.GetMapCursor(nextHash); } set { - CBlockStoreItem newCursor = this; - newCursor.nextHash = value.Hash; + nextHash = value.Hash; - CBlockStore.Instance.UpdateCursor(this, ref newCursor); + CBlockStore.Instance.UpdateMapCursor(this); } } @@ -404,7 +404,7 @@ namespace Novacoin nTarget.Compact = nBits; /* Old protocol */ - if (nTime < NetUtils.nChainChecksSwitchTime) + if (nTime < NetInfo.nChainChecksSwitchTime) { return IsProofOfStake ? (new uint256(1) << 256) / (nTarget + 1) : 1; } @@ -412,7 +412,7 @@ namespace Novacoin /* New protocol */ // Calculate work amount for block - var nPoWTrust = NetUtils.nPoWBase / (nTarget + 1); + var nPoWTrust = NetInfo.nPoWBase / (nTarget + 1); // Set nPowTrust to 1 if we are checking PoS block or PoW difficulty is too low nPoWTrust = (IsProofOfStake || !nPoWTrust) ? 1 : nPoWTrust; @@ -509,6 +509,9 @@ namespace Novacoin get { return Interop.AppendWithZeros(ChainTrust); } set { ChainTrust = Interop.TrimArray(value); } } + + public long nMint { get; internal set; } + public long nMoneySupply { get; internal set; } } /// @@ -625,6 +628,7 @@ namespace Novacoin public long nTxOffset { get { return (long) VarInt.DecodeVarInt(TxOffset); } + private set { TxOffset = VarInt.EncodeVarInt(value); } } /// @@ -634,6 +638,51 @@ namespace Novacoin public int nTxSize { get { return (int)VarInt.DecodeVarInt(TxSize); } + private set { TxSize = VarInt.EncodeVarInt(value); } + } + + public CMerkleNode(CTransaction tx) + { + nTxOffset = -1; + nParentBlockID = -1; + + nTxSize = tx.Size; + TransactionHash = tx.Hash; + + if (tx.IsCoinBase) + { + TransactionFlags |= TxFlags.TX_COINBASE; + } + else if (tx.IsCoinStake) + { + TransactionFlags |= TxFlags.TX_COINSTAKE; + } + else + { + TransactionFlags |= TxFlags.TX_USER; + } + } + + public CMerkleNode(long nBlockId, long nOffset, CTransaction tx) + { + nParentBlockID = nBlockId; + + nTxOffset = nOffset; + nTxSize = tx.Size; + TransactionHash = tx.Hash; + + if (tx.IsCoinBase) + { + TransactionFlags |= TxFlags.TX_COINBASE; + } + else if (tx.IsCoinStake) + { + TransactionFlags |= TxFlags.TX_COINSTAKE; + } + else + { + TransactionFlags |= TxFlags.TX_USER; + } } } @@ -670,27 +719,39 @@ namespace Novacoin /// /// Getter for output number. /// + [Ignore] public uint nOut { get { return (uint)VarInt.DecodeVarInt(OutputNumber); } + private set { OutputNumber = VarInt.EncodeVarInt(value); } } /// /// Getter for output value. /// + [Ignore] public ulong nValue { get { return VarInt.DecodeVarInt(OutputValue); } + private set { OutputValue = VarInt.EncodeVarInt(value); } } /// /// Getter ans setter for IsSpent flag. /// + [Ignore] public bool IsSpent { get { return (outputFlags & OutputFlags.SPENT) != 0; } set { outputFlags |= value ? OutputFlags.SPENT : OutputFlags.AVAILABLE; } } + + public TxOutItem(CTxOut o, uint nOut) + { + nValue = o.nValue; + scriptPubKey = o.scriptPubKey; + this.nOut = nOut; + } } public class CBlockStore : IDisposable @@ -886,7 +947,7 @@ namespace Novacoin byte[] TransactionHash { get; set; } } - public bool FetchInputs(ref CTransaction tx, ref Dictionary queued, ref Dictionary inputs, bool IsBlock, out bool Invalid) + public bool FetchInputs(CTransaction tx, ref Dictionary queued, ref Dictionary inputs, bool IsBlock, out bool Invalid) { Invalid = false; @@ -919,8 +980,10 @@ namespace Novacoin var inputsKey = new COutPoint(item.TransactionHash, item.nOut); + item.IsSpent = true; + // Add output data to dictionary - inputs[inputsKey] = new CTxOut(item.nValue, item.scriptPubKey); + inputs.Add(inputsKey, (TxOutItem) item); } if (queryResults.Count < tx.vin.Length) @@ -939,10 +1002,10 @@ namespace Novacoin } // Add output data to dictionary - inputs[outPoint] = queued[outPoint]; + inputs.Add(outPoint, queued[outPoint]); - // And remove it from queued data - queued.Remove(outPoint); + // Mark output as spent + queued[outPoint].IsSpent = true; } } else @@ -965,8 +1028,10 @@ namespace Novacoin return false; // nOut is out of range } + + // TODO: return inputs from map + throw new NotImplementedException(); - inputs[outPoint] = txPrev.vout[outPoint.n]; } return false; @@ -1063,7 +1128,7 @@ namespace Novacoin { uint256 hashBlock = cursor.Hash; - if (genesisBlockCursor == null && hashBlock == NetUtils.nHashGenesisBlock) + if (genesisBlockCursor == null && hashBlock == NetInfo.nHashGenesisBlock) { genesisBlockCursor = cursor; } @@ -1288,11 +1353,186 @@ namespace Novacoin return false; // Invalid block found. } + bool fScriptChecks = cursor.nHeight >= Checkpoints.TotalBlocksEstimate; + var scriptFlags = scriptflag.SCRIPT_VERIFY_NOCACHE | scriptflag.SCRIPT_VERIFY_P2SH; + + ulong nFees = 0; + ulong nValueIn = 0; + ulong nValueOut = 0; + uint nSigOps = 0; + + var queuedMerkleNodes = new Dictionary(); + var queued = new Dictionary(); + + for (var nTx = 0; nTx < block.vtx.Length; nTx++) + { + var tx = block.vtx[nTx]; + var hashTx = tx.Hash; + var nTxPos = cursor.nBlockPos + block.GetTxOffset(nTx); + + Dictionary txouts; + if (GetOutputs(hashTx, out txouts)) + { + // Do not allow blocks that contain transactions which 'overwrite' older transactions, + // unless those are already completely spent. + return false; + } + + nSigOps += tx.LegacySigOpCount; + if (nSigOps > CBlock.nMaxSigOps) + { + return false; // too many sigops + } + + var inputs = new Dictionary(); + + if (tx.IsCoinBase) + { + nValueOut += tx.nValueOut; + } + else + { + bool Invalid; + if (!FetchInputs(tx, ref queued, ref inputs, true, out Invalid)) + { + return false; // Unable to fetch some inputs. + } + + // 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); + if (nSigOps > CBlock.nMaxSigOps) + { + return false; // too many sigops + } + + ulong nTxValueIn = tx.GetValueIn(inputs); + ulong nTxValueOut = tx.nValueOut; + + nValueIn += nTxValueIn; + nValueOut += nTxValueOut; + + if (!tx.IsCoinStake) + { + nFees += nTxValueIn - nTxValueOut; + } + + if (!ConnectInputs(tx, inputs, queued, cursor, fScriptChecks, scriptFlags)) + { + return false; + } + } + + for (var i = 0u; i < tx.vout.Length; i++) + { + var mNode = new CMerkleNode(cursor.ItemID, nTxPos, tx); + queuedMerkleNodes.Add(hashTx, mNode); + + var outKey = new COutPoint(hashTx, i); + var outData = new TxOutItem(tx.vout[i], i); + + outData.IsSpent = false; + + queued.Add(outKey, outData); + } + } + + if (!block.IsProofOfStake) + { + ulong nBlockReward = CBlock.GetProofOfWorkReward(cursor.nBits, nFees); + + // Check coinbase reward + if (block.vtx[0].nValueOut > nBlockReward) + { + return false; // coinbase reward exceeded + } + } + + cursor.nMint = (long) (nValueOut - nValueIn + nFees); + cursor.nMoneySupply = (cursor.prev != null ? cursor.prev.nMoneySupply : 0) + (long)nValueOut - (long)nValueIn; + + if (!UpdateDBCursor(ref cursor)) + { + return false; // Unable to commit changes + } + + if (fJustCheck) + { + return true; + } + + // Write queued transaction changes + var actualMerkleNodes = new Dictionary(); + var queuedOutpointItems = new List(); + foreach(KeyValuePair outPair in queued) + { + uint256 txID = outPair.Key.hash; + CMerkleNode merkleNode; + + if (actualMerkleNodes.ContainsKey(txID)) + { + merkleNode = actualMerkleNodes[txID]; + } + else + { + merkleNode = queuedMerkleNodes[txID]; + if (!SaveMerkleNode(ref merkleNode)) + { + // Unable to save merkle tree cursor. + return false; + } + actualMerkleNodes.Add(txID, merkleNode); + } + + var outItem = outPair.Value; + outItem.nMerkleNodeID = merkleNode.nMerkleNodeID; + + queuedOutpointItems.Add(outItem); + } + + if (!SaveOutpoints(ref queuedOutpointItems)) + { + return false; // Unable to save outpoints + } + // TODO: the remaining stuff lol :D throw new NotImplementedException(); } + /// + /// Insert set of outpoints + /// + /// List of TxOutItem objects. + /// Result + private bool SaveOutpoints(ref List queuedOutpointItems) + { + return dbConn.InsertAll(queuedOutpointItems, false) != 0; + } + + /// + /// Insert merkle node into db and set actual record id value. + /// + /// Merkle node object reference. + /// Result + private bool SaveMerkleNode(ref CMerkleNode merkleNode) + { + if (dbConn.Insert(merkleNode) == 0) + { + return false; + } + + merkleNode.nMerkleNodeID = dbPlatform.SQLiteApi.LastInsertRowid(dbConn.Handle); + + return true; + } + + private bool ConnectInputs(CTransaction tx, Dictionary inputs, Dictionary queued, CBlockStoreItem cursor, bool fScriptChecks, scriptflag scriptFlags) + { + throw new NotImplementedException(); + } + private bool WriteHashBestChain(uint256 hash) { throw new NotImplementedException(); @@ -1332,7 +1572,7 @@ namespace Novacoin uint nHeight = prevBlockCursor.nHeight + 1; // Check timestamp against prev - if (NetUtils.FutureDrift(block.header.nTime) < prevBlockHeader.nTime) + if (NetInfo.FutureDrift(block.header.nTime) < prevBlockHeader.nTime) { // block's timestamp is too early return false; @@ -1365,21 +1605,25 @@ namespace Novacoin return true; } + /// + /// GEt block by hash. + /// + /// Block hash + /// Block object reference + /// Block position reference + /// Result public bool GetBlock(uint256 blockHash, ref CBlock block, ref long nBlockPos) { - var reader = new BinaryReader(fStreamReadWrite).BaseStream; - - var QueryBlock = dbConn.Query("select * from [BlockStorage] where [Hash] = ?", (byte[])blockHash); + CBlockStoreItem cursor; - if (QueryBlock.Count == 1) + if (!blockMap.TryGetValue(blockHash, out cursor)) { - nBlockPos = QueryBlock[0].nBlockPos; - return QueryBlock[0].ReadFromFile(ref reader, out block); + return false; // Unable to fetch block cursor } - // Block not found + nBlockPos = cursor.nBlockPos; - return false; + return cursor.ReadFromFile(ref fStreamReadWrite, out block); } @@ -1401,7 +1645,7 @@ namespace Novacoin /// Result of operation public bool GetBlockByTransactionID(uint256 TxID, ref CBlock block, ref CTransaction tx, ref long nBlockPos, ref long nTxPos) { - var queryResult = dbConn.Query("select *, from [BlockStorage] b left join [MerkleNodes] m on (b.[ItemID] = m.[nParentBlockID]) where m.[TransactionHash] = ?", (byte[])TxID); + var queryResult = dbConn.Query("select * from [BlockStorage] b left join [MerkleNodes] m on (b.[ItemID] = m.[nParentBlockID]) where m.[TransactionHash] = ?", (byte[])TxID); if (queryResult.Count == 1) { @@ -1423,12 +1667,46 @@ namespace Novacoin return false; } + public bool GetOutputs(uint256 transactionHash, out Dictionary txouts, bool fUnspentOnly=true) + { + txouts = null; + + var queryParams = new object[] { (byte[])transactionHash, fUnspentOnly ? OutputFlags.AVAILABLE : (OutputFlags.AVAILABLE | OutputFlags.SPENT) }; + var queryResult = dbConn.Query("select o.* from [Outputs] o left join [MerkleNodes] m on m.[nMerkleNodeID] = o.[nMerkleNodeID] where m.[TransactionHash] = ? and outputFlags = ?", queryParams); + + if (queryResult.Count != 0) + { + txouts = new Dictionary(); + + foreach (var o in queryResult) + { + var outpointKey = new COutPoint(transactionHash, o.nOut); + var outpointData = o; + + txouts.Add(outpointKey, outpointData); + } + + // There are some unspent inputs. + return true; + } + + // This transaction has been spent completely. + return false; + } + + public bool WriteNodes(ref CMerkleNode[] merkleNodes) + { + + + return true; + } + /// /// Get block cursor from map. /// /// block hash /// Cursor or null - public CBlockStoreItem GetCursor(uint256 blockHash) + public CBlockStoreItem GetMapCursor(uint256 blockHash) { if (blockHash == 0) { @@ -1436,20 +1714,24 @@ namespace Novacoin return null; } - // First, check our block map. - CBlockStoreItem item = null; - if (blockMap.TryGetValue(blockHash, out item)) - { - return item; - } + CBlockStoreItem cursor = null; + blockMap.TryGetValue(blockHash, out cursor); + return cursor; + } + + /// + /// Load cursor from database. + /// + /// Block hash + /// Block cursor object + public CBlockStoreItem GetDBCursor(uint256 blockHash) + { // Trying to get cursor from the database. var QueryBlockCursor = dbConn.Query("select * from [BlockStorage] where [Hash] = ?", (byte[])blockHash); if (QueryBlockCursor.Count == 1) { - blockMap.TryAdd(blockHash, QueryBlockCursor[0]); - return QueryBlockCursor[0]; } @@ -1460,17 +1742,22 @@ namespace Novacoin /// /// Update cursor in memory and on disk. /// - /// Original cursor - /// New cursor - /// - public bool UpdateCursor(CBlockStoreItem originalItem, ref CBlockStoreItem newItem) + /// Block cursor + /// Result + public bool UpdateMapCursor(CBlockStoreItem cursor) { - if (blockMap.TryUpdate(originalItem.Hash, newItem, originalItem)) - { - return dbConn.Update(newItem) != 0; - } + var original = blockMap[cursor.Hash]; + return blockMap.TryUpdate(cursor.Hash, cursor, original); + } - return false; + /// + /// Update cursor record in database. + /// + /// Block cursor object + /// Result + public bool UpdateDBCursor(ref CBlockStoreItem cursor) + { + return dbConn.Update(cursor) != 0; } public bool ProcessBlock(ref CBlock block) diff --git a/Novacoin/CTransaction.cs b/Novacoin/CTransaction.cs index 8a5f6a7..a061c70 100644 --- a/Novacoin/CTransaction.cs +++ b/Novacoin/CTransaction.cs @@ -21,6 +21,7 @@ using System.Text; using System.Collections.Generic; using System.IO; using System.Diagnostics.Contracts; +using System.Numerics; namespace Novacoin { @@ -48,6 +49,11 @@ namespace Novacoin public class CTransaction { /// + /// One cent = 10000 satoshis. + /// + public const ulong nCent = 10000; + + /// /// One coin = 1000000 satoshis. /// public const ulong nCoin = 1000000; @@ -251,9 +257,9 @@ namespace Novacoin } if (nBlockTime == 0) { - nBlockTime = NetUtils.GetAdjustedTime(); + nBlockTime = NetInfo.GetAdjustedTime(); } - if (nLockTime < (nLockTime < NetUtils.nLockTimeThreshold ? nBlockHeight : nBlockTime)) + if (nLockTime < (nLockTime < NetInfo.nLockTimeThreshold ? nBlockHeight : nBlockTime)) { return true; } @@ -407,7 +413,7 @@ namespace Novacoin /// /// Amount of novacoins spent by this transaction. /// - public ulong ValueOut + public ulong nValueOut { get { @@ -474,5 +480,15 @@ namespace Novacoin } public static bool MoneyRange(ulong nValue) { return (nValue <= nMaxMoney); } + + internal uint GetP2SHSigOpCount(Dictionary inputs) + { + throw new NotImplementedException(); + } + + internal ulong GetValueIn(Dictionary inputs) + { + throw new NotImplementedException(); + } } } diff --git a/Novacoin/Checkpoint.cs b/Novacoin/Checkpoint.cs deleted file mode 100644 index b9a6686..0000000 --- a/Novacoin/Checkpoint.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Novacoin -{ - class Checkpoint - { - } -} diff --git a/Novacoin/DatabaseInterfaces.cs b/Novacoin/DatabaseInterfaces.cs index ed95d8f..0d6e35e 100644 --- a/Novacoin/DatabaseInterfaces.cs +++ b/Novacoin/DatabaseInterfaces.cs @@ -179,5 +179,4 @@ namespace Novacoin /// bool IsSpent { get; set; } } - } diff --git a/Novacoin/NetInfo.cs b/Novacoin/NetInfo.cs index 1cf6f54..4e0d519 100644 --- a/Novacoin/NetInfo.cs +++ b/Novacoin/NetInfo.cs @@ -2,23 +2,58 @@ namespace Novacoin { - internal class NetUtils + /// + /// Basic network params. + /// + internal class NetInfo { - public static uint256 nProofOfWorkLimit = ~(new uint256(0)) >> 20; // "standard" scrypt target limit for proof of work, results with 0,000244140625 proof-of-work difficulty - public static uint256 nProofOfStakeLegacyLimit = ~(new uint256(0)) >> 24; // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty + /// + /// "standard" scrypt target limit for proof of work, results with 0,000244140625 proof-of-work difficulty + /// + public static uint256 nProofOfWorkLimit = ~(new uint256(0)) >> 20; - public static uint256 nProofOfStakeLimit = ~(new uint256(0)) >> 27; // proof of stake target limit since 20 June 2013, equal to 0.03125 proof of stake difficulty - public static uint256 nProofOfStakeHardLimit = ~(new uint256(0)) >> 30; // disabled temporarily, will be used in the future to fix minimal proof of stake difficulty at 0.25 + /// + /// Proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty + /// + public static uint256 nProofOfStakeLegacyLimit = ~(new uint256(0)) >> 24; - public static uint256 nPoWBase = new uint256("00000000ffff0000000000000000000000000000000000000000000000000000"); // difficulty-1 target + /// + /// Proof of stake target limit since 20 June 2013, equal to 0.03125 proof of stake difficulty + /// + public static uint256 nProofOfStakeLimit = ~(new uint256(0)) >> 27; - public static uint nChainChecksSwitchTime = 1379635200; // Fri, 20 Sep 2013 00:00:00 GMT + /// + /// Disabled temporarily, will be used in the future to fix minimal proof of stake difficulty at 0.25 + /// + public static uint256 nProofOfStakeHardLimit = ~(new uint256(0)) >> 30; + /// + /// Difficulty-1 target + /// + public static uint256 nPoWBase = new uint256("00000000ffff0000000000000000000000000000000000000000000000000000"); + + /// + /// Fri, 20 Sep 2013 00:00:00 GMT + /// + public static uint nChainChecksSwitchTime = 1379635200; + + /// + /// Hash of block #0 + /// public static uint256 nHashGenesisBlock = new uint256("00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4"); public static readonly uint nLockTimeThreshold = 500000000; + + /// + /// Allowed clock drift. + /// private static readonly uint nDrift = 7200; + /// + /// Maximum possible proof-of-work reward. + /// + public const ulong nMaxMintProofOfWork = CTransaction.nCoin * 100; + public static uint GetAdjustedTime() { return Interop.GetTime(); diff --git a/Novacoin/Novacoin.csproj b/Novacoin/Novacoin.csproj index 475682f..2954c91 100644 --- a/Novacoin/Novacoin.csproj +++ b/Novacoin/Novacoin.csproj @@ -109,7 +109,7 @@ - + diff --git a/Novacoin/StakeModifier.cs b/Novacoin/StakeModifier.cs index 67ed568..b3f7876 100644 --- a/Novacoin/StakeModifier.cs +++ b/Novacoin/StakeModifier.cs @@ -144,7 +144,7 @@ namespace Novacoin selectedCursor = null; foreach (var item in sortedByTimestamp) { - CBlockStoreItem cursor = CBlockStore.Instance.GetCursor(item.Item2); + CBlockStoreItem cursor = CBlockStore.Instance.GetMapCursor(item.Item2); if (cursor == null) { @@ -298,7 +298,7 @@ namespace Novacoin static bool GetKernelStakeModifier(uint256 hashBlockFrom, ref long nStakeModifier, ref uint nStakeModifierHeight, ref uint nStakeModifierTime) { nStakeModifier = 0; - var cursorFrom = CBlockStore.Instance.GetCursor(hashBlockFrom); + var cursorFrom = CBlockStore.Instance.GetMapCursor(hashBlockFrom); if (cursorFrom == null) { return false; // Block not indexed @@ -401,7 +401,7 @@ namespace Novacoin internal static uint GetStakeModifierChecksum(CBlockStoreItem itemTemplate) { - Contract.Assert(itemTemplate.prev != null || (uint256)itemTemplate.Hash == NetUtils.nHashGenesisBlock); + Contract.Assert(itemTemplate.prev != null || (uint256)itemTemplate.Hash == NetInfo.nHashGenesisBlock); // Hash previous checksum with flags, hashProofOfStake and nStakeModifier MemoryStream ss = new MemoryStream(); diff --git a/NovacoinTest/Program.cs b/NovacoinTest/Program.cs index 7483d4b..43a5ed8 100644 --- a/NovacoinTest/Program.cs +++ b/NovacoinTest/Program.cs @@ -319,6 +319,8 @@ namespace NovacoinTest Console.WriteLine("Reading the block file..."); var bs = new CBlockStore(); bs.ParseBlockFile(); + + Console.ReadLine(); } } }