// Check whether the coinstake timestamp meets protocol public static bool CheckCoinStakeTimestamp(int nHeight, long nTimeBlock, long nTimeTx) { if (StakeValidator.IsProtocolV2(nHeight)) { return((nTimeBlock == nTimeTx) && ((nTimeTx & STAKE_TIMESTAMP_MASK) == 0)); } else { return(nTimeBlock == nTimeTx); } }
public override void ContextualCheckBlockHeader(ContextInformation context) { base.ContextualCheckBlockHeader(context); var chainedBlock = context.BlockResult.ChainedBlock; if (!StakeValidator.IsProtocolV3((int)chainedBlock.Header.Time)) { if (chainedBlock.Header.Version > BlockHeader.CURRENT_VERSION) { ConsensusErrors.BadVersion.Throw(); } } if (StakeValidator.IsProtocolV2(chainedBlock.Height) && chainedBlock.Header.Version < 7) { ConsensusErrors.BadVersion.Throw(); } else if (!StakeValidator.IsProtocolV2(chainedBlock.Height) && chainedBlock.Header.Version > 6) { ConsensusErrors.BadVersion.Throw(); } if (context.Stake.BlockStake.IsProofOfWork() && chainedBlock.Height > this.ConsensusParams.LastPOWBlock) { ConsensusErrors.ProofOfWorkTooHeigh.Throw(); } // Check coinbase timestamp if (chainedBlock.Header.Time > FutureDrift(context.BlockResult.Block.Transactions[0].Time, chainedBlock.Height)) { ConsensusErrors.TimeTooNew.Throw(); } // Check coinstake timestamp if (context.Stake.BlockStake.IsProofOfStake() && !PosConsensusValidator.CheckCoinStakeTimestamp(chainedBlock.Height, chainedBlock.Header.Time, context.BlockResult.Block.Transactions[1].Time)) { ConsensusErrors.StakeTimeViolation.Throw(); } // Check timestamp against prev if (chainedBlock.Header.Time <= StakeValidator.GetPastTimeLimit(chainedBlock.Previous) || FutureDrift(chainedBlock.Header.Time, chainedBlock.Height) < chainedBlock.Previous.Header.Time) { ConsensusErrors.BlockTimestampTooEarly.Throw(); } }
private static long FutureDrift(long nTime, int nHeight) { return(StakeValidator.IsProtocolV2(nHeight) ? FutureDriftV2(nTime) : FutureDriftV1(nTime)); }