public bool Check(IHeaderValidationContext context, ref BlockValidationState validationState) { Protocol.Types.BlockHeader header = context.Header; if (header.PreviousBlockHash == null) { validationState.Invalid(BlockValidationStateResults.InvalidHeader, "prev-hash-null", "previous hash null, allowed only on genesis block"); return(false); } // ensures tip previous header is present. if (!context.ChainState.TryGetKnownHeaderNode(context.Header.PreviousBlockHash !, out HeaderNode? previousNode)) { //previous tip header not found, abort. validationState.Invalid(BlockValidationStateResults.MissingPreviousHeader, "prev-blk-not-found", "previous header not found, can't connect headers"); return(false); } if (previousNode.IsInvalid()) { validationState.Invalid(BlockValidationStateResults.CachedInvalid, "bad-prevblk", "previous block invalid"); return(false); } context.SetData(PREV_BLOCK, previousNode); return(true); }
public bool Check(IBlockValidationContext context, ref BlockValidationState validationState) { if (IsBlockMalleated(context.Block.Transactions !)) { return(validationState.Invalid(BlockValidationStateResults.Mutated, "bad-txns-duplicate", "duplicate transaction")); } UInt256 computedMerkleRoot = _merkleRootCalculator.GetBlockMerkleRoot(context.Block); if (context.Block.Header !.MerkleRoot != computedMerkleRoot) { return(validationState.Invalid(BlockValidationStateResults.Mutated, "bad-txnmrklroot", "hashMerkleRoot mismatch")); } return(true); }
public bool Check(IBlockValidationContext context, ref BlockValidationState validationState) { Protocol.Types.Transaction[] transactions = context.Block.Transactions !; // First transaction must be coinbase, the rest must not be if ((transactions.Length == 0) || !transactions[0].IsCoinBase()) { validationState.Invalid(BlockValidationStateResults.Consensus, "bad-cb-missing", "first tx is not coinbase"); return(false); } for (int i = 1; i < transactions.Length; i++) { if (transactions[i].IsCoinBase()) { validationState.Invalid(BlockValidationStateResults.Consensus, "bad-cb-multiple", "more than one coinbase"); return(false); } } return(true); }
public bool Check(IHeaderValidationContext context, ref BlockValidationState validationState) { if (!context.TryGetData(CheckPreviousBlock.PREV_BLOCK, out HeaderNode? previousHeaderNode)) { ThrowHelper.ThrowArgumentException("Fatal exception, this rule must be executed before CheckPreviousBlock, need previous header node"); return(false); } if (context.Header.TimeStamp <= _headerMedianTimeCalculator.Calculate(previousHeaderNode !.Hash, previousHeaderNode.Height)) { validationState.Invalid(BlockValidationStateResults.InvalidHeader, "time-too-old", "block's timestamp is too early"); return(false); } // Check timestamp. if (context.Header.TimeStamp > (_dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() + MAX_FUTURE_BLOCK_TIME)) { validationState.Invalid(BlockValidationStateResults.TimeFuture, "time-too-new", "block timestamp too far in the future"); return(false); } return(true); }
public bool Check(IHeaderValidationContext context, ref BlockValidationState validationState) { BlockHeader header = context.Header; // Check proof of work matches claimed amount //if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) if (!_proofOfWorkCalculator.CheckProofOfWork(header)) { validationState.Invalid(BlockValidationStateResults.InvalidHeader, "high-hash", "proof of work failed"); return(false); } return(true); }
public bool Check(IBlockValidationContext context, ref BlockValidationState validationState) { int transactionsCount = context.Block.Transactions !.Length; if ( transactionsCount == 0 || transactionsCount * _consensusParameters.WitnessScaleFactor > _consensusParameters.MaxBlockWeight || GetBlockSize(context.Block) * _consensusParameters.WitnessScaleFactor > _consensusParameters.MaxBlockWeight ) { return(validationState.Invalid(BlockValidationStateResults.Consensus, "bad-blk-length", "size limits failed")); } return(true); }
public bool Check(IBlockValidationContext context, ref BlockValidationState validationState) { Transaction[] transactions = context.Block.Transactions !; for (int i = 0; i < transactions.Length; i++) { if (!PerformCheck(transactions[i], out TransactionValidationState? transactionValidationState)) { // checks performed here are context-free validation checks. The only possible failures are consensus failures. return(validationState.Invalid(BlockValidationStateResults.Consensus, transactionValidationState.RejectReason !, transactionValidationState.DebugMessage !)); } } return(true); }
public bool Check(IHeaderValidationContext context, ref BlockValidationState validationState) { HeaderNode?existingHeader = context.KnownHeader; // check if the tip we want to set is already into our chain if (existingHeader != null) { if (existingHeader.IsInvalid()) { validationState.Invalid(BlockValidationStateResults.CachedInvalid, "duplicate", "block marked as invalid"); return(false); } // if the header has been already validated before, we can skip the validation process. context.ForceAsValid("The header we want to accept is already in our headers chain."); } return(true); }