selectedCursor = null;
foreach (var item in sortedByTimestamp)
{
- CBlockStoreItem cursor = CBlockStore.Instance.GetCursor(item.Item2);
+ CBlockStoreItem cursor = CBlockStore.Instance.GetMapCursor(item.Item2);
if (cursor == null)
{
}
// 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);
/// 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
/// </summary>
- 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
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
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;
}
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();
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
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
}