X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=Novacoin%2FStakeModifier.cs;h=882a699486564ed6c1f6c5992322bfe37fc8bc45;hb=04ac3ad40812b5ff686f16e182a10a78b9816bf4;hp=7f45eb85879aa55362f2a1339941edf667256cda;hpb=217d4232e9feeb787b9163b2ca1e701840d5b65b;p=NovacoinLibrary.git diff --git a/Novacoin/StakeModifier.cs b/Novacoin/StakeModifier.cs index 7f45eb8..882a699 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) { @@ -280,7 +280,7 @@ namespace Novacoin } // write the entropy bit of the selected block - nStakeModifierNew |= ((cursor.StakeEntropyBit) << nRound); + nStakeModifierNew |= (((long)cursor.StakeEntropyBit) << nRound); // add the selected block from candidates to selected list mapSelectedBlocks.Add(cursor.Hash, cursor); @@ -295,10 +295,13 @@ namespace Novacoin /// The stake modifier used to hash for a stake kernel is chosen as the stake /// modifier about a selection interval later than the coin generating the kernel /// - static bool GetKernelStakeModifier(uint256 hashBlockFrom, ref long nStakeModifier, ref uint nStakeModifierHeight, ref uint nStakeModifierTime) + static bool GetKernelStakeModifier(uint256 hashBlockFrom, out long nStakeModifier, out uint nStakeModifierHeight, out uint nStakeModifierTime) { nStakeModifier = 0; - var cursorFrom = CBlockStore.Instance.GetCursor(hashBlockFrom); + nStakeModifierTime = 0; + nStakeModifierHeight = 0; + + var cursorFrom = CBlockStore.Instance.GetMapCursor(hashBlockFrom); if (cursorFrom == null) { return false; // Block not indexed @@ -330,16 +333,18 @@ namespace Novacoin return true; } - public static bool GetKernelStakeModifier(uint256 hashBlockFrom, ref long nStakeModifier) + public static bool GetKernelStakeModifier(uint256 hashBlockFrom, out long nStakeModifier) { uint nStakeModifierHeight = 0; uint nStakeModifierTime = 0; - return GetKernelStakeModifier(hashBlockFrom, ref nStakeModifier, ref nStakeModifierHeight, ref nStakeModifierTime); + return GetKernelStakeModifier(hashBlockFrom, out nStakeModifier, out nStakeModifierHeight, out nStakeModifierTime); } - public static bool CheckStakeKernelHash(uint nBits, uint256 hashBlockFrom, uint nTimeBlockFrom, uint nTxPrevOffset, CTransaction txPrev, COutPoint prevout, uint nTimeTx, ref uint256 hashProofOfStake, ref uint256 targetProofOfStake) + public static bool CheckStakeKernelHash(uint nBits, uint256 hashBlockFrom, uint nTimeBlockFrom, uint nTxPrevOffset, CTransaction txPrev, COutPoint prevout, uint nTimeTx, out uint256 hashProofOfStake, out uint256 targetProofOfStake) { + hashProofOfStake = targetProofOfStake = 0; + if (nTimeTx < txPrev.nTime) { return false; // Transaction timestamp violation @@ -359,10 +364,10 @@ namespace Novacoin targetProofOfStake = nCoinDayWeight * nTargetPerCoinDay; // Calculate hash - long nStakeModifier = 0; - uint nStakeModifierHeight = 0; - uint nStakeModifierTime = 0; - if (!GetKernelStakeModifier(hashBlockFrom, ref nStakeModifier, ref nStakeModifierHeight, ref nStakeModifierTime)) + long nStakeModifier; + uint nStakeModifierTime; + uint nStakeModifierHeight; + if (!GetKernelStakeModifier(hashBlockFrom, out nStakeModifier, out nStakeModifierHeight, out nStakeModifierTime)) { return false; } @@ -399,9 +404,9 @@ namespace Novacoin return Math.Min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, nStakeMaxAge); } - internal static uint GetStakeModifierChecksum(CBlockStoreItem itemTemplate) + internal static uint GetStakeModifierChecksum(ref 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(); @@ -432,8 +437,10 @@ namespace Novacoin return (uint)hashChecksum.Low64; } - internal static bool CheckProofOfStake(CTransaction tx, uint nBits, ref uint256 hashProofOfStake, ref uint256 targetProofOfStake) + public static bool CheckProofOfStake(CTransaction tx, uint nBits, out uint256 hashProofOfStake, out uint256 targetProofOfStake) { + hashProofOfStake = targetProofOfStake = 0; + if (!tx.IsCoinStake) { return false; // called on non-coinstake @@ -443,17 +450,40 @@ namespace Novacoin CTxIn txin = tx.vin[0]; // Read block header - - CBlock block = null; - CTransaction txPrev = null; - long nBlockPos = 0, nTxPos = 0; - - if (!CBlockStore.Instance.GetByTransactionID(txin.prevout.hash, ref block, ref txPrev, ref nBlockPos, ref nTxPos)) + + long nBlockPos; + CBlock block; + if (!CBlockStore.Instance.GetBlockByTransactionID(txin.prevout.hash, out block, out nBlockPos)) { return false; // unable to read block of previous transaction } - if (!CheckStakeKernelHash(nBits, block.header.Hash, block.header.nTime, (uint)(nTxPos - nBlockPos), txPrev, txin.prevout, tx.nTime, ref hashProofOfStake, ref targetProofOfStake)) + long nTxPos = 0; + CTransaction txPrev = null; + + // Iterate through vtx array + for (var i = 0; i < block.vtx.Length; i++) + { + if (block.vtx[i].Hash == txin.prevout.hash) + { + txPrev = block.vtx[i]; + nTxPos = nBlockPos + block.GetTxOffset(i); + + break; + } + } + + if (txPrev == null) + { + return false; // No such transaction found in the block + } + + if (!ScriptCode.VerifyScript(txin.scriptSig, txPrev.vout[txin.prevout.n].scriptPubKey, tx, 0, (int)scriptflag.SCRIPT_VERIFY_P2SH, 0)) + { + return false; // vin[0] signature check failed + } + + if (!CheckStakeKernelHash(nBits, block.header.Hash, block.header.nTime, (uint)(nTxPos - nBlockPos), txPrev, txin.prevout, tx.nTime, out hashProofOfStake, out targetProofOfStake)) { return false; // check kernel failed on coinstake }