public Target GetWorkRequired(Network network, ChainedHeader prev) { return(this.GetWorkRequired(network.Consensus, prev)); }
public Target GetWorkRequired(Consensus consensus, ChainedHeader prev) { return(new ChainedHeader(this, this.GetHash(), prev).GetWorkRequired(consensus)); }
/// <summary> /// Set time to consensus acceptable value. /// </summary> /// <param name="now">The expected date.</param> /// <param name="network">Network.</param> /// <param name="prev">Previous block.</param> public void UpdateTime(DateTimeOffset now, Network network, ChainedHeader prev) { this.UpdateTime(now, network.Consensus, prev); }
public bool Evaluate(ChainedHeader block) { DateTimeOffset nBlockTime = block.Previous == null?Utils.UnixTimeToDateTime(0) : block.Previous.GetMedianTimePast(); return(this.MinHeight < block.Height && this.MinTime < nBlockTime); }
/// <summary> /// Gets the proof of work target for this entry in the chain. /// </summary> /// <param name="consensus">Consensus rules to use for this computation.</param> /// <returns>The target proof of work.</returns> public Target GetWorkRequired(Consensus consensus) { // Genesis block. if (this.Height == 0) { return(consensus.PowLimit); } Target proofOfWorkLimit = consensus.PowLimit; ChainedHeader lastBlock = this.Previous; int height = this.Height; if (lastBlock == null) { return(proofOfWorkLimit); } // Only change once per interval. if ((height) % consensus.DifficultyAdjustmentInterval != 0) { if (consensus.PowAllowMinDifficultyBlocks) { // Special difficulty rule for testnet: // If the new block's timestamp is more than 2* 10 minutes // then allow mining of a min-difficulty block. if (this.Header.BlockTime > (lastBlock.Header.BlockTime + TimeSpan.FromTicks(consensus.PowTargetSpacing.Ticks * 2))) { return(proofOfWorkLimit); } // Return the last non-special-min-difficulty-rules-block. ChainedHeader chainedHeader = lastBlock; while ((chainedHeader.Previous != null) && ((chainedHeader.Height % consensus.DifficultyAdjustmentInterval) != 0) && (chainedHeader.Header.Bits == proofOfWorkLimit)) { chainedHeader = chainedHeader.Previous; } return(chainedHeader.Header.Bits); } return(lastBlock.Header.Bits); } // Go back by what we want to be 14 days worth of blocks. long pastHeight = lastBlock.Height - (consensus.DifficultyAdjustmentInterval - 1); ChainedHeader firstChainedHeader = this.GetAncestor((int)pastHeight); if (firstChainedHeader == null) { throw new NotSupportedException("Can only calculate work of a full chain"); } if (consensus.PowNoRetargeting) { return(lastBlock.Header.Bits); } // Limit adjustment step. TimeSpan actualTimespan = lastBlock.Header.BlockTime - firstChainedHeader.Header.BlockTime; if (actualTimespan < TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks / 4)) { actualTimespan = TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks / 4); } if (actualTimespan > TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks * 4)) { actualTimespan = TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks * 4); } // Retarget. BigInteger newTarget = lastBlock.Header.Bits.ToBigInteger(); newTarget = newTarget.Multiply(BigInteger.ValueOf((long)actualTimespan.TotalSeconds)); newTarget = newTarget.Divide(BigInteger.ValueOf((long)consensus.PowTargetTimespan.TotalSeconds)); var finalTarget = new Target(newTarget); if (finalTarget > proofOfWorkLimit) { finalTarget = proofOfWorkLimit; } return(finalTarget); }
public ChainIndexer(Network network, ChainedHeader chainedHeader) : this() { this.Network = network; this.Initialize(chainedHeader); }
public ConcurrentChain(Network network, ChainedHeader chainedHeader) { this.network = network; SetTip(chainedHeader); }