Example #1
0
        // Check kernel hash target and coinstake signature
        public static bool CheckProofOfStake(IBlockRepository blockStore, ITransactionRepository trasnactionStore, IBlockTransactionMapStore mapStore,
                                             ChainedBlock pindexPrev, BlockStake prevBlockStake, Transaction tx, uint nBits, out uint256 hashProofOfStake, out uint256 targetProofOfStake)
        {
            targetProofOfStake = null; hashProofOfStake = null;

            // todo: Comments on this mehtod:
            // the store objects (IBlockRepository and  ITransactionRepository) should be a singleton instance of
            // the BlockValidator and would be initiated as part of a Dependency Injection freamwork

            if (!tx.IsCoinStake)
            {
                return(false);                // error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString());
            }
            // Kernel (input 0) must match the stake hash target per coin age (nBits)
            var txIn = tx.Inputs[0];

            // First try finding the previous transaction in database
            var txPrev = trasnactionStore.Get(txIn.PrevOut.Hash);

            if (txPrev == null)
            {
                return(false);                // tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed"));  // previous transaction not in main chain, may occur during initial download
            }
            // Verify signature
            if (!VerifySignature(txPrev, tx, 0, ScriptVerify.None))
            {
                return(false);                // tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString()));
            }
            // Read block header
            var blockHashPrev = mapStore.GetBlockHash(txIn.PrevOut.Hash);
            var block         = blockHashPrev == null ? null : blockStore.GetBlock(blockHashPrev);

            if (block == null)
            {
                return(false);                //fDebug? error("CheckProofOfStake() : read block failed") : false; // unable to read block of previous transaction
            }
            // Min age requirement
            if (IsProtocolV3((int)tx.Time))
            {
                int nDepth = 0;
                if (IsConfirmedInNPrevBlocks(blockStore, txPrev, pindexPrev, StakeMinConfirmations - 1, ref nDepth))
                {
                    return(false);                    // tx.DoS(100, error("CheckProofOfStake() : tried to stake at depth %d", nDepth + 1));
                }
            }
            else
            {
                var nTimeBlockFrom = block.Header.Time;
                if (nTimeBlockFrom + StakeMinAge > tx.Time)
                {
                    return(false);                    // error("CheckProofOfStake() : min age violation");
                }
            }

            if (!CheckStakeKernelHash(pindexPrev, nBits, block, txPrev, prevBlockStake, txIn.PrevOut, tx.Time, out hashProofOfStake, out targetProofOfStake, false))
            {
                return(false);                // tx.DoS(1, error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s", tx.GetHash().ToString(), hashProofOfStake.ToString())); // may occur during initial download or if behind on block chain sync
            }
            return(true);
        }
Example #2
0
        public static bool CheckKernel(IBlockRepository blockStore, ITransactionRepository trasnactionStore,
                                       IBlockTransactionMapStore mapStore, StakeChain stakeChain,
                                       ChainedBlock pindexPrev, uint nBits, long nTime, OutPoint prevout, ref long pBlockTime)
        {
            uint256 hashProofOfStake = null, targetProofOfStake = null;

            var txPrev = trasnactionStore.Get(prevout.Hash);

            if (txPrev == null)
            {
                return(false);
            }

            // Read block header
            var blockHashPrev = mapStore.GetBlockHash(prevout.Hash);
            var block  = blockHashPrev == null ? null : blockStore.GetBlock(blockHashPrev);

            if (block == null)
            {
                return(false);
            }

            if (IsProtocolV3((int)nTime))
            {
                int nDepth = 0;
                if (IsConfirmedInNPrevBlocks(blockStore, txPrev, pindexPrev, StakeMinConfirmations - 1, ref nDepth))
                {
                    return(false);                    // tx.DoS(100, error("CheckProofOfStake() : tried to stake at depth %d", nDepth + 1));
                }
            }
            else
            {
                var nTimeBlockFrom = block.Header.Time;
                if (nTimeBlockFrom + StakeMinAge > nTime)
                {
                    return(false);                    // error("CheckProofOfStake() : min age violation");
                }
            }

            var prevBlockStake = stakeChain.Get(pindexPrev.HashBlock);

            if (prevBlockStake == null)
            {
                return(false);                // the stake proof of the previous block is not set
            }
            // todo: check this unclear logic
            //if (pBlockTime)
            //	pBlockTime = block.Header.Time;

            return(CheckStakeKernelHash(pindexPrev, nBits, block, txPrev, prevBlockStake, prevout, (uint)nTime, out hashProofOfStake, out targetProofOfStake, false));
        }