public BIP9DeploymentsParameters this[BIP9Deployments index] { get { return(_Parameters[(int)index]); } set { _Parent.EnsureNotFrozen(); _Parameters[(int)index] = value; } }
private bool ContainsKey(uint256 hash, BIP9Deployments deployment) { if (hash == null) { return(true); } ThresholdState?[] threshold; if (!this.cache.TryGetValue(hash, out threshold)) { return(false); } return(threshold[(int)deployment].HasValue); }
private void Set(uint256 hash, BIP9Deployments deployment, ThresholdState state) { if (hash == null) { return; } ThresholdState?[] threshold; if (!this.cache.TryGetValue(hash, out threshold)) { threshold = new ThresholdState?[ArraySize]; this.cache.Add(hash, threshold); } threshold[(int)deployment] = state; }
private ThresholdState Get(uint256 hash, BIP9Deployments deployment) { if (hash == null) { return(ThresholdState.Defined); } ThresholdState?[] threshold; if (!this.cache.TryGetValue(hash, out threshold)) { throw new InvalidOperationException("Should never happen"); } if (threshold[(int)deployment] == null) { throw new InvalidOperationException("Should never happen"); } return(threshold[(int)deployment].Value); }
public ThresholdState GetState(ChainedBlock pindexPrev, BIP9Deployments deployment) { int nPeriod = this.consensus.MinerConfirmationWindow; int nThreshold = this.consensus.RuleChangeActivationThreshold; var nTimeStart = this.consensus.BIP9Deployments[deployment]?.StartTime; var nTimeTimeout = this.consensus.BIP9Deployments[deployment]?.Timeout; // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1. if (pindexPrev != null) { pindexPrev = pindexPrev.GetAncestor(pindexPrev.Height - ((pindexPrev.Height + 1) % nPeriod)); } // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known List <ChainedBlock> vToCompute = new List <ChainedBlock>(); while (!this.ContainsKey(pindexPrev?.HashBlock, deployment)) { if (pindexPrev.GetMedianTimePast() < nTimeStart) { // Optimization: don't recompute down further, as we know every earlier block will be before the start time this.Set(pindexPrev?.HashBlock, deployment, ThresholdState.Defined); break; } vToCompute.Add(pindexPrev); pindexPrev = pindexPrev.GetAncestor(pindexPrev.Height - nPeriod); } // At this point, cache[pindexPrev] is known this.Assert(this.ContainsKey(pindexPrev?.HashBlock, deployment)); ThresholdState state = this.Get(pindexPrev?.HashBlock, deployment); // Now walk forward and compute the state of descendants of pindexPrev while (vToCompute.Count != 0) { ThresholdState stateNext = state; pindexPrev = vToCompute[vToCompute.Count - 1]; vToCompute.RemoveAt(vToCompute.Count - 1); switch (state) { case ThresholdState.Defined: { if (pindexPrev.GetMedianTimePast() >= nTimeTimeout) { stateNext = ThresholdState.Failed; } else if (pindexPrev.GetMedianTimePast() >= nTimeStart) { stateNext = ThresholdState.Started; } break; } case ThresholdState.Started: { if (pindexPrev.GetMedianTimePast() >= nTimeTimeout) { stateNext = ThresholdState.Failed; break; } // We need to count ChainedBlock pindexCount = pindexPrev; int count = 0; for (int i = 0; i < nPeriod; i++) { if (this.Condition(pindexCount, deployment)) { count++; } pindexCount = pindexCount.Previous; } if (count >= nThreshold) { stateNext = ThresholdState.LockedIn; } break; } case ThresholdState.LockedIn: { // Always progresses into ACTIVE. stateNext = ThresholdState.Active; break; } case ThresholdState.Failed: case ThresholdState.Active: { // Nothing happens, these are terminal states. break; } } this.Set(pindexPrev?.HashBlock, deployment, state = stateNext); } return(state); }
public uint Mask(BIP9Deployments deployment) { return(((uint)1) << this.consensus.BIP9Deployments[deployment].Bit); }
private bool Condition(ChainedBlock pindex, BIP9Deployments deployment) { return(((pindex.Header.Version & VersionbitsTopMask) == VersionbitsTopBits) && (pindex.Header.Version & this.Mask(deployment)) != 0); }
public BIP9DeploymentsParameters this[BIP9Deployments index] { get { return(this.parameters[(int)index]); } set { this.parameters[(int)index] = value; } }
public BIP9DeploymentsParameters this[BIP9Deployments index] { get => this.parameters[(int)index];
private uint Mask(BIP9Deployments deployment) { return(((uint)1) << _Consensus.BIP9Deployments[deployment].Bit); }
private bool Condition(ChainedBlock pindex, BIP9Deployments deployment) { return(((pindex.Header.Version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex.Header.Version & Mask(deployment)) != 0); }