コード例 #1
0
        public const uint ModifierInterval     = 10 * 60; // time to elapse before new modifier is computed

        public static bool CheckAndComputeStake(IBlockRepository blockStore, ITransactionRepository trasnactionStore, IBlockTransactionMapStore mapStore, StakeChain stakeChain,
                                                ChainBase chainIndex, ChainedBlock pindex, Block block, out BlockStake blockStake)
        {
            if (block.GetHash() != pindex.HashBlock)
            {
                throw new ArgumentException();
            }

            blockStake = new BlockStake(block);

            uint256 hashProof = null;

            // Verify hash target and signature of coinstake tx
            if (BlockStake.IsProofOfStake(block))
            {
                var pindexPrev = pindex.Previous;

                var prevBlockStake = stakeChain.Get(pindexPrev.HashBlock);
                if (prevBlockStake == null)
                {
                    return(false);                    // the stake proof of the previous block is not set
                }
                uint256 targetProofOfStake;
                if (!CheckProofOfStake(blockStore, trasnactionStore, mapStore, pindexPrev, prevBlockStake, block.Transactions[1],
                                       pindex.Header.Bits.ToCompact(), out hashProof, out targetProofOfStake))
                {
                    return(false);                    // error("AcceptBlock() : check proof-of-stake failed for block %s", hash.ToString());
                }
            }

            // PoW is checked in CheckBlock()
            if (BlockStake.IsProofOfWork(block))
            {
                hashProof = pindex.Header.GetPoWHash();
            }

            // todo: is this the same as chain work?
            // compute chain trust score
            //pindexNew.nChainTrust = (pindexNew->pprev ? pindexNew->pprev->nChainTrust : 0) + pindexNew->GetBlockTrust();

            // compute stake entropy bit for stake modifier
            if (!blockStake.SetStakeEntropyBit(blockStake.GetStakeEntropyBit()))
            {
                return(false);                //error("AddToBlockIndex() : SetStakeEntropyBit() failed");
            }
            // Record proof hash value
            blockStake.HashProof = hashProof;

            // compute stake modifier
            return(ComputeStakeModifier(chainIndex, pindex, blockStake, stakeChain));
        }
コード例 #2
0
ファイル: BlockStake.cs プロジェクト: billsquall/NStratis
 public Target GetWorkRequired(ChainedBlock chainedBlock, BlockStake blockStake, Consensus consensus)
 {
     return(BlockValidator.GetNextTargetRequired(this, chainedBlock.Previous, consensus, blockStake.IsProofOfStake()));
 }
コード例 #3
0
        // a method to check a block, this may be moved to the full node.
        public static bool CheckBlock(Block block, bool checkPow = true, bool checkMerkleRoot = true, bool checkSig = true)
        {
            // These are checks that are independent of context
            // that can be verified before saving an orphan block.

            // Size limits
            if (!block.Transactions.Any() || block.GetSerializedSize() > MAX_BLOCK_SIZE)
            {
                return(false);                // DoS(100, error("CheckBlock() : size limits failed"));
            }
            // Check proof of work matches claimed amount
            if (checkPow && BlockStake.IsProofOfWork(block) && !block.CheckProofOfWork())
            {
                return(false);                //DoS(50, error("CheckBlock() : proof of work failed"));
            }
            // Check timestamp
            if (block.Header.Time > FutureDriftV2(DateTime.UtcNow.Ticks)) //GetAdjustedTime()))
            {
                return(false);                                            //error("CheckBlock() : block timestamp too far in he future");
            }
            // First transaction must be coinbase, the rest must not be
            if (!block.Transactions[0].IsCoinBase)
            {
                return(false);                //  DoS(100, error("CheckBlock() : first tx is not coinbase"));
            }
            if (block.Transactions.Skip(1).Any(t => t.IsCoinBase))
            {
                return(false);                //DoS(100, error("CheckBlock() : more than one coinbase"));
            }
            if (BlockStake.IsProofOfStake(block))
            {
                // Coinbase output should be empty if proof-of-stake block
                if (block.Transactions[0].Outputs.Count != 1 || !block.Transactions[0].Outputs[0].IsEmpty)
                {
                    return(false);                    // DoS(100, error("CheckBlock() : coinbase output not empty for proof-of-stake block"));
                }
                // Second transaction must be coinstake, the rest must not be
                if (!block.Transactions[1].IsCoinStake)
                {
                    return(false);                    // DoS(100, error("CheckBlock() : second tx is not coinstake"));
                }
                if (block.Transactions.Skip(2).Any(t => t.IsCoinStake))
                {
                    return(false);                    //DoS(100, error("CheckBlock() : more than one coinstake"));
                }
            }

            // Check proof-of-stake block signature
            if (checkSig && !CheckBlockSignature(block))
            {
                return(false);                //DoS(100, error("CheckBlock() : bad proof-of-stake block signature"));
            }
            // Check transactions
            foreach (var transaction in block.Transactions)
            {
                if (transaction.Check() != TransactionCheckResult.Success)
                {
                    return(false);                    // DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
                }
                // ppcoin: check transaction timestamp
                if (block.Header.Time < transaction.Time)
                {
                    return(false);                    // DoS(50, error("CheckBlock() : block timestamp earlier than transaction timestamp"));
                }
            }

            // Check for duplicate txids. This is caught by ConnectInputs(),
            // but catching it earlier avoids a potential DoS attack:
            var set = new HashSet <uint256>();

            if (block.Transactions.Select(t => t.GetHash()).Any(h => !set.Add(h)))
            {
                return(false);                //DoS(100, error("CheckBlock() : duplicate transaction"));
            }
            // todo: check if this is legacy from older implementtions and actually needed
            //uint nSigOps = 0;
            //foreach (var transaction in block.Transactions)
            //{
            //	nSigOps += GetLegacySigOpCount(transaction);
            //}
            //if (nSigOps > MAX_BLOCK_SIGOPS)
            //	return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));

            // Check merkle root
            if (checkMerkleRoot && !block.CheckMerkleRoot())
            {
                return(false);                //DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
            }
            return(true);
        }